#! /usr/bin/env python # def idem_random ( n, rank, key ): #*****************************************************************************80 # ## IDEM_RANDOM returns a random idempotent matrix of rank K. # # Properties: # # A is idempotent: A * A = A # # If A is invertible, then A must be the identity matrix. # In other words, unless A is the identity matrix, it is singular. # # I - A is also idempotent. # # All eigenvalues of A are either 0 or 1. # # rank(A) = trace(A) # # A is a projector matrix. # # The matrix I - 2A is involutory, that is ( I - 2A ) * ( I - 2A ) = I. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 14 February 2015 # # Author: # # John Burkardt # # Reference: # # Alston Householder, John Carpenter, # The singular values of involutory and of idempotent matrices, # Numerische Mathematik, # Volume 5, 1963, pages 234-237. # # Parameters: # # Input, integer N, the order of A. # # Input, integer RANK, the rank of A. # 0 <= RANK <= N. # # Input, integer KEY, a positive value that selects the data. # # Output, real A(N,N), the matrix. # import numpy as np from orth_random import orth_random from sys import exit if ( rank < 0 or n < rank ): print ( '' ) print ( 'IDEM_RANDOM - Fatal error!' ) print ( ' RANK must be between 0 and N.' ) print ( ' Input value = %d' % ( rank ) ) exit ( 'IDEM_RANDOM - Fatal error!' ) # # Get a random orthogonal matrix Q. # q = orth_random ( n, key ) # # Compute Q' * D * Q, where D is the diagonal eigenvalue matrix # of RANK 1's followed by N-RANK 0's. # a = np.zeros ( ( n, n ) ) for i in range ( 0, n ): for j in range ( 0, n ): t = 0.0 for k in range ( 0, rank ): t = t + q[k,i] * q[k,j] a[i,j] = t return a def idem_random_determinant ( n, rank, key ): #*****************************************************************************80 # ## IDEM_RANDOM_DETERMINANT returns the determinant of the IDEM_RANDOM matrix. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 14 February 2015 # # Author: # # John Burkardt # # Parameters: # # Input, integer N, the order of the matrix. # # Input, integer RANK, the rank. # # Input, integer KEY, a positive value that selects the data. # # Output, real VALUE, the determinant. # if ( rank == n ): value = 1.0 else: value = 0.0 return value def idem_random_determinant_test ( ): #*****************************************************************************80 # ## IDEM_RANDOM_DETERMINANT_TEST tests IDEM_RANDOM_DETERMINANT. # # Licensing: # # This code is distributed under the GNU LGPL license. #, # Modified: # # 14 February 2015 # # Author: # # John Burkardt # import platform from idem_random import idem_random from r8mat_print import r8mat_print print ( '' ) print ( 'IDEM_RANDOM_DETERMINANT_TEST' ) print ( ' Python version: %s' % ( platform.python_version ( ) ) ) print ( ' IDEM_RANDOM_DETERMINANT: determinant of the IDEM_RANDOM matrix.' ) n = 5 i4_lo = 0 i4_hi = n seed = 123456789 rank, seed = i4_uniform_ab ( i4_lo, i4_hi, seed ) print ( '' ) print ( ' Randomly chosen rank will be %d' % ( rank ) ) key = 123456789 a, seed = idem_random ( n, rank, key ) m = n r8mat_print ( m, n, a, ' IDEM_RANDOM matrix:' ) value = idem_random_determinant ( n, rank, key ) print ( '' ) print ( ' Value = %g' % ( value ) ) # # Terminate. # print ( '' ) print ( 'IDEM_RANDOM_DETERMINANT_TEST' ) print ( ' Normal end of execution.' ) return def idem_random_eigen_right ( n, rank, key ): #*****************************************************************************80 # ## IDEM_RANDOM_EIGEN_RIGHT returns the right eigenvectors of the IDEM_RANDOM matrix. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 17 March 2015 # # Author: # # John Burkardt # # Reference: # # Alston Householder, John Carpenter, # The singular values of involutory and of idempotent matrices, # Numerische Mathematik, # Volume 5, 1963, pages 234-237. # # Parameters: # # Input, integer N, the order of the matrix. # # Input, integer RANK, the rank of A. # 0 <= RANK <= N. # # Input, integer KEY, a positive value that selects the data. # # Output, real X(N,N), the matrix. # import numpy as np from orth_random import orth_random x = orth_random ( n, key ) x = np.transpose ( x ) return x def idem_random_eigenvalues ( n, rank, key ): #*****************************************************************************80 # ## IDEM_RANDOM_EIGENVALUES returns the eigenvalues of the IDEM_RANDOM matrix. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 24 October 2007 # # Author: # # John Burkardt # # Parameters: # # Input, integer N, the order of A. # # Input, integer RANK, the rank of A. # # Input, integer KEY, a positive value that selects the data. # # Output, real LAM(N), the eigenvalues. # import numpy as np lam = np.zeros ( n ) for i in range ( 0, rank ): lam[i] = 1.0 return lam def idem_random_test ( ): #*****************************************************************************80 # ## IDEM_RANDOM_TEST tests IDEM_RANDOM. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 17 March 2015 # # Author: # # John Burkardt # import numpy as np import platform from r8mat_print import r8mat_print n = 5 i4_lo = 0 i4_hi = n seed = 123456789 print ( '' ) print ( 'IDEM_RANDOM_TEST' ) print ( ' Python version: %s' % ( platform.python_version ( ) ) ) print ( ' IDEM_RANDOM computes a random idempotent matrix.' ) rank, seed = i4_uniform_ab ( i4_lo, i4_hi, seed ) print ( '' ) print ( ' Randomly chosen rank will be %d' % ( rank ) ) key = 123456789 a = idem_random ( n, rank, key ) m = n r8mat_print ( m, n, a, ' IDEM_RANDOM matrix:' ) # # Terminate. # print ( '' ) print ( 'IDEM_RANDOM_TEST:' ) print ( ' Normal end of execution.' ) return if ( __name__ == '__main__' ): from timestamp import timestamp timestamp ( ) idem_random_test ( ) timestamp ( )