/******************************************************************* Subroutine to compute the Covariance Matrix (CM) matrix *X: the pointer to the matrix matrix *covm: the pointer to the output covariance matrix *******************************************************************/ void mcovar(matrix *X, matrix *covm) { int i, j, k; vector Coli; // the pointer to the 'i'th column vector vector Colj; // the pointer to the 'j'th column vector double *pxi; double *pxj; double *pci; vnew(&Coli, X->m); vnew(&Colj, X->m); covm->m = X->n; covm->n = X->n; for (i=0; i<(X->n); i++) { // i -- row index of CM for (j=0; j<(X->n); j++) { // j -- column index of CM for (k=0; k<(X->m); k++) { pxi = X->pr + i; pxj = X->pr + j; *(Coli.pr+k) = *(pxi+(X->n)*k); *(Colj.pr+k) = *(pxj+(X->n)*k); } // the value of CM[i,j] pci = covm->pr + (covm->m)*i; *(pci+j) = vcovar(&Coli, &Colj); } } vdelete(&Coli); vdelete(&Colj); }
grayscale_image * grayscale_image::load(const char * filename) { grayscale_image * result = 0; if (vStringCaseEndsIn(filename, ".ppm")) { color_image * the_image = color_image::load(filename); if (the_image == 0) { return 0; } result = the_image->ToGray(); vdelete(the_image); } else if (vStringCaseEndsIn(filename, ".pgm")) { vPPM_Header header(filename); if ((strcmp(header.Header(), "P5\n") != 0) && (strcmp(header.Header(), "P2\n") != 0)) { return 0; } result = new grayscale_image(header.Rows(), header.Cols()); if (strcmp(header.Header(), "P5\n") == 0) { result->ReadBandwise(filename, header.Offset()); } else if (strcmp(header.Header(), "P2\n") == 0) { result->ReadTextBandwise(filename, header.Offset()); } } else if (vStringCaseEndsIn(filename, ".bmp")) { color_image * the_image = color_image::load(filename); if (the_image == 0) { return 0; } result = the_image->ToGray(); vdelete(the_image); } else { return 0; } return result; }
ushort grayscale_image::save(const char * filename) { ushort result = 1; if (vStringCaseEndsIn(filename, ".ppm")) { color_image * the_image = this->color_copy(); result = the_image->save(filename); vdelete(the_image); } else if (vStringCaseEndsIn(filename, ".pgm")) { vPPM_Header header((vint4) rows, (vint4) cols, "P5\n"); FILE * fp = fopen(filename, vFOPEN_WRITE); if (fp == 0) return 0; ushort success; success = header.Write(fp); if (success == 0) result = 0; success = WriteBandwise(fp); if (success == 0) result = 0; fclose(fp); } else if (vStringCaseEndsIn(filename, ".bmp")) { result = (ushort) function_save_grayscale_bitmap(this, filename); } else if (vStringCaseEndsIn(filename, ".bmp")) { result = store(filename); } return result; }
/******************************************************************* Subroutine to compute the Variance of Matrix matrix *X: the pointer to the matrix char direction: 'c' - compute the mean of each column 'r' - compute the mean of each row vector *mean: the pointer to the mean vector *******************************************************************/ int mvar(matrix *X, char direction, vector *var) { int row_l, row_n; int i; int result; vector col_vec; vector row_vec; row_l = X->n; row_n = X->m; vnew(&col_vec, row_n); vnew(&row_vec, row_l); if (direction == 'c') { // compute the variance of each column var->l = row_l; for (i=0; i<row_l; i++) { getcolvec(X, i, &col_vec); *(var->pr + i) = vcovar(&col_vec, &col_vec); } result = 1; } else if (direction == 'r') { // compute the variance of each row var->l = row_n; for (i=0; i<row_n; i++) { getrowvec(X, i, &row_vec); *(var->pr + i) = vcovar(&row_vec, &row_vec);; } result = 1; } else { result = 0; printf("the direction parameter should be 'c' or 'r'"); } vdelete(&col_vec); vdelete(&row_vec); return result; }
/******************************************************************* Subroutine to compute the inverse matrix and determinant matrix *cov: the pointer to the covariance matrix matrix *inv_cov: the pointer to the inverse covariance matrix matrix *cov_mat: the pointer to the approximate covariance matrix when singular. If unsingular, it equals to cov double *det_cov: the pointer to determinant return value: '1' - successfully exit '0' - exit with waring/error *******************************************************************/ int veCov(matrix *cov, matrix *inv_cov, matrix *cov_mat, double *det_cov) { int i, j; matrix eigvec_re; matrix eigvec_im; vector eigval_re; vector eigval_im; int *eig_order; int eig_info; int num_v; // the number of eigenvalue int rank_c; double sum_v; double factor = 0.02; double ass_value; double min_real; mnew(&eigvec_re, cov->m, cov->n); mnew(&eigvec_im, cov->m, cov->n); vnew(&eigval_re, cov->n); vnew(&eigval_im, cov->n); eig_order = new int[cov->n]; // the eigenvector and eigenvalue of covariance matrix eig_info = eig(cov, &eigvec_re, &eigvec_im, &eigval_re, &eigval_im); //vprint(&eigval_re); //vprint(&eigval_im); if (!eig_info) { printf(" The eigenvalue computation failed! \n"); return 0; //.... } // the rank of covariance matrix num_v = cov->n; /*rank_c = num_v; for (i=0; i<num_v; i++) { if ((fabs(*(eigval_re.pr+i)) < ZEROTHRESH) && (fabs(*(eigval_im.pr+i)) < ZEROTHRESH)) { rank_c--; } } printf("rank = %d", rank_c);*/ rank_c = rank(cov, TOLERANCE); // compute the inverse and determinate if (rank_c == num_v) { // nonsingular inv(cov, inv_cov); mcopy(cov, cov_mat); *det_cov = det(cov); } else { // singular min_real = pow(10, (((double)-250) / ((double) cov->m))); /*for (i=0; i<num_v; i++) { if ((*(eigval_re.pr+i) < ZEROTHRESH) || (*(eigval_im.pr+i) != 0)) { *(eigval_re.pr+i) = 0; // ???? keep the real part of complex or not *(eigval_im.pr+i) = 0; } } sort(&eigval_re, eig_order, 'd'); */ for (i=0; i<num_v; i++) { // when negtive real eigenvalue, change to absolute value // to ensure all the real eigenvalues are positive if ((eigval_re.pr[i] < 0) && (eigval_im.pr[i] == 0)) { eigval_re.pr[i] *= -1; // the i-th column of eigenvector should also be changed the sign for (j=0; j<(eigvec_re.m); j++) { eigvec_re.pr[j*(eigvec_re.n)+i] *= -1; } } } //vprint(&eigval_re); //vprint(&eigval_im); // sort real eigenvalues descendingly, put complex ones at the end sorteig(&eigval_re, &eigval_im, eig_order); for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = 0; *(eigval_im.pr+i) = 0; } //vprint(&eigval_re); //vprint(&eigval_im); sum_v = vsum(&eigval_re); ass_value = factor * sum_v / (num_v - rank_c); if (ass_value < (0.5 * (*(eigval_re.pr+rank_c)) * (1 - factor))) { if (ass_value > min_real) { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = ass_value; } for (i=0; i<rank_c; i++) { *(eigval_re.pr+i) *= 1 - factor; } } else { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = min_real; } } } else { ass_value = 0.5 * (*(eigval_re.pr+rank_c)) * (1 - factor); if (ass_value > min_real) { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = ass_value; } for (i=0; i<rank_c; i++) { *(eigval_re.pr+i) = *(eigval_re.pr+i) - ass_value * (num_v - rank_c) * (*(eigval_re.pr+i)) / sum_v; } } else { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = min_real; } } } //vprint(&eigval_re); //vprint(&eigval_im); matrix eigvec_re_sorted; matrix eigvec_re_sorted_t; mnew(&eigvec_re_sorted, num_v, num_v); mnew(&eigvec_re_sorted_t, num_v, num_v); sortcols(eig_order, &eigvec_re, &eigvec_re_sorted); transpose(&eigvec_re_sorted, &eigvec_re_sorted_t); matrix inv_eig_vl_s; mnew(&inv_eig_vl_s, num_v, num_v); for (i=1; i<num_v; i++) { *(inv_eig_vl_s.pr + i*num_v + i) = 1 / (*(eigval_re.pr+i)); } matrix tmp; mnew(&tmp, num_v, num_v); mmMul(&eigvec_re_sorted, &inv_eig_vl_s, &tmp); mmMul(&tmp, &eigvec_re_sorted_t, inv_cov); matrix diag_eigval; mnew(&diag_eigval, num_v, num_v); for (i=0; i<num_v; i++) { *(diag_eigval.pr + i*num_v + i) = *(eigval_re.pr+i); } mmMul(&eigvec_re_sorted, &diag_eigval, &tmp); mmMul(&tmp, &eigvec_re_sorted_t, cov_mat); *det_cov = 1; for (i=0; i<num_v; i++) { *det_cov = (*det_cov) * (*(eigval_re.pr+i)); } mdelete(&inv_eig_vl_s); mdelete(&eigvec_re_sorted); mdelete(&eigvec_re_sorted_t); mdelete(&tmp); mdelete(&diag_eigval); } #ifdef _DEBUG printf("rank = %d \n", rank_c); printf("\n det_cov = %e \n", *det_cov); printf("inv_cov = \n"); mprint(inv_cov); printf("cov_mat = \n"); mprint(cov_mat); #endif mdelete(&eigvec_re); mdelete(&eigvec_im); vdelete(&eigval_re); vdelete(&eigval_im); delete []eig_order; return 1; }
/******************************************************************* Subroutine to do the EM algorithm matrix *D: the pointer to the matrix data matrix *mean0_x: the pointer to a matrix containing the initial Means of clusters vector *w0: the pointer to a vector containing the initial mixing proportion of clusters double vv: the value for initializing the Covariance matrix of clusters double error: the error threshold vector *Zjk_up: the pointer to a vector containing Posterior probabilities of the up-level cluster samples matrix *mean1_x: the pointer to a matrix containing the Means of clusters in t-space vector *w0_t: the pointer to a vector containing the mixing proportions of the identified clusters in t-space matrix *cov_mat: the pointer to a group of matrixs containing the Covariance matrix of clusters in t-space matrix *Zjk: the pointer to a matrix containing Posterior probabilities of all samples belonging to all the sub-level clusters, each column is for one cluster. return value: '1' - successfully exit '0' - exit with waring/error *******************************************************************/ int veSubEM(matrix *D, matrix *mean0_x, vector *w0, double vv, double error, vector *Zjk_up, //input matrix *mean1_x, vector *w0_t, matrix *cov_mat, matrix *Zjk) //output { int k0, kc, n, p; int i, j, k, u, s; matrix *Var0; matrix Gxn; vector Fx; matrix MUK; matrix MU1; int zeroFx_num = 1; //double error = 0.01; double err = error + (double)1; vector Zjk_temp; n = D->m; p = D->n; k0 = mean0_x->m; kc = mean0_x->n; Var0 = new matrix[k0]; for(i=0; i<k0; i++) { mnew(Var0+i, p, p); } mnew(&Gxn, n, k0); vnew(&Fx, n); vnew(&Zjk_temp, n); mnew(&MUK, k0, p); mcopy(mean0_x, &MUK); mnew(&MU1, k0, p); vector D_j; vector Zjk_k; double sum_tmp = 0; matrix Ck; vector D_i; vector MUK_k; vector cen_D_i; matrix mtmp; vector vtmp; vnew(&D_j, n); vnew(&Zjk_k, n); mnew(&Ck, p, p); vnew(&D_i, p); vnew(&MUK_k, p); vnew(&cen_D_i, p); mnew(&mtmp, p, p); vnew(&vtmp, n); //Initializing the parameters of mixture of Gaussians //Initinalize the covariance matrix //Use EM algorithm to perform the local training. //Test intialization of covarinace matrix //printf("Testing covariance matrix initialization... \n"); while (zeroFx_num != 0) { for(i=0; i<k0; i++) { meye(Var0+i); for (j=0; j<p; j++) { *((Var0+i)->pr+j*p+j) = vv; } } veModel(D, mean0_x, Var0, w0, &Gxn, &Fx); //printf("\n Gxn = :\n"); //mprint(&Gxn); //printf("\n Fx = :\n"); //vprint(&Fx); zeroFx_num = 0; for (i=0; i<n; i++) { if (*(Fx.pr+i) == 0) { zeroFx_num++; } } vv *= 2; } vones(&Zjk_temp); //printf("\n EM in t-space starts ... \n"); //printf("\n Data = \n"); //mprint(D); int l = 0; while (err > error) { #ifdef _DEBUG printf(" \n...... in EM loop %d ......\n", ++l); printf("\n L%d: w0 = \n", l); vprint(w0); printf("\n L%d: MUK = \n", l); mprint(&MUK); printf("\n L%d: Var0 = \n", l); for(i=0; i<k0; i++) { mprint(Var0+i); printf("\n"); } printf("\n L%d: Zjk = \n", l); mprint(Zjk); #endif veModel(D, &MUK, Var0, w0, &Gxn, &Fx); #ifdef _DEBUG printf("\n L%d: Gxn = \n", l); mprint(&Gxn); printf("\n L%d: Fx = \n", l); vprint(&Fx); #endif for (k=0; k<k0; k++) { u = k*p; double zz = 0; double zz_up = 0; for (i=0; i<n; i++) { *(Zjk->pr+i*k0+k) = (*(w0->pr+k)) * Zjk_up->pr[i] * (*(Gxn.pr+i*k0+k)) / (*(Fx.pr+i)); zz += *(Zjk->pr+i*k0+k); zz_up += Zjk_up->pr[i]; } *(w0->pr+k) = zz/zz_up; for (j=0; j<p; j++) { getcolvec(D, j, &D_j); getcolvec(Zjk, k, &Zjk_k); sum_tmp = 0; for (i=0; i<n; i++) { sum_tmp += (*(Zjk_k.pr+i)) * (*(D_j.pr+i)); } *(MU1.pr+u+j) = sum_tmp / zz; } mzero(&Ck); for (i=0; i<n; i++) { getrowvec(D, i, &D_i); getrowvec(&MUK, k, &MUK_k); for (j=0; j<p; j++) { *(cen_D_i.pr+j) = *(D_i.pr+j) - *(MUK_k.pr+j); } vvMul(&cen_D_i, &cen_D_i, &mtmp); for (j=0; j<p; j++) { for (s=0; s<p; s++) { *(Ck.pr+j*p+s) += (*(Zjk->pr+i*k0+k)) * (*(mtmp.pr+j*p+s)); } } } for (j=0; j<p; j++) { for (s=0; s<p; s++) { *(Var0[k].pr+j*p+s) = (*(Ck.pr+j*p+s)) / zz; } } } // for (k... mcopy(&MU1, &MUK); for (i=0; i<n; i++) { *(vtmp.pr+i) = fabs(*(Zjk_k.pr+i) - *(Zjk_temp.pr+i)); } err = vmean(&vtmp); vcopy(&Zjk_k, &Zjk_temp); } // while vcopy(w0, w0_t); mcopy(&MUK, mean1_x); for(i=0; i<k0; i++) { mcopy(Var0+i, cov_mat+i); } for(i=0; i<k0; i++) { mdelete(Var0+i); } mdelete(&Gxn); vdelete(&Fx); vdelete(&Zjk_temp); mdelete(&MUK); mdelete(&MU1); vdelete(&D_j); vdelete(&Zjk_k); mdelete(&Ck); vdelete(&D_i); vdelete(&MUK_k); vdelete(&cen_D_i); mdelete(&mtmp); vdelete(&vtmp); return 1; }
/* Main */ int main() { matrix MX; mnew(&MX, 200, 8); sampleLoad("data_200x8.txt", &MX); printf("data=\n"); mprint(&MX); double mean[2][8]= {{4.427227e-001, 7.671556e-001, -9.523772e-001, 3.867558e-001, -7.916976e-001, 1.165247e-001, -1.261666e-001, 8.550054e-002}, {-2.383899e-001, -4.130850e-001, 5.128200e-001, -2.082537e-001, 4.263000e-001, -6.274427e-002, 6.793605e-002, -4.603889e-002}}; matrix MUK; mnew(&MUK, 2, 8); MUK.pr = *mean; matrix *Var0; Var0 = new matrix[2]; for(int i=0; i<2; i++) { mnew(Var0+i, 8, 8); } sampleLoad("var0.txt", Var0); printf("var0=\n"); mprint(Var0); sampleLoad("var1.txt", Var0+1); printf("var1=\n"); mprint(Var0+1); double W[] = {3.500007e-001, 6.499993e-001}; vector w0; vnew(&w0, 2); w0.pr = W; matrix Gxn; mnew(&Gxn, 200, 2); vector Fx; vnew(&Fx, 200); veModel(&MX, &MUK, Var0, &w0, &Gxn, &Fx); printf("Gxn=\n"); mprint(&Gxn); printf("Fx=\n"); vprint(&Fx); matrix tmp; mnew(&tmp, 1, 8); matrix tmp2; mnew(&tmp2, 1, 1); matrix cen_Dj; mnew(&cen_Dj, 1, 8); matrix cen_Dj_t; mnew(&cen_Dj_t, 8, 1); for(i=0; i<8; i++) { *(cen_Dj.pr+i) = *(MX.pr+0+i) - *(MUK.pr+8+i); } transpose(&cen_Dj, &cen_Dj_t); printf("\ncen_Dj=\n"); mprint(&cen_Dj); mprint(&cen_Dj_t); matrix inv_Var1; mnew(&inv_Var1, 8, 8); sampleLoad("inv_var1.txt", &inv_Var1); mprint(&inv_Var1); mmMul(&cen_Dj, &inv_Var1, &tmp); printf("\ntmp=\n"); mprint(&tmp); mmMul(&tmp, &cen_Dj_t, &tmp2); printf("\ntmp2=\n"); mprint(&tmp2); double val = *(tmp2.pr); printf("\nval=%e\n", val); mdelete(&MX); mdelete(&MUK); mdelete(Var0); mdelete(Var0+1); vdelete(&w0); mdelete(&Gxn); vdelete(&Fx); return 0; }
/* * Change operator. * * In a single line we mark the end of the changed area with '$'. * On multiple whole lines, we clear the lines first. * Across lines with both wcursor and wdot given, we delete * and sync then append (but one operation for undo). */ void vchange(int c) { register char *cp; register int i, ind, cnt; line *addr; if (wdot) { /* * Change/delete of lines or across line boundaries. */ if ((cnt = xdw()) < 0) return; getDOT(); if (wcursor && cnt == 1) { /* * Not really. */ wdot = 0; if (c == EOF) { vdelete(c); return; } goto smallchange; } if (cursor && wcursor) { /* * Across line boundaries, but not * necessarily whole lines. * Construct what will be left. */ *cursor = 0; strcpy(genbuf, linebuf); getline(*wdot); if (strlen(genbuf) + strlen(wcursor) > LBSIZE - 2) { getDOT(); beep(); return; } strcat(genbuf, wcursor); if (c == EOF && *vpastwh(genbuf) == 0) { /* * Although this is a delete * spanning line boundaries, what * would be left is all white space, * so take it all away. */ wcursor = 0; getDOT(); op = 0; notpart(lastreg); notpart('1'); vdelete(c); return; } ind = -1; } else if (c == EOF && wcursor == 0) { vdelete(c); return; } else #ifdef LISPCODE /* * We are just substituting text for whole lines, * so determine the first autoindent. */ if (value(LISP) && value(AUTOINDENT)) ind = lindent(dot); else #endif ind = whitecnt(linebuf); i = vcline >= 0 ? LINE(vcline) : WTOP; /* * Delete the lines from the buffer, * and remember how the partial stuff came about in * case we are told to put. */ addr = dot; vremote(cnt, delete, 0); setpk(); notenam = "delete"; if (c != EOF) notenam = "change"; /* * If DEL[0] were nonzero, put would put it back * rather than the deleted lines. */ DEL[0] = 0; if (cnt > 1) killU(); /* * Now hack the screen image coordination. */ vreplace(vcline, cnt, 0); wdot = NOLINE; noteit(0); vcline--; if (addr <= dol) dot--; /* * If this is a across line delete/change, * cursor stays where it is; just splice together the pieces * of the new line. Otherwise generate a autoindent * after a S command. */ if (ind >= 0) { *genindent(ind) = 0; vdoappend(genbuf); } else { vmcurs = cursor; strcLIN(genbuf); vdoappend(linebuf); } /* * Indicate a change on hardcopies by * erasing the current line. */ if (c != EOF && state != VISUAL && state != HARDOPEN) { int oldhold = hold; hold |= HOLDAT, vclrlin(i, dot), hold = oldhold; } /* * Open the line (logically) on the screen, and * update the screen tail. Unless we are really a delete * go off and gather up inserted characters. */ vcline++; if (vcline < 0) vcline = 0; vopen(dot, i); vsyncCL(); noteit(1); if (c != EOF) { if (ind >= 0) { cursor = linebuf; linebuf[0] = 0; vfixcurs(); } else { ind = 0; vcursat(cursor); } vappend('x', 1, ind); return; } if (*cursor == 0 && cursor > linebuf) cursor += skipleft(linebuf, cursor); vrepaint(cursor); return; } smallchange: /* * The rest of this is just low level hacking on changes * of small numbers of characters. */ if (wcursor < linebuf) wcursor = linebuf; if (cursor == wcursor) { beep(); return; } i = vdcMID(); cp = cursor; if (state != HARDOPEN) vfixcurs(); /* * Put out the \\'s indicating changed text in hardcopy, * or mark the end of the change with $ if not hardcopy. */ if (state == HARDOPEN) bleep(i, cp); else { int c, d, n; vcursbef(wcursor); d = skipleft(linebuf, wcursor); nextc(c, &wcursor[d], n); if (colsc(c) > 1) putchar(' '); putchar('$'); i = cindent(); } /* * Remember the deleted text for possible put, * and then prepare and execute the input portion of the change. */ cursor = cp; setDEL(); CP(cursor, wcursor); if (state != HARDOPEN) { vcursaft(cursor - 1); doomed = i - cindent(); } else { /* sethard(); wcursor = cursor; cursor = linebuf; vgoto(outline, value(NUMBER) << 3); vmove(); */ doomed = 0; } prepapp(); vappend('c', 1, 0); }
/******************************************************************* Subroutine to do the Sub-Level PCA-PPM matrix *pcadata_re: the pointer to the new matrix containing the real part of data projected onto the space defined by the PCA matrix *pcadata_re: the pointer to the new matrix containing the imaginary part of data projected onto the space defined by the PCA matrix *pcavec_re: the pointer to a matrix containing the real part of eigenvector matrix *pcavec_im: the pointer to a matrix containing the imaginary part of eigenvector vector *pcaval_re: the pointer to a vector containing the real part of eigenvalues vector *pcaval_im: the pointer to a vector containing the imaginary part of eigenvalues vector *Zjk: the pointer to a vector containing the Zjk values matrix *subpcappmvec_re: the pointer to a matrix containing the real part of sorted eigenvectors by sub kurtosis rank matrix *subpcappmvec_re: the pointer to a matrix containing the imaginary part of sorted eigenvectors by sub kurtosis rank return value: '1' - successfully exit '0' - exit with waring/error *******************************************************************/ int veSubPCAPPM(matrix *pcadata_re, matrix *pcadata_im, matrix *pcavec_re, matrix *pcavec_im, vector *pcaval_re, vector *pcaval_im, vector *Zjk, matrix *subpcappmvec_re, matrix *subpcappmvec_im) { int m, n; int i, j, u=0, v=0; vector X1n, Xm1; matrix mZjk; matrix M1; matrix data_pow2; matrix data_pow4; vector V1; vector V2; vector V4; vector kurt; int* kurt_id; double sumZjk; double cen_data; bool allreal = true; m=pcadata_re->m; n=pcadata_im->n; vnew(&X1n, n); vnew(&Xm1, m); mnew(&mZjk, m, n); mnew(&M1, m, n); mnew(&data_pow2, m, n); mnew(&data_pow4, m, n); vnew(&V1, n); vnew(&V2, n); vnew(&V4, n); vnew(&kurt, n); kurt_id = new int[n]; vector V1_im; vector Xm1_im; matrix M1_im; double cen_data_im; matrix data_pow2_im; matrix data_pow4_im; vector V2_im; vector V4_im; vector kurt_im; vnew(&Xm1_im, m); mnew(&M1_im, m, n); mnew(&data_pow2_im, m, n); mnew(&data_pow4_im, m, n); vnew(&V1_im, n); vnew(&V2_im, n); vnew(&V4_im, n); vnew(&kurt_im, n); // whether complex eigenvalue exists for (i=0; i<n; i++) { if (*(pcaval_im->pr+i) != 0) { allreal = false; break; } } // center the data set its means // data_proj = data_proj - ones(n,1)*(sum(Zjk*ones(1,p).*(data_proj))./sum(Zjk)); vones(&X1n); vones(&Xm1); vvMul(Zjk, &X1n, &mZjk); sumZjk = vsum(Zjk); if (allreal==true) { kurtmodel(&mZjk, sumZjk, pcadata_re, &V1); vvMul(&Xm1, &V1, &M1); for (i=0; i<m*n; i++) { cen_data = *(pcadata_re->pr + i) - *(M1.pr + i); //*(data->pr + i) = cen_data; *(data_pow2.pr+i) = pow(cen_data, 2); *(data_pow4.pr+i) = pow(cen_data, 4); } // calculate kurtosis : kurt(y) = E{y^4}-3(E{y^2})^2 //kurt = sum(Zjk*ones(1,p).*(data_proj.^4))./sum(Zjk)... //- 3*(sum(Zjk*ones(1,p).*(data_proj.^2))./sum(Zjk)).^2; %Not normalized Kurtosis kurtmodel(&mZjk, sumZjk, &data_pow2, &V2); kurtmodel(&mZjk, sumZjk, &data_pow4, &V4); for (j=0; j<n; j++) { *(kurt.pr+j) = *(V4.pr+j) - 3*(pow(*(V2.pr+j), 2)); } } else { ckurtmodel(&mZjk, sumZjk, pcadata_re, pcadata_im, &V1, &V1_im); cvvMul(&Xm1, &Xm1_im, &V1, &V1_im, &M1, &M1_im); for (i=0; i<m*n; i++) { cen_data = *(pcadata_re->pr + i) - *(M1.pr + i); cen_data_im = *(pcadata_im->pr + i) - *(M1_im.pr + i); //*(data->pr + i) = cen_data; *(data_pow2.pr+i) = pow(cen_data, 2) - pow(cen_data_im, 2); *(data_pow2_im.pr+i) = 2 * cen_data * cen_data_im; *(data_pow4.pr+i) = pow(*(data_pow2.pr+i), 2) - pow(*(data_pow2_im.pr+i), 2); *(data_pow4_im.pr+i) = 2 * (*(data_pow2.pr+i)) * (*(data_pow2_im.pr+i)); } // calculate kurtosis : kurt(y) = E{y^4}-3(E{y^2})^2 //kurt = sum(Zjk*ones(1,p).*(data_proj.^4))./sum(Zjk)... //- 3*(sum(Zjk*ones(1,p).*(data_proj.^2))./sum(Zjk)).^2; %Not normalized Kurtosis ckurtmodel(&mZjk, sumZjk, &data_pow2, &data_pow2_im, &V2, &V2_im); ckurtmodel(&mZjk, sumZjk, &data_pow4, &data_pow4_im, &V4, &V4_im); for (j=0; j<n; j++) { *(kurt.pr+j) = *(V4.pr+j) - 3*(pow(*(V2.pr+j), 2) - pow(*(V2_im.pr+j), 2)); *(kurt_im.pr+j) = *(V4_im.pr+j) - 3 * 2 * (*(V2.pr+j)) * (*(V2_im.pr+j)); } } // sort kurt value in ascending order and reorder the pca_vec int realeig_num; int *realeig_id; int *compeig_id; vector realkurt; int *real_order; realeig_num = n; for (i=0; i<n; i++) { if (*(pcaval_im->pr+i) != 0) { realeig_num--; } } vnew(&realkurt, realeig_num); realeig_id = new int[realeig_num]; compeig_id = new int[n-realeig_num]; real_order = new int[realeig_num]; for (i=0; i<n; i++) { if (*(pcaval_im->pr+i) == 0) { realeig_id[u] = i; *(realkurt.pr+u) = *(kurt.pr+i); u++; } else { compeig_id[v] = i; v++; } } sort(&realkurt, real_order, 'a'); int *tmp; tmp = new int[realeig_num]; for (i=0; i<realeig_num; i++) { tmp[i] = realeig_id[i]; } for (i=0; i<realeig_num; i++) { realeig_id[i] = tmp[real_order[i]]; } delete []tmp; vector kurt0; vector kurt0_im; vnew(&kurt0, kurt.l); vcopy(&kurt, &kurt0); vnew(&kurt0_im, kurt.l); vcopy(&kurt_im, &kurt0_im); for (i=0; i<realeig_num; i++) { kurt_id[i] = realeig_id[i]; *(kurt.pr+i) = *(realkurt.pr+i); *(kurt_im.pr+i) = 0; } for (i=0; i<n-realeig_num; i++) { kurt_id[i+realeig_num] = compeig_id[i]; *(kurt.pr+i+realeig_num) = *(kurt0.pr + compeig_id[i]); *(kurt_im.pr+i+realeig_num) = *(kurt0_im.pr + compeig_id[i]); } //printf(" the real part of kurt value is : \n"); //vprint(&kurt); //printf(" the imaginary part of kurt value is : \n"); //vprint(&kurt_im); //printf(" the kurt id is : \n"); //for (i=0; i<n; i++) { // printf("%d\t", kurt_id[i]); //} sortcols(kurt_id, pcavec_re, subpcappmvec_re); sortcols(kurt_id, pcavec_im, subpcappmvec_im); vdelete(&X1n); vdelete(&Xm1); mdelete(&mZjk); mdelete(&M1); mdelete(&data_pow2); mdelete(&data_pow4); vdelete(&V1); vdelete(&V2); vdelete(&V4); vdelete(&kurt); vdelete(&kurt0); delete []kurt_id; vdelete(&realkurt); delete []realeig_id; delete []compeig_id; delete []real_order; vdelete(&Xm1_im); mdelete(&M1_im); mdelete(&data_pow2_im); mdelete(&data_pow4_im); vdelete(&V1_im); vdelete(&V2_im); vdelete(&V4_im); vdelete(&kurt_im); vdelete(&kurt0_im); return 1; }
/******************************************************************* Subroutine to perform dimension pre-screening using signal-to-noise ratio (SNR) matrix *cov: the pointer to the covariance matrix matrix *inv_cov: the pointer to the inverse covariance matrix matrix *cov_mat: the pointer to the approximate covariance matrix when singular. If unsingular, it equals to cov double *det_cov: the pointer to determinant return value: '1' - successfully exit '0' - exit with waring/error *******************************************************************/ int veSNR(matrix *data, int *label, int dim_num, int *top_label, vector *snr_sorted) { int i, j, k, t, u; int num_class; int m, n; vector count; vector *data_mean; vector *variance; vector pro; vector snr; int *new_order; int row_T; double tmp; m = data->m; n = data->n; num_class = 0; for (j=0; j<m; j++) { if (num_class < label[j]) { num_class = label[j]; } } vnew(&count, num_class); vnew(&pro, num_class); vnew(&snr, n); data_mean = new vector[num_class]; for (i=0; i<num_class; i++) { vnew(data_mean+i, n); } variance = new vector[num_class]; for (i=0; i<num_class; i++) { vnew(variance+i, n); } new_order = new int[n]; for (i=0; i<num_class; i++) { // distingush each class row_T = 0; for (j=0; j<m; j++) { if (label[j] == i+1) { row_T ++; } } int *T; T = new int[row_T]; t = 0; for (j=0; j<m; j++) { if (label[j] == i+1) { T[t++] = j; } } pro.pr[i] = ((double) row_T) / ((double) m); // compute data_mean for each class matrix data_i; mnew(&data_i, row_T, n); for (t=0; t<row_T; t++) { u = t*n; for (k=0; k<n; k++) { data_i.pr[u+k] = data->pr[(T[t])*n+k]; } } mmean(&data_i, 'c', data_mean+i); mvar(&data_i, 'c', variance+i); delete []T; mdelete(&data_i); } //jj = []; for (i=0; i<num_class-1; i++) { for (j=i; j<num_class; j++) { for (k=0; k<n; k++) { tmp = ((variance+i)->pr[k] * pro.pr[i] + (variance+j)->pr[k] * pro.pr[j]) / (pro.pr[i] + pro.pr[j]); if (tmp < 1.0000e-3) { //jj = [jj k]; //printf(" Warning: \n "); } else { snr.pr[k] += pro.pr[i] * pro.pr[j] * pow(((data_mean+i)->pr[k] - (data_mean+j)->pr[k]), 2) / tmp; } } } } sort(&snr, new_order, 'd'); for (k=0; k<dim_num; k++) { top_label[k] = new_order[k]; } vcopy(&snr, snr_sorted); //vdelete(&count); vdelete(&pro); vdelete(&snr); for (i=0; i<num_class; i++) { vdelete(data_mean+i); } for (i=0; i<num_class; i++) { vdelete(variance+i); } delete []new_order; return 1; }