function a = r8vec_permute ( n, a, p )

%*****************************************************************************80
%
%% r8vec_permute() permutes an R8VEC in place.
%
%  Discussion:
%
%    This routine permutes an array of real "objects", but the same
%    logic can be used to permute an array of objects of any arithmetic
%    type, or an array of objects of any complexity.  The only temporary
%    storage required is enough to store a single object.  The number
%    of data movements made is N + the number of cycles of order 2 or more,
%    which is never more than N + N/2.
%
%    P(I) = J means that the I-th element of the output array should be 
%    the J-th element of the input array.  P must be a legal permutation
%    of the integers from 1 to N, otherwise the algorithm will
%    fail catastrophically.
%
%  Example:
%
%    Input:
%
%      N = 5
%      P = (   2,   4,   5,   1,   3 )
%      A = ( 1.0, 2.0, 3.0, 4.0, 5.0 )
%
%    Output:
%
%      A    = ( 2.0, 4.0, 5.0, 1.0, 3.0 ).
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    23 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer N, the number of objects.
%
%    real A(N), the array to be permuted.
%
%    integer P(N), the permutation.  
%
%  Output:
%
%    real A(N), the permuted array.
%
  ierror = perm_check ( n, p );

  if ( ierror ~= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8VEC_PERMUTE - Fatal error!\n' );
    fprintf ( 1, '  The input array does not represent\n' );
    fprintf ( 1, '  a proper permutation.  In particular, the\n' );
    fprintf ( 1, '  array is missing the value %d\n', ierror );
    error ( 'R8VEC_PERMUTE - Fatal error!' );
  end
%
%  Search for the next element of the permutation that has not been used.
%
  for istart = 1 : n

    if ( p(istart) < 0 )

      continue

    elseif ( p(istart) == istart )

      p(istart) = -p(istart);
      continue

    else

      a_temp = a(istart);
      iget = istart;
%
%  Copy the new value into the vacated entry.
%
      while ( true )

        iput = iget;
        iget = p(iget);

        p(iput) = -p(iput);

        if ( iget < 1 || n < iget )
          fprintf ( 1, '\n' );
          fprintf ( 1, 'R8VEC_PERMUTE - Fatal error!\n' );
          fprintf ( 1, '  A permutation index is out of range.\n' );
          fprintf ( 1, '  P(%d) = %d\n', iput, iget );
          error ( 'R8VEC_PERMUTE - Fatal error!' );
        end

        if ( iget == istart )
          a(iput) = a_temp;
          break
        end

        a(iput) = a(iget);

      end

    end

  end
%
%  Restore the signs of the entries.
%
  p(1:n) = -p(1:n);

  return
end
