// this matrix_h07.h file has the Gramm-Schmidt , Rayleigh, Gaussian, and Poisson.  random.




//   pseudo-random value generator  *********************************


//  returns pseudo-random numbers uniformly in [0.0, 1.0).
MATRIX_DLL_API
double pseudo_random(void);




//  Gramm-Schmidt ortho-normalization algorithm  ******************


//  performs, left to right, an insitu Gram-Schmidt ortho-normalization of vertical-vectors.
//  returns a 64 if the set of vectors is dependent.
//		also if the given array is a real-isomorph of a complex matrix.
//	constructs vertical vectors, left to right.
//		if you want horizontal vectors (top to bottom); employ the next subroutine.
MATRIX_DLL_API
int matrix_insitu_GrammSchmidt(MAT *array, unsigned long random);


//	same as previous; but, top to bottom.
MATRIX_DLL_API
int matrix_insitu_downward_GrammSchmidt(MAT *array, unsigned long random, MAT *scratch_1);



//  Gaussian probability distribution  *********************************


//  returns the normalized Rayleigh probability density distribution.  its domain is [0, oo).
MATRIX_DLL_API
double Rayleigh_pdf(double x);


//  returns the normalized Reyleigh commulative probability distribution.  its domain is [0, oo).
MATRIX_DLL_API
double Rayleigh_cpd(double x);


//  returns the inverse of the normalized Rayleigh commulative probability distribution.  its domain is [0, 1).
//  will return a zero for any x outside of its domain.
MATRIX_DLL_API
double Rayleigh_inverse_cpd(double x);


//	computes the x and y coordinates of a random Gaussian event,
//	from a pair (u, v) of random integers in the domain [0, 1)^2.
//  if either of the u or v is outside of its domain; will error-out with a return-code of 64.
MATRIX_DLL_API
int Gaussian_event_coords(double u, double v, double *xx, double *yy);


//  returns the centered normalized Gaussian probability density distribution.  its domain is (-oo, oo).
MATRIX_DLL_API
double Gaussian_pdf(double x);


//  computes a multi-dimensional Gaussian probability density distribution.  its domain is (-oo, oo)^vect_x->jmx..
//	the array is the inverse of the variance matrix.  it has to be positive-definite symmetric.
//		the value of the determinant of this array has to be provided.
//	the vectors x and u have to be horizontal; ie., their imx has to be equal to one.
//  if any of the foregoing conditions is not satisfied; will error-out with a return-code of 64.
MATRIX_DLL_API
int matrix_Gaussian_pdf(MAT *array, double determinant, MAT *vect_x, MAT *vect_u, double *answer,
						MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4);



//   various random matrices *********************************

//  other random matrices are near the end of the matrix_c08.cpp file.



//  elements imx and jmx, of the array, have to be pre-assigned.
//	yields a pseudo-random matrix, with elements uniformly in (-1.0, 1.0].
MATRIX_DLL_API
int matrix_uniformly_random(MAT *array);


//  elements imx and jmx, of the array, have to be pre-assigned.
//	yields a pseudo-random diagonal matrix, with elements uniformly in (-1.0, 1.0].
MATRIX_DLL_API
int matrix_uniformly_random_diagonal(MAT *array);


//	yields a diagonal matrix, of size imx by imx, with elements in a geometric-progression, with
//		the starting value adjusted to make the determinant equal to one.
//	it is presumed -- but, not essential -- that ratio be in the open interval (0, 1).
//	WARNING:  will error-out with a divide-by-zero; if ratio is equal to either one or zero.
MATRIX_DLL_API
int matrix_geometric_diag(unsigned long int imx, double ratio, MAT *diag);


//	yields a pseud-random positive-symmetric matrix of size imx by imx.
MATRIX_DLL_API
int matrix_random_positive_symmetric(unsigned long imx, MAT *array, MAT *scratch);


//	yields a complementary pair of pseudo-random symmetric and skew-symmetric matrices of size imx by imx.
MATRIX_DLL_API
int matrix_random_symmetric_and_skew(unsigned long imx, MAT *symmetric, MAT *skew_symmetric,
							MAT *scratch_1, MAT *scratch_2, MAT *scratch_3);


//  yields a pseudo-random permutation matrix -- which it designates as an ortho-normal matrix --
//		of size imx by imx.
//	set cmp to zero for a real matrix.  set it to one for a complex matrix.
MATRIX_DLL_API
int matrix_random_permutation(unsigned long imx, unsigned long cmp, MAT *array);


//  yields a pseudo-random ortho-normal matrix of size imx by imx.
MATRIX_DLL_API
int matrix_random_orthonormal(unsigned long imx, MAT *array, MAT *scratch_1,
							  MAT *scratch_2, MAT *scratch_3, MAT *scratch_4,
							  MAT *scratch_5);


//	yields a pseudo-random symmetric matrix, with known factors, of size imx by imx.
//	mlicr is the negative of the logarithm, to the base ten, of the ill-conditioning ratio.
MATRIX_DLL_API
int matrix_random_symmetic_and_factors(unsigned long imx, double mlicr, MAT *array, MAT *bra,
									   MAT *diag, MAT *ket, MAT *scratch_1, MAT *scratch_2,
									   MAT *scratch_3);

	
MATRIX_DLL_API
int matrix_random_real_and_factors(unsigned long imx, double mlicr, MAT *array, MAT *bra,
									   MAT *diag, MAT *ket, MAT *scratch_1, MAT *scratch_2,
									   MAT *scratch_3, MAT *scratch_4);


//	yields a pseudo-random real matrix, with known factors, of size imx by imx.
//	mlicr is the negative of the logarithm, to the base ten, of the ill-conditioning ratio.
MATRIX_DLL_API
int matrix_random_real_and_factors(unsigned long imx, double mlicr, MAT *array, MAT *bra,
									   MAT *diag, MAT *ket, MAT *scratch_1, MAT *scratch_2,
									   MAT *scratch_3, MAT *scratch_4);


//   various random complex matrices *********************************


//	the actual complex matrix (ie., with complex elements) is of size imp by jmp.
//		the real-isomorph array is of twice this size.
//	yields a pseudo-random complex matrix, with elements uniformly in (-1.0, 1.0].
MATRIX_DLL_API
int matrix_random_complex(unsigned long imp, unsigned long jmp, MAT *array,
						  MAT *scratch_1, MAT *scratch_2, MAT *scratch_3);


//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//	yields a pseudo-random positive Hermitian matrix, with elements uniformly in (-1.0, 1.0].
MATRIX_DLL_API
int matrix_random_positive_Hermitian(unsigned long imp, MAT *array, MAT *scratch_1,
									 MAT *scratch_2, MAT *scratch_3, MAT *scratch_4);


//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//	yields a pseudo-random Hermitian and skew-Hermitian matrix, with elements uniformly in (-1.0, 1.0].
MATRIX_DLL_API
int matrix_random_Hermitian_and_skew(unsigned long imp, MAT *Hermitian, MAT *skew_Hermitian,
									 MAT *scratch_1, MAT *scratch_2,
									 MAT *scratch_3, MAT *scratch_4);


//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//  yields a pseudo-random unitary matrix.
MATRIX_DLL_API
int matrix_random_unitary(unsigned long imp, MAT *array, MAT *scratch_1,
							  MAT *scratch_2, MAT *scratch_3, MAT *scratch_4,
							  MAT *scratch_5, MAT *scratch_6);


//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//	yields a pseudo-random skew-Hermitian-diagonal matrix, with elements uniformly in (-1.0, 1.0].
MATRIX_DLL_API
int matrix_random_skewHermitiandiagonal(unsigned long imp, MAT *array, MAT *scratch_1, MAT *scratch_2,
							MAT *scratch_3);

	
//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//	yields a diagonal matrix, of size imx by imx, with elements in a geometric-progression, with
//		the starting value adjusted to make the determinant equal to one.
//	it is presumed -- but, not essential -- that ratio be in the open interval (0, 1).
//	WARNING:  will error-out with a divide-by-zero; if ratio is equal to either one or zero.
MATRIX_DLL_API
int matrix_geometric_complex_diag(unsigned long imp, double ratio, MAT *diag,
								  MAT *scratch_1, MAT *scratch_2, MAT *scratch_3);

	
//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//	yields a pseudo-random symmetric matrix, with known factors.
//..		but, see the documentation regarding degrees of freedom..
//	mlicr is the negative of the logarithm, to the base ten, of the ill-conditioning ratio.
MATRIX_DLL_API
int matrix_random_Hermitian_and_factors(unsigned long imp, double mlicr, MAT *array, MAT *bra,
									   MAT *diag, MAT *ket, MAT *scratch_1, MAT *scratch_2,
									   MAT *scratch_3, MAT *scratch_4);


//	the actual complex matrix (ie., with complex elements) is of size imp by imp.
//		the real-isomorph array is of twice this size.
//	yields a pseudo-random complex matrix, with known factors.
//..		but, see the documentation regarding degrees of freedom..
//	mlicr is the negative of the logarithm, to the base ten, of the ill-conditioning ratio.
MATRIX_DLL_API
int matrix_random_complex_and_factors(unsigned long imp, double mlicr, MAT *array, MAT *bra,
									   MAT *diag, MAT *ket, MAT *scratch_1, MAT *scratch_2,
									   MAT *scratch_3, MAT *scratch_4, MAT *scratch_5);





//	copyright (c) 2003,4 by R.I. 'Scibor-Marchocki.  last modified on Thursday 01-st April 2004.
