// this matrix_c08.cpp file has the factor analysis & multi-dimensional linear-regression. // channel rate, angle, and effective correlation coefficient. cascaded channels. #define ELEVEN_MX 17 #define ARR 0 #define AVE 1 #define LBRA 2 #define LDIAG 3 #define MBRA 4 #define MDIAG 5 #define MKET 6 #define RDIAG 7 #define RKET 8 #define LAVE 9 #define RAVE 10 #define REGRxyFWD 11 #define REGRxyINV 12 #define REGRyxFWD 13 #define REGRyxINV 14 #define VarRESyy 15 #define VarRESxx 16 struct channel { MAT eleven[ELEVEN_MX]; double R, Theta, rho; bool valid; }; typedef struct channel CHN; // the effective correlation coefficeint rho -- caution: do not use for linear-regression -- and // the Information Theoretic channel rate R and angle Theta. // they are three ways of expressing the same thing. // this subroutine must be called immediately upon the declaration of the channel. MATRIX_DLL_API void matrix_initialize_channel(CHN *chan); // the user must call for each channel, before the termination of his/her program. MATRIX_DLL_API int matrix_channel_dealloc(CHN *chan); // the background specifies 0=zero matrix 1=identity matrix. // places the array_in along the principal diagonal of an identity matrix, of new_size, // at the specified displacement. MATRIX_DLL_API int matrix_augment(MAT *array_in, unsigned long background, unsigned long new_size, unsigned long displacement, MAT *array); // places the channel represented by the array_in along the principal diagonal // of an identity matrix, of at least new_size, // at the displacement which will place the partitioning in the middle. // the background specifies 0=zero matrix 1=identity matrix. MATRIX_DLL_API int matrix_augment_channel(MAT *array_in, unsigned long background, unsigned long new_size, MAT *array); // from the array_in, crops the array of new size imx by jmx, at the specified displacement, // along the principal diagonal. // you may want to modify the symmetry or other properties of the resulting matrix, // since those provided by this routine may not be valid. MATRIX_DLL_API int matrix_crop(MAT *array_in, unsigned long imx, unsigned long jmx, unsigned long displacement, MAT *array); // from a partitioned positive-definite symmetric matrix computes the small-set. // WARNING: will error-out with a return of 128; if the array is not as specified. // since there is no easy way to test for the "definite", instead, // the algorithms and subroutines are designed to handle a singularity. MATRIX_DLL_API int matrix_part_smallset(MAT *array, MAT *left_bra, MAT *left_diag, MAT *middle_bra, MAT *middle_diag, MAT *middle_ket, MAT *right_diag, MAT *right_ket, MAT *scratch_a, MAT *scratch_b, MAT *scratch_c, MAT *scratch_d, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6, MAT *scratch_7, MAT *scratch_8); // finds the effective correlation coefficeint rho (caution -- do not use for linear-regression -- and // the Information Theoretic channel rate R and effective angle Theta. // they are three ways of expressing the same thing. // the middle_diag is the small-style middle diagonal of a channel. MATRIX_DLL_API int matrix_channel_rate(MAT *middle_diag, double *R, double *Theta, double *rho, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3); // finds the effective correlation coefficeint rho (caution -- do not use for linear-regression -- and // the Information Theoretic channel rate R and effective angle Theta. // they are three ways of expressing the same thing. // the array is the large-style array which is the channel. // computes the channel rate, without factoring the channel. // however, it inverts three matrices. hence, is slower than the foregoing routine. MATRIX_DLL_API int matrix_channel_rate(MAT *array, double *R, double *Theta, double *rho, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6); // also finds the effective correlation coefficeint rho (caution -- do not use for linear-regression -- and // the Information Theoretic channel rate R and effective angle Theta. // they are three ways of expressing the same thing. MATRIX_DLL_API int matrix_smallset_largeset(MAT *left_bra, MAT *left_diag, MAT *middle_bra, MAT *middle_diag, MAT *middle_ket, MAT *right_diag, MAT *right_ket, MAT *exterior_bra, MAT *exterior_diag, MAT *interior_bra, MAT *interior_diag, double *R, double *Theta, double *rho, MAT *scratch_01, MAT *scratch_02, MAT *scratch_1, MAT *scratch_2); MATRIX_DLL_API int matrix_largeset_multiply(MAT *exterior_bra, MAT *exterior_diag, MAT *interior_bra, MAT *interior_diag, MAT *array, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3); // the channel must have all the small elements pre-loaded. // this routine computes the ARR and the AVE from those given small elements and places them into the channel. MATRIX_DLL_API int matrix_construct_channel(CHN *chan, MAT *exterior_bra, MAT *exterior_diag, MAT *interior_bra, MAT *interior_diag, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5); // also finds the effective correlation coefficeint rho (caution -- do not use for linear-regression -- and // the Information Theoretic channel rate R and angle Theta. It stores these three values into the chan // they are three ways of expressing the same thing. // array is the second-order moment matrix, computed about the mean ave, which is a horizontal vector (ie., imx is one).. // each has to be partitioned at the same position and they have to be of the same size. // the array has to be a positive definite symmetric matrix. // the array has to be of even size and partitioned in the middle. added Saturday 13-th March 2004. // if necessary, augment the matrix with an identity matrix along the diagonal. MATRIX_DLL_API int matrix_array_bar_channel(MAT *array, MAT *ave, CHN *chan, MAT *exterior_bra, MAT *exterior_diag, MAT *interior_bra, MAT *interior_diag, MAT *reconstructed, double *residue, MAT *scratch_a, MAT *scratch_b, MAT *scratch_c, MAT *scratch_d, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6, MAT *scratch_7, MAT *scratch_8); // performs the calculation y = (x - xo) * array + yo, where x, xo, yo, y are horizontal vectors. // the size of x and xo is assumed to be equal to the height imx of the array. // the size of yo and y is assumed to be equal to the width jmx of the array. // xo is the average of the x. yo is the average of the y. // array is the regression-matrix obtained from the REGR or REGR_INV // (or either of their transposes) of the channel. // x is the input variable. y is the predicted-value of the output variable. // WARNING: Unlike the rest of this library, this program is not designed to check the sizes of // the input or output vectors. MATRIX_DLL_API int matrix_compute_regression(double *x_vect, double *xo_vect, MAT *array, double *yo_vect, double *y_vect); // finds the effective correlation coefficient rho_opt -- caution: do not use for linear-regression -- and // the Information Theoretic channel rate R_opt and angle Theta_opt, // that result from an optimum middle channel, which may be shown to be provided by an identity matrix. // they are three ways of expressing the same thing. MATRIX_DLL_API int matrix_3cascade_opt_channel_rate(CHN *chan1, CHN *chan3, double *R_opt, double *Theta_opt, double *rho_opt, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4); // finds the effective correlation coefficient rho -- caution: do not use for linear-regression -- and // the Information Theoretic channel rate R and angle Theta, // which may be shown to be provided by an identity matrix. // they are three ways of expressing the same thing. // also finds the middle_bra, middle_diag, and middle_ket. MATRIX_DLL_API int matrix_3cascade_opt_channel_rate(CHN *chan1, MAT *ortho, CHN *chan3, double *R, double *Theta, double *rho, MAT *middle_bra, MAT *middle_diag, MAT *middle_ket, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6, MAT *scratch_7, MAT *scratch_8, MAT *scratch_9); // also finds the effective correlation coefficeint rho -- caution: do not use for linear-regression -- and // the Information Theoretic channel rate R and angle Theta. It stores these three values into the chan // they are three ways of expressing the same thing. // the R_opt, Theta_opt, and rho_opt are those that result from an optimum middle channel, // which may be shown to be provided by an identity matrix. // constructs the cascaded channel from the first channel, // the second channel represented by an ortho-normal array, and the third channel. MATRIX_DLL_API int matrix_3cascade(CHN *chan1, MAT *ortho, CHN *chan3, CHN *chan, double *R_opt, double *Theta_opt, double *rho_opt, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5); // ********* five specialized routines for construction ********************* // yields an ortho-normal array of the of the designated size. // if sw is 1; the array_in, must by ortho-normal, // else will error-out with a return of 8. // sw: 0=identity, 1=transpose, 2=random. MATRIX_DLL_API int matrix_orthonormal_xxx(unsigned long sw, unsigned long size, MAT *array_in, MAT *array, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5); // yields a diagonal array of the designated size, // whose first element is equal to start and // subsequent elements are in a geometric-progression with the specified ratio. // WARNING: intentionally no diagnostics, so that we may check downstreem diagnostics. MATRIX_DLL_API int matrix_diagonal_xxx(unsigned long size, double start, double ratio, MAT *array); // yields a horizontal-vector of the designated size. // sw: 0=zero, 1=random. MATRIX_DLL_API int matrix_vect_xxx(unsigned long sw, unsigned long size, MAT *array); // yields a channel of small-size size. // see the prededing three routines for sw, start, and ratio. // WARNING: intentionally no diagnostics, so that we may check downstreem diagnostics. // each of start_LDIAG, ratio_LDIAG, start_RDIAG, and ratio_RDIAG should be strictly positive. // the magnitude of each of start_MDIAG and ratio_MDIAG should be strictly less than one. MATRIX_DLL_API int matrix_channel_xxx(unsigned long size, unsigned long sw_LBRA, unsigned long sw_MBRA, unsigned long sw_MKET, unsigned long sw_RKET, unsigned long sw_LAVE, unsigned long sw_RAVE, double start_LDIAG, double ratio_LDIAG, double start_MDIAG, double ratio_MDIAG, double start_RDIAG, double ratio_RDIAG, CHN *chan, MAT *exterior_bra, MAT *exterior_diag, MAT *interior_bra, MAT *interior_diag, double *R, double *Theta, double *rho, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6); // compares each of the corresponding elements of a pair of channels. // the sum of the individual relative values is stored into relative[ELEVEN_MX]. // NOTE: these test is insufficiently sophisticated for testing a degenerate matrix. // that is, for a degenerate matrix, it almost always, it will yield a // false positive -- not equal -- for the corresponding ortho-normal matrix. // not to worry: a matrix is degenerate almost never. // except, of course, when it is constructed explicitly to be so. :-) // also, the ortho-normal matrices usually will not test equal if they are constructed // by different algorithms: bi-linear, Gramm-Schmidt, or Jacobi. // in short, if the relative[ELEVEN_MX] is acceptably small (in magnitude); // then, the two channels are equal. However, otherwise, the result is not decisive. MATRIX_DLL_API int matrix_isit_equal_channels(CHN *chan_a, CHN *chan_b, double relative[ELEVEN_MX + 1], MAT *scratch_1, MAT *scratch_2); // copyright (c) 2003,4 by R.I. 'Scibor-Marchocki. last modified Monday 17-th May 2004.