/* * File: EigenvectorPowerIterationTest.java * Authors: Kevin R. Dixon * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright October 18, 2007, Sandia Corporation. Under the terms of Contract * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by * or on behalf of the U.S. Government. Export of this program may require a * license from the United States Government. See CopyrightHistory.txt for * complete details. * * */ package gov.sandia.cognition.math.matrix.decomposition; import gov.sandia.cognition.math.matrix.Matrix; import gov.sandia.cognition.math.matrix.MatrixFactory; import gov.sandia.cognition.math.matrix.Vector; import gov.sandia.cognition.math.matrix.VectorFactory; import gov.sandia.cognition.math.matrix.mtj.DenseMatrixFactoryMTJ; import gov.sandia.cognition.math.matrix.mtj.decomposition.EigenDecompositionRightMTJ; import java.util.ArrayList; import java.util.Random; import junit.framework.TestCase; /** * * @author Kevin R. Dixon */ public class EigenvectorPowerIterationTest extends TestCase { /** * Random number generator */ protected Random random = new Random( 1 ); /** * * @param testName */ public EigenvectorPowerIterationTest( String testName ) { super( testName ); } /** * Test of estimateEigenvectors method, of class gov.sandia.cognition.math.matrix.EigenvectorPowerIteration. */ public void testEstimateEigenvectors() { System.out.println( "estimateEigenVectors" ); int M = 3; double r = 1; Matrix C = MatrixFactory.getDefault().createUniformRandom( M, M, -r, r, random ); Matrix A = C.times( C.transpose() ); double stoppingThreshold = 1e-5; int maxIterations = 100; int numComponents = M; ArrayList<Vector> eigenvectors = EigenvectorPowerIteration.estimateEigenvectors( A.clone(), numComponents, stoppingThreshold, maxIterations ); EigenDecomposition evd = EigenDecompositionRightMTJ.create( DenseMatrixFactoryMTJ.INSTANCE.copyMatrix( A ) ); System.out.println( "Actual:\n" + evd.getEigenVectorsRealPart() ); System.out.println( "Eigenvectors:\n" ); for (int i = 0; i < eigenvectors.size(); i++) { Vector actual = evd.getEigenVectorsRealPart().getColumn( i ); Vector estimate = eigenvectors.get( i ); double error = Math.min( actual.minus( estimate ).norm2(), actual.plus( estimate ).norm2() ); System.out.println( "Actual: " + actual ); System.out.println( "Estimate: " + estimate ); System.out.println( "Error: " + error ); assertEquals( 0.0, error, 1e-2 ); } } /** * Test of estimateEigenVector method, of class gov.sandia.cognition.math.matrix.EigenvectorPowerIteration. */ public void testEstimateEigenvector() { System.out.println( "estimateEigenVector" ); int M = 3; double r = 1; Matrix C = MatrixFactory.getDefault().createUniformRandom( M, M, -r, r, random ); Matrix A = C.times( C.transpose() ); Vector u = VectorFactory.getDefault().copyValues( 1.0, 0.0, 0.0 ); double stoppingThreshold = 1e-5; int maxIterations = 100; Vector result = EigenvectorPowerIteration.estimateEigenvector( u, A, stoppingThreshold, maxIterations ); System.out.println( "EigenVector: " + result ); } /** * Test of estimateEigenValue method, of class gov.sandia.cognition.math.matrix.EigenvectorPowerIteration. */ public void testEstimateEigenvalue() { System.out.println( "estimateEigenvalue" ); int M = 3; double r = 1; Matrix C = MatrixFactory.getDefault().createUniformRandom( M, M, -r, r, random ); Matrix A = C.times( C.transpose() ); Vector v = EigenvectorPowerIteration.estimateEigenvectors( A, 1, 1e-5, 100 ).get( 0 ); double result = EigenvectorPowerIteration.estimateEigenvalue( A, v ); EigenDecomposition evd = EigenDecompositionRightMTJ.create( DenseMatrixFactoryMTJ.INSTANCE.copyMatrix( A ) ); double lambda = evd.getEigenValue( 0 ).getMagnitude(); System.out.println( "Actual: " + lambda + " Estimate: " + result ); final double EPS = 1e-5; assertEquals( lambda, result, EPS ); } /** * Degenerate case testing */ public void testDegenerateCases() { System.out.println( "DegenerateCases" ); int M = 3; // Some of the degenerate cases for eigendecompositions are // Nonpositive definite matrices (negative and zero eigenvalues) Matrix B = MatrixFactory.getDefault().createMatrix( M, M ); B.setElement( 0, 0, -1.0 ); B.setElement( 1, 1, -2.0 ); EigenDecomposition evd = EigenDecompositionRightMTJ.create( DenseMatrixFactoryMTJ.INSTANCE.copyMatrix( B ) ); Matrix Bc = B.clone(); ArrayList<Vector> vs = EigenvectorPowerIteration.estimateEigenvectors( Bc, 2, 1e-5, 100 ); final double EPS = 1e-5; for (int i = 0; i < vs.size(); i++) { double lambdahat = EigenvectorPowerIteration.estimateEigenvalue( B, vs.get( i ) ); double lambda = evd.getEigenValue( i ).getRealPart(); System.out.println( i + ": Lambda: " + lambda + " Estimate: " + lambdahat ); assertEquals( lambda, lambdahat, EPS ); } // Also, repeated eigenvalues can be a problem for some formulations. Matrix B2 = MatrixFactory.getDefault().createMatrix( M, M ); B2.setElement( 0, 0, 3.0 ); B2.setElement( 1, 1, 3.0 ); EigenDecomposition evd2 = EigenDecompositionRightMTJ.create( DenseMatrixFactoryMTJ.INSTANCE.copyMatrix( B2 ) ); Matrix Bc2 = B2.clone(); ArrayList<Vector> vs2 = EigenvectorPowerIteration.estimateEigenvectors( Bc2, 2, 1e-5, 100 ); for (int i = 0; i < vs2.size(); i++) { double lambdahat = EigenvectorPowerIteration.estimateEigenvalue( B2, vs2.get( i ) ); double lambda = evd2.getEigenValue( i ).getRealPart(); System.out.println( i + ": Lambda: " + lambda + " Estimate: " + lambdahat ); assertEquals( lambda, lambdahat, EPS ); } } }