/* eigen_verify Verify properties of the eigen vectors. The eigenbasis should be ortonormal: R'*R - I == 0 The basis should be decomposed such that: MR - RD == 0 returns true if tests fail. */ int eigen_verify(Matrix M, Matrix lambda, Matrix R) { Matrix RtR = transposeMultiplyMatrixL(R, R); Matrix identity = makeIdentityMatrix(R->col_dim); Matrix MR = multiplyMatrix(M, R); Matrix D = makeIdentityMatrix(lambda->row_dim); Matrix RD; Matrix test; int i, j; int failed = 0; const double tol = 1.0e-7; for (i = 0; i < lambda->row_dim; i++) { ME(D, i, i) = ME(lambda, i, 0); } RD = multiplyMatrix(R, D); freeMatrix(D); DEBUG(2, "Checking orthogonality of eigenvectors"); test = subtractMatrix(RtR, identity); freeMatrix(RtR); freeMatrix(identity); for (i = 0; i < test->row_dim; i++) { for (j = 0; j < test->col_dim; j++) { if (!EQUAL_ZERO(ME(test, i, j), tol)) { failed = 1; MESSAGE("Eigenvectors are not orthogonal to within tolerance."); DEBUG_DOUBLE(1, "Matrix Element", ME(test, i, j)); DEBUG_DOUBLE(1, "Tolerance", tol); exit(1); } } } freeMatrix(test); DEBUG(2, "Checking reconstruction property of eigensystem"); test = subtractMatrix(MR, RD); freeMatrix(MR); freeMatrix(RD); for (i = 0; i < test->row_dim; i++) { for (j = 0; j < test->col_dim; j++) { if (!EQUAL_ZERO(ME(test, i, j), tol)) { failed = 1; MESSAGE("Covariance matrix is not reconstructable to within tolerance."); DEBUG_DOUBLE(1, "Matrix Element", ME(test, i, j)); DEBUG_DOUBLE(1, "Tolerance", tol); exit(1); } } } freeMatrix(test); return failed; }
/** Verify properties of the eigen basis used for pca. The eigenbasis should be ortonormal: U'*U - I == 0 The basis should be decomposed such that: X == U*D*V' returns true if tests fail. */ int basis_verify(Matrix X, Matrix U) { Matrix UtX = transposeMultiplyMatrixL(U, X); Matrix UUtX = multiplyMatrix(U, UtX); Matrix UtU = transposeMultiplyMatrixL(U, U); Matrix identity = makeIdentityMatrix(U->col_dim); Matrix test; int i, j; int failed = 0; const double tol = 1.0e-7; freeMatrix(UtX); DEBUG(2, "Checking orthogonality of eigenbasis"); test = subtractMatrix(UtU, identity); freeMatrix(UtU); freeMatrix(identity); for (i = 0; i < test->row_dim; i++) { for (j = 0; j < test->col_dim; j++) { if (!EQUAL_ZERO(ME(test, i, j), tol)) { failed = 1; MESSAGE("Eigenbasis is not orthogonal to within tolerance."); DEBUG_DOUBLE(1, "Matrix Element", ME(test, i, j)); DEBUG_DOUBLE(1, "Tolerance", tol); exit(1); } } } freeMatrix(test); DEBUG(2, "Checking reconstruction property of the eigen decomposition"); test = subtractMatrix(X, UUtX); freeMatrix(UUtX); for (i = 0; i < test->row_dim; i++) { for (j = 0; j < test->col_dim; j++) { if (!EQUAL_ZERO(ME(test, i, j), tol)) { failed = 1; MESSAGE("Data matrix is not reconstructable to within tolerance."); DEBUG_DOUBLE(1, "Matrix Element", ME(test, i, j)); DEBUG_DOUBLE(1, "Tolarence", tol); exit(1); } } } freeMatrix(test); return failed; }
void fisherVerify(Matrix fisherBasis, Matrix fisherValues, Matrix Sw, Matrix Sb) { Matrix SbW = multiplyMatrix(Sb, fisherBasis); Matrix SwW = multiplyMatrix(Sw, fisherBasis); Matrix D = makeIdentityMatrix(fisherBasis->row_dim); Matrix DSwW; Matrix zeroMat; int i, j; MESSAGE("Verifying Fisher Basis."); for (i = 0; i < D->row_dim; i++) { ME(D, i, i) = ME(fisherValues, i, 0); } DSwW = multiplyMatrix(D, SwW); zeroMat = subtractMatrix(SbW, DSwW); for (i = 0; i < zeroMat->row_dim; i++) { for (j = 0; j < zeroMat->col_dim; j++) { if (!EQUAL_ZERO(ME(zeroMat, i, j), 0.000001)) { DEBUG( -1, "Fisher validation failed."); printf("Element: (%d,%d) value = %f", i, j, ME(zeroMat, i, j)); exit(1); } } } }
int keepConverging(int n, Matrix *actual, Matrix *previous) { if(n >= 2000) return 0; Matrix *diff = copyMatrixConfig(actual); subtractMatrix(diff, actual, previous); return norm(diff) > 10e-12; }
/* findBCSMatrix The approach here is to use equation 116 on p. 122 of Duda, "Pattern Classification" to solve for the between class scatter matrix. The equation reads: St = Sw + Sb (St is total scatter matrix) Solving for Sb, Sb = St - Sw. Note Sw is computed above. The total scatter matrix is easy to compute, it is what we think of as the covariance matrix when the points have been centered. */ Matrix findBCSMatrix(Matrix imspca, Matrix Sw) { Matrix Sb; Matrix St; Matrix mean; MESSAGE("Finding between-class scatter matrix."); mean = get_mean_image(imspca); mean_subtract_images(imspca, mean); DEBUG(3, "Producing total scatter matrix"); St = transposeMultiplyMatrixR(imspca, imspca); DEBUG(2, "Producing between-class scatter matrix"); Sb = subtractMatrix(St, Sw); freeMatrix(St); freeMatrix(mean); return Sb; }