// this matrix_h02.h file has the matrix Fibonacci norm, diagonal, and the isit?.




//  multiplies the array_in by is transpose, to yield the array = array_in array_intr.
//  thus hiding the ket; but, leaving the bra exposed on each side.
MATRIX_DLL_API
int matrix_fold(MAT *array_in, MAT *array);


//  finds the Fibonacci norm of the matrix:  if take_square_root is 0; will not take the conventional square-root.
MATRIX_DLL_API
int matrix_norm(MAT *array, bool take_square_root, double *norm, MAT *scratch_1);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_check_equality(MAT *array_a, MAT *array_b, double *residue,
						  MAT *scratch_1, MAT *scratch_2);


//  elements imx and jmx have to be pre-assigned.  yields the zero matrix.
MATRIX_DLL_API
int matrix_zero(MAT *array);


//  WARNING:  in situ!
//  sets the principal diagonal to the value x.
MATRIX_DLL_API
int matrix_insitu_set_diagonal(MAT *array, double x);


//  elements imx and jmx have to be pre-assigned.  yields the identity matrix.
MATRIX_DLL_API
int matrix_identity(MAT *array);



//  ***********************************************************
//  the following subroutines operate upon diagonal matrices, exclusively.
//  they will error-out -- with a return value of 64 -- otherwise.


//  finds the product of the corresponding elements of the diagonals.
MATRIX_DLL_API
int matrix_diag_multiply(MAT *array_a, MAT *array_b, MAT *array);


//	sets any diagonal element, whose absolute value is less than or equal to
//		mat_pref.singular times the norm, to exactly ZERO.
MATRIX_DLL_API
int matrix_diag_insitu_singular(MAT *array);

	
//  finds the reciprocal of each non-zero element of the diagonal.
//		each zero element is carried-over as zero.
//  computes and sets the resulting trace.
//	while this routine will to its thing,
//		the significance of the result is doubvious if the matrix is not square.
MATRIX_DLL_API
int matrix_diag_insitu_inverse(MAT *array);


//  finds the absolute value of each of the diagonal.  computes and sets the trace and the determinant.
MATRIX_DLL_API
int matrix_diag_insitu_absolute_value(MAT *array);


MATRIX_DLL_API
int matrix_diag_copy(MAT *array_in, MAT *array);


//	computes the Theta from the rho (which is given by the MDIAG of a channel).
MATRIX_DLL_API
int matrix_diag_acos(MAT *array_in, MAT *array);


//	computes the channel-rate R(Y, X) from the Theta, of the preceding subroutine.
MATRIX_DLL_API
int matrix_diag_minuslogsin(MAT *array_in, MAT *array);


//	computes the Theta from the channel-rate R(Y, X).
//	It is the inverse of the preceding subroutine.
MATRIX_DLL_API
int matrix_diag_asinexpminus(MAT *array_in, MAT *array);


//	computes the rho from the Theta.
//	it is the inverse of the matrix_diag_acos subroutine, above.
MATRIX_DLL_API
int matrix_diag_cos(MAT *array_in, MAT *array);


MATRIX_DLL_API
int matrix_diag_subtract(MAT *array_a, MAT *array_b, MAT *array);


//  finds the reciprocal of each non-zero element of the diagonal.  each zero element is carried-over as zero.
MATRIX_DLL_API
int matrix_diag_inverse(MAT *array_in, MAT *array);


//  finds the square of each element of the diagonal.
MATRIX_DLL_API
int matrix_diag_square(MAT *array_in, MAT *array);


//  finds the square-root of the absolute value of each element of the diagonal.
//	while this routine will to its thing,
//		the significance of the result is doubvious if the matrix is not square.
MATRIX_DLL_API
int matrix_diag_sqrt(MAT *array_in, MAT *array);


//  if the original determinant is not valid; will set this determinant and mark it valid.
MATRIX_DLL_API
int matrix_diag_determinant(MAT *array, double *determinant);


//*******************************************


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_zero(MAT *array, double *residue, MAT *scratch_1);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_identity(MAT *array, double *residue,
						 MAT *scratch_1, MAT *scratch_2, MAT *scratch_3);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_diagonal(MAT *array, double *residue,
						 MAT *scratch_1, MAT *scratch_2);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_orthonormal(MAT *array, double *residue,
						    MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_skewsymmetric(MAT *array, double *residue,
						      MAT *scratch_1, MAT *scratch_2, MAT *scratch_3);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_symmetric(MAT *array, double *residue,
						  MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4);


//  returns the norm of the difference.
MATRIX_DLL_API
int matrix_isit_asclaimed(MAT *array, double *residue,
						  MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4);


MATRIX_DLL_API
int matrix_isit_inverse(MAT *array, MAT *array_inv, double *norm_left, double *norm_right,
						MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4);


MATRIX_DLL_API
int matrix_isit_equal(MAT *array_a, MAT *array_b, double *relative,
					  MAT *scratch_1, MAT *scratch_2);


//	Hermitian by definition is symmetric complex.
//	skew_hermitian by definition is skew_symmetric complex.
//	unitary by defintion is ortho-normal complex.
//	you will need to perform the indicated two tests for each of the foregoing matrices.
MATRIX_DLL_API
int matrix_isit_complex(MAT *array, double *relative,
						MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4,
						MAT *scratch_5, MAT *scratch_6);


//	will error-out with a return of 64; if array is not diagonal.
//	will yield answer:  2=positive-definite, 1=positive, 0=otherwise.
MATRIX_DLL_API
int matrix_diagonal_isit_positive(MAT *array, unsigned long *answer);




// copyright (c) 2003,4 by R.I. 'Scibor-Marchocki.  last modified Monday 17-th May 2004.

// eof
