/* * File: MatrixFactoryTestHarness.java * Authors: Kevin R. Dixon * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright Jun 25, 2009, 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; import gov.sandia.cognition.math.UnivariateStatisticsUtil; import java.util.ArrayList; import junit.framework.TestCase; import java.util.Random; /** * Unit tests for MatrixFactoryTestHarness. * * @author krdixon */ public abstract class MatrixFactoryTestHarness extends TestCase { /** * Random number generator to use for a fixed random seed. */ public Random random = new Random( 1 ); /** * Default tolerance of the regression tests, {@value}. */ public double EPS = 1e-5; /** * Range to create random matrices, {@value}. */ protected static double RANGE = 10.0; /** * Tests for class MatrixFactoryTestHarness. * @param testName Name of the test. */ public MatrixFactoryTestHarness( String testName) { super(testName); } /** * Creates a new MatrixFactory * @return * MatrixFactory to test */ public abstract MatrixFactory<?> createFactory(); /** * Creates a random matrix from the factory * @return * random matrix */ public abstract Matrix createRandomMatrix(); /** * Tests the constructors of class MatrixFactoryTestHarness. */ public void testConstructors() { System.out.println( "Constructors" ); MatrixFactory<?> factory = this.createFactory(); assertNotNull( factory ); } /** * Test of getDefault method, of class MatrixFactory. */ public void testGetDefault() { System.out.println("getDefault"); MatrixFactory<? extends Matrix> result = MatrixFactory.getDefault(); assertSame( MatrixFactory.DEFAULT_DENSE_INSTANCE, result ); } /** * Test of getDenseDefault method, of class MatrixFactory. */ public void testGetDenseDefault() { System.out.println("getDenseDefault"); MatrixFactory<? extends Matrix> result = MatrixFactory.getDenseDefault(); assertSame( MatrixFactory.DEFAULT_DENSE_INSTANCE, result ); } /** * Test of getSparseDefault method, of class MatrixFactory. */ public void testGetSparseDefault() { System.out.println("getDefault"); MatrixFactory<? extends Matrix> result = MatrixFactory.getSparseDefault(); assertSame( MatrixFactory.DEFAULT_SPARSE_INSTANCE, result ); } /** * Test of getDiagonalDefault method, of class MatrixFactory. */ public void testGetDiagonalDefault() { System.out.println("getDiagonalDefault"); MatrixFactory<? extends DiagonalMatrix> result = MatrixFactory.getDiagonalDefault(); assertSame( MatrixFactory.DEFAULT_DIAGONAL_INSTANCE, result ); } /** * Test of copyMatrix method, of class MatrixFactory. */ public void testCopyMatrix() { System.out.println("copyMatrix"); MatrixFactory<?> instance = this.createFactory(); Matrix matrix = this.createRandomMatrix(); assertNotNull( matrix ); Matrix copy = instance.copyMatrix(matrix); assertNotNull( copy ); assertNotSame( matrix, copy ); assertEquals( matrix, copy ); matrix.scaleEquals(random.nextDouble()); assertFalse( matrix.equals(copy) ); } /** * Test of copyArray method, of class MatrixFactory. */ public void testCopyArray() { System.out.println("copyArray"); MatrixFactory<?> instance = this.createFactory(); Matrix matrix = this.createRandomMatrix(); int M = matrix.getNumRows(); int N = matrix.getNumColumns(); double[][] values = new double[ M ][ N ]; for( int i = 0; i < M; i++ ) { for( int j = 0; j < N; j++ ) { values[i][j] = matrix.getElement(i, j); } } Matrix copy = instance.copyArray(values); assertNotNull( copy ); assertNotSame( matrix, copy ); assertEquals( matrix, copy ); matrix.scaleEquals(random.nextDouble()); assertFalse( matrix.equals( copy ) ); Matrix m00 = instance.copyArray( new double[0][0] ); assertEquals( 0, m00.getNumRows() ); assertEquals( 0, m00.getNumColumns() ); } /** * Test of createMatrix method, of class MatrixFactory. */ public void testCreateMatrix() { System.out.println("createMatrix"); Matrix matrix = this.createRandomMatrix(); int M = matrix.getNumRows(); int N = matrix.getNumColumns(); MatrixFactory<?> factory = this.createFactory(); Matrix m2 = factory.createMatrix(M, N); assertNotNull( m2 ); assertNotSame( matrix, m2 ); assertEquals( M, m2.getNumRows() ); assertEquals( N, m2.getNumColumns() ); for( int i = 0; i < M; i++ ) { for( int j = 0; j < N; j++ ) { assertEquals( 0.0, m2.getElement(i, j) ); } } } public void testCreateMatrixWithInitialValue() { Matrix matrix = this.createRandomMatrix(); int M = matrix.getNumRows(); int N = matrix.getNumColumns(); MatrixFactory<?> factory = this.createFactory(); double initialValue = this.random.nextGaussian(); Matrix m3 = factory.createMatrix(M, N, initialValue); assertNotNull(m3); assertEquals(M, m3.getNumRows()); assertEquals(N, m3.getNumColumns()); boolean hasNonZero = false; for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { double value = m3.getElement(i, j); if (value != 0.0) { hasNonZero = true; assertEquals(initialValue, value, 0.0); } } } assertTrue(hasNonZero); } /** * Test of createIdentity method, of class MatrixFactory. */ public void testCreateIdentity() { System.out.println("createIdentity"); Matrix matrix = this.createRandomMatrix(); int M = matrix.getNumRows(); int N = matrix.getNumColumns(); MatrixFactory<?> instance = this.createFactory(); Matrix ident = instance.createIdentity(M, N); assertNotNull( ident ); assertNotSame( matrix, ident ); assertEquals( M, ident.getNumRows() ); assertEquals( N, ident.getNumColumns() ); Matrix isq = instance.createIdentity( N ); Matrix ir1 = instance.createIdentity( N, N ); assertEquals( isq, ir1 ); isq = instance.createIdentity(M); ir1 = instance.createIdentity(M,M); assertEquals( isq, ir1 ); for( int i = 0; i < M; i++ ) { for( int j = 0; j < N; j++ ) { if( i == j ) { assertEquals( 1.0, ident.getElement(i, j) ); } else { assertEquals( 0.0, ident.getElement(i, j) ); } } } } /** * Test of createUniformRandom method, of class MatrixFactory. */ public void testCreateUniformRandom() { System.out.println("createUniformRandom"); Matrix m = this.createRandomMatrix(); MatrixFactory<?> factory = this.createFactory(); int M = m.getNumRows(); int N = m.getNumColumns(); Matrix mr = factory.createUniformRandom(M, N, -RANGE, RANGE, random); assertNotNull( mr ); assertNotSame( m, mr ); assertEquals( M, mr.getNumRows() ); assertEquals( N, mr.getNumColumns() ); boolean nonzero = false; for( int i = 0; i < M; i++ ) { for( int j = 0; j < N; j++ ) { double value = mr.getElement(i, j); if( value != 0.0 ) { nonzero = true; if( (value < -RANGE) || (value > RANGE) ) { fail( "Nonzero value outside the given range!" ); } } } } if( !nonzero ) { fail( "I didn't find any nonzero values in your random matrix!!" ); } } /** * Test of createGaussianRandom method, of class MatrixFactory. */ public void testCreateGaussianRandom() { Matrix m = this.createRandomMatrix(); MatrixFactory<?> factory = this.createFactory(); int M = m.getNumRows(); int N = m.getNumColumns(); Matrix mr = factory.createGaussianRandom(M, N, random); assertNotNull(mr); assertNotSame(m, mr); assertEquals(M, mr.getNumRows()); assertEquals(N, mr.getNumColumns()); assertFalse(mr.equals(factory.createGaussianRandom(M, N, random))); M = 100 * M; N = 100 * N; mr = factory.createGaussianRandom(M, N, random); assertEquals(M, mr.getNumRows()); assertEquals(N, mr.getNumColumns()); double mean = UnivariateStatisticsUtil.computeMean(mr.convertToVector().valuesAsList()); double variance = UnivariateStatisticsUtil.computeVariance(mr.convertToVector().valuesAsList()); assertEquals(0.0, mean, 1e-2); assertEquals(1.0, variance, 1e-2); } /** * Test of copyRowVectors method, of class MatrixFactory. */ public void testCopyRowVectors_Collection() { System.out.println("copyRowVectors"); Matrix m = this.createRandomMatrix(); int M = m.getNumRows(); int N = m.getNumColumns(); ArrayList<Vector> rows = new ArrayList<Vector>( M ); for( int i = 0; i < M; i++ ) { rows.add( m.getRow(i) ); } MatrixFactory<?> factory = this.createFactory(); @SuppressWarnings("unchecked") Matrix mr = factory.copyRowVectors(rows); assertNotNull( mr ); assertNotSame( m, mr ); assertEquals( m, mr ); for( int i = 0; i < M; i++ ) { assertEquals( m.getRow(i), mr.getRow(i) ); } } /** * Test of copyRowVectors method, of class MatrixFactory. */ public void testCopyRowVectors_VectorizableArr() { System.out.println("copyRowVectors"); Matrix m = this.createRandomMatrix(); int M = m.getNumRows(); int N = m.getNumColumns(); Vector[] rows = new Vector[ M ]; for( int i = 0; i < M; i++ ) { rows[i] = m.getRow(i); } MatrixFactory<?> factory = this.createFactory(); @SuppressWarnings("unchecked") Matrix mr = factory.copyRowVectors(rows); assertNotNull( mr ); assertNotSame( m, mr ); assertEquals( m, mr ); for( int i = 0; i < M; i++ ) { assertEquals( m.getRow(i), mr.getRow(i) ); } } /** * Test of copyColumnVectors method, of class MatrixFactory. */ public void testCopyColumnVectors_Collection() { System.out.println("copyColumnVectors"); Matrix m = this.createRandomMatrix(); int M = m.getNumRows(); int N = m.getNumColumns(); ArrayList<Vector> cols = new ArrayList<Vector>( M ); for( int j = 0; j < N; j++ ) { cols.add( m.getColumn(j) ); } MatrixFactory<?> factory = this.createFactory(); @SuppressWarnings("unchecked") Matrix mr = factory.copyColumnVectors(cols); assertNotNull( mr ); assertNotSame( m, mr ); assertEquals( m, mr ); for( int j = 0; j < N; j++ ) { assertEquals( m.getColumn(j), mr.getColumn(j) ); } } /** * Test of copyColumnVectors method, of class MatrixFactory. */ public void testCopyColumnVectors_VectorizableArr() { System.out.println("copyColumnVectors"); Matrix m = this.createRandomMatrix(); int M = m.getNumRows(); int N = m.getNumColumns(); Vector[] cols = new Vector[ N ]; for( int j = 0; j < N; j++ ) { cols[j] = m.getColumn(j); } MatrixFactory<?> factory = this.createFactory(); @SuppressWarnings("unchecked") Matrix mr = factory.copyColumnVectors(cols); assertNotNull( mr ); assertNotSame( m, mr ); assertEquals( m, mr ); for( int j = 0; j < N; j++ ) { assertEquals( m.getColumn(j), mr.getColumn(j) ); } } /** * Test of createDiagonal method, of class MatrixFactory. */ public void testCreateDiagonal() { System.out.println("createDiagonal"); Vector diagonal = VectorFactory.getDefault().copyValues( random.nextGaussian(), random.nextGaussian(), random.nextGaussian() ); int M = diagonal.getDimensionality(); MatrixFactory<?> instance = this.createFactory(); Matrix diag = instance.createDiagonal(diagonal); assertNotNull( diag ); assertEquals( M, diag.getNumRows() ); assertEquals( M, diag.getNumColumns() ); for( int i = 0; i < M; i++ ) { for( int j = 0; j < M; j++ ) { if( i == j ) { assertEquals( diagonal.getElement(i), diag.getElement(i, j) ); } else { assertEquals( 0.0, diag.getElement(i, j) ); } } } } }