#! /usr/bin/env python # def r8vec_permute ( n, p, a ): #*****************************************************************************80 # ## R8VEC_PERMUTE permutes an R8VEC in place. # # Discussion: # # An I4VEC is a vector of R8's. # # 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. # # Example: # # Input: # # N = 5 # P = ( 1, 3, 4, 0, 2 ) # 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 GNU LGPL license. # # Modified: # # 26 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, integer N, the number of objects. # # Input, integer P[N], the permutation. P(I) = J means # that the I-th element of the output array should be the J-th # element of the input array. # # Input, real A[N], the array to be permuted. # # Output, real A[N], the permuted array. # from perm0_check import perm0_check from sys import exit check = perm0_check ( n, p ); if ( not check ): print ( '' ) print ( 'R8VEC_PERMUTE - Fatal error!' ) print ( ' PERM0_CHECK rejects the permutation.' ) exit ( 'R8VEC_PERMUTE - Fatal error!' ) # # In order for the sign negation trick to work, we need to assume that the # entries of P are strictly positive. Presumably, the lowest number is 0. # So temporarily add 1 to each entry to force positivity. # for i in range ( 0, n ): p[i] = p[i] + 1 # # Search for the next element of the permutation that has not been used. # for istart in range ( 1, n + 1 ): if ( p[istart-1] < 0 ): continue elif ( p[istart-1] == istart ): p[istart-1] = - p[istart-1] else: a_temp = a[istart-1]; iget = istart; # # Copy the new value into the vacated entry. # while ( True ): iput = iget iget = p[iget-1] p[iput-1] = - p[iput-1] if ( iget < 1 or n < iget ): print ( '' ) print ( 'R8VEC_PERMUTE - Fatal error!' ) print ( ' Entry IPUT = %d has' % ( iput ) ) print ( ' an illegal value IGET = %d.' % (iget ) ) exit ( 'R8VEC_PERMUTE - Fatal error!' ) if ( iget == istart ): a[iput-1] = a_temp break a[iput-1] = a[iget-1] # # Restore the signs of the entries. # for i in range ( 0, n ): p[i] = - p[i] # # Restore the entries. # for i in range ( 0, n ): p[i] = p[i] - 1 return a def r8vec_permute_test ( ): #*****************************************************************************80 # ## R8VEC_PERMUTE_TEST tests R8VEC_PERMUTE. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 26 October 2014 # # Author: # # John Burkardt # import numpy as np import platform from i4vec_print import i4vec_print from r8vec_print import r8vec_print n = 5 print ( '' ) print ( 'R8VEC_PERMUTE_TEST' ) print ( ' Python version: %s' % ( platform.python_version ( ) ) ) print ( ' R8VEC_PERMUTE permutes an R8VEC.' ) x = np.array ( [ 1.1, 2.2, 3.3, 4.4, 5.5 ], dtype = np.float64 ) p = np.array ( [ 1, 3, 4, 0, 2 ], dtype = np.int32 ) r8vec_print ( n, x, ' Original array X[]:' ) i4vec_print ( n, p, ' Permutation vector P[]:' ) x = r8vec_permute ( n, p, x ) r8vec_print ( n, x, ' Permuted array X[P[*]]:' ) # # Terminate. # print ( '' ) print ( 'R8VEC_PERMUTE_TEST:' ) print ( ' Normal end of execution.' ) return if ( __name__ == '__main__' ): from timestamp import timestamp timestamp ( ) r8vec_permute_test ( ) timestamp ( )