/** * Preforms standard tests that can be performed on any decomposition without prior knowledge of * what the results should be. */ public void performStandardTests(SymmetricQRAlgorithmDecomposition alg, Matrix A, int numReal) { // basic sanity tests assertEquals(A.rowCount(), alg.getNumberOfEigenvalues()); if (numReal >= 0) { for (int i = 0; i < A.rowCount(); i++) { Vector2 v = alg.getEigenvalue(i); assertFalse(Double.isNaN(v.x)); if (v.y == 0) numReal--; else if (Math.abs(v.y) < 10 * EPS) numReal--; } // if there are more than the expected number of real eigenvalues this will // be negative assertEquals(0, numReal); } // checkCharacteristicEquation(alg,A); if (computeVectors) { testPairsConsistent(alg, A); testVectorsLinearlyIndependent(alg); } }
/** If the eigenvalues are all known, real, and the same this can be used to check them. */ public void testEigenvalues(SymmetricQRAlgorithmDecomposition alg, double expected) { for (int i = 0; i < alg.getNumberOfEigenvalues(); i++) { Vector2 c = alg.getEigenvalue(i); assertTrue(c.y == 0); assertEquals(expected, c.x, 1e-8); } }
public void testForEigenvalue( SymmetricQRAlgorithmDecomposition alg, Matrix A, double valueReal, double valueImg, int numMatched) { int N = alg.getNumberOfEigenvalues(); int numFound = 0; for (int i = 0; i < N; i++) { Vector2 c = alg.getEigenvalue(i); if (Math.abs(c.x - valueReal) < 1e-4 && Math.abs(c.y - valueImg) < 1e-4) { numFound++; } } assertEquals(numMatched, numFound); }
/** See if eigenvalues cause the characteristic equation to have a value of zero */ public void checkCharacteristicEquation(SymmetricQRAlgorithmDecomposition alg, Matrix A) { int N = alg.getNumberOfEigenvalues(); Matrix a = Matrix.create(A); for (int i = 0; i < N; i++) { Vector2 c = alg.getEigenvalue(i); if (Math.abs(c.y - 0) < 1e-8) { // test using the characteristic equation Matrix temp = Matrix.createIdentity(A.columnCount()); temp.scale(c.x); temp.sub(a); double det = temp.determinant(); // extremely crude test. given perfect data this is probably considered a failure... // However, // its hard to tell what a good test value actually is. assertEquals(0, det, 0.1); } } }
/** Sees if the pair of eigenvalue and eigenvector was found in the decomposition. */ public void testForEigenpair( SymmetricQRAlgorithmDecomposition alg, double valueReal, double valueImg, double... vector) { int N = alg.getNumberOfEigenvalues(); int numMatched = 0; for (int i = 0; i < N; i++) { Vector2 c = alg.getEigenvalue(i); if (Math.abs(c.x - valueReal) < 1e-4 && Math.abs(c.y - valueImg) < 1e-4) { // if( c.isReal() ) { if (Math.abs(c.y - 0) < 1e-8) if (vector.length > 0) { AVector v = alg.getEigenVector(i); AMatrix e = Matrix.createFromRows(vector); e = e.getTranspose(); Matrix t = Matrix.create(v.length(), 1); t.setColumn(0, v); double error = diffNormF(e, t); // CommonOps.changeSign(e); e.multiply(-1); double error2 = diffNormF(e, t); if (error < 1e-3 || error2 < 1e-3) numMatched++; } else { numMatched++; } else if (Math.abs(c.y - 0) > 1e-8) { numMatched++; } } } assertEquals(1, numMatched); }
/** * Checks to see if an eigenvalue is complex then the eigenvector is null. If it is real it then * checks to see if the equation A*v = lambda*v holds true. */ public void testPairsConsistent(SymmetricQRAlgorithmDecomposition alg, Matrix A) { // // System.out.println("-------------------------------------------------------------------------"); int N = alg.getNumberOfEigenvalues(); for (int i = 0; i < N; i++) { Vector2 c = alg.getEigenvalue(i); AVector v = alg.getEigenVector(i); if (Double.isInfinite(c.x) || Double.isNaN(c.x) || Double.isInfinite(c.y) || Double.isNaN(c.y)) fail("Uncountable eigenvalue"); if (Math.abs(c.y) > 1e-20) { assertTrue(v == null); } else { assertTrue(v != null); // if( MatrixFeatures.hasUncountable(v)) { // throw new RuntimeException("Egads"); // } assertFalse(v.hasUncountable()); // CommonOps.mult(A,v,tempA); Matrix ta = Matrix.create(A.rowCount(), 1); ta.setColumn(0, (v)); AMatrix tempA = Multiplications.multiply(A, ta); // CommonOps.scale(c.real,v,tempB); Matrix tb = Matrix.create(v.length(), 1); tb.setColumn(0, v); AMatrix tempB = tb.multiplyCopy(c.x); // double max = NormOps.normPInf(A); double max = normPInf(A); if (max == 0) max = 1; double error = diffNormF(tempA, tempB) / max; if (error > 1e-12) { // System.out.println("Original matrix:"); // System.out.println(A); // A.print(); // System.out.println("Eigenvalue = "+c.x); // Eigenpair p = EigenOps.computeEigenVector(A,c.real); // p.vector.print(); // v.print(); // // // CommonOps.mult(A,p.vector,tempA); // CommonOps.scale(c.real,p.vector,tempB); // // max = NormOps.normPInf(A); // // System.out.println("error before = "+error); // error = SpecializedOps.diffNormF(tempA,tempB)/max; // System.out.println("error after = "+error); // A.print("%f"); // System.out.println(); fail("Error was too large"); } assertTrue(error <= 1e-12); } } }