/*
* File: DiagonalMatrixMTJTest.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Sep 19, 2008, 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.mtj;
import gov.sandia.cognition.math.ComplexNumber;
import gov.sandia.cognition.math.RingTestHarness;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.math.matrix.Matrix;
import gov.sandia.cognition.math.matrix.MatrixFactory;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* JUnit tests for class DiagonalMatrixMTJTest
* @author Kevin R. Dixon
*/
public class DiagonalMatrixMTJTest
extends RingTestHarness<Matrix>
{
/**
* Entry point for JUnit tests for class DiagonalMatrixMTJTest
* @param testName name of this test
*/
public DiagonalMatrixMTJTest(
String testName)
{
super(testName);
}
/**
* Test
* @return Test
*/
public static Test suite()
{
TestSuite suite = new TestSuite(DiagonalMatrixMTJTest.class);
return suite;
}
@Override
protected DiagonalMatrixMTJ createRandom()
{
int dim = RANDOM.nextInt( 10 ) + 2;
DiagonalMatrixMTJ matrix =
DiagonalMatrixFactoryMTJ.INSTANCE.createMatrix( dim );
double[] diagonal = matrix.getDiagonal();
for( int i = 0; i < dim; i++ )
{
diagonal[i] = RANDOM.nextDouble() * 2.0 * RANGE - RANGE;
}
return matrix;
}
@Override
public void testScaleEquals()
{
System.out.println( "scaleEquals" );
DiagonalMatrixMTJ matrix = this.createRandom();
DiagonalMatrixMTJ original = (DiagonalMatrixMTJ) matrix.clone();
assertNotSame( matrix, original );
assertEquals( matrix.getDimensionality(), original.getDimensionality() );
assertEquals( matrix, original );
double scale = RANDOM.nextDouble() * 2.0 * RANGE - RANGE;
matrix.scaleEquals( scale );
assertNotSame( matrix, original );
assertFalse( matrix.equals( original ) );
for( int i = 0; i < matrix.getDimensionality(); i++ )
{
assertEquals( matrix.getElement(i), original.getElement(i)*scale );
}
}
@Override
public void testPlusEquals()
{
System.out.println( "plusEquals" );
DiagonalMatrixMTJ original = this.createRandom();
DiagonalMatrixMTJ m1 = (DiagonalMatrixMTJ) original.clone();
int M = m1.getDimensionality();
DiagonalMatrixMTJ m2 = new DiagonalMatrixMTJ( M );
for( int i = 0; i < M; i++ )
{
m2.setElement( i, RANDOM.nextDouble() );
}
assertEquals( original, m1 );
DiagonalMatrixMTJ m2clone = (DiagonalMatrixMTJ) m2.clone();
assertNotSame( m2clone, m2 );
assertEquals( m2clone, m2 );
m1.plusEquals( m2 );
assertEquals( m2clone, m2 );
assertFalse( original.equals( m1 ) );
for( int i = 0; i < m1.getDimensionality(); i++ )
{
assertEquals( original.getElement(i) + m2clone.getElement(i), m1.getElement(i) );
}
DenseMatrix mbad = new DenseMatrix( M, M );
for( int i = 0; i < M; i++ )
{
for( int j = 0; j < M; j++ )
{
mbad.setElement( i, j, RANDOM.nextDouble() * 2.0 * RANGE - RANGE );
}
}
try
{
m1.plusEquals( mbad );
fail( "Can't add off-diagonal elements to a diagonal matrix" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
// This should be fine
mbad.plusEquals( m1 );
}
@Override
public void testDotTimesEquals()
{
DiagonalMatrixMTJ original = this.createRandom();
DiagonalMatrixMTJ m1 = (DiagonalMatrixMTJ) original.clone();
int M = m1.getDimensionality();
DiagonalMatrixMTJ m2 = new DiagonalMatrixMTJ( M );
for( int i = 0; i < M; i++ )
{
m2.setElement( i, RANDOM.nextDouble() );
}
assertEquals( original, m1 );
DiagonalMatrixMTJ m2clone = (DiagonalMatrixMTJ) m2.clone();
assertNotSame( m2clone, m2 );
assertEquals( m2clone, m2 );
m1.dotTimesEquals( m2 );
assertEquals( m2clone, m2 );
assertFalse( original.equals( m1 ) );
for( int i = 0; i < m1.getDimensionality(); i++ )
{
assertEquals( original.getElement(i) * m2clone.getElement(i), m1.getElement(i) );
}
DenseMatrix mbad = new DenseMatrix( M, M );
for( int i = 0; i < M; i++ )
{
for( int j = 0; j < M; j++ )
{
mbad.setElement( i, j, RANDOM.nextDouble() * 2.0 * RANGE - RANGE );
}
}
// This should be fine.
m1.dotTimesEquals( mbad );
}
/**
* Test of getDimensionality method, of class DiagonalMatrixMTJ.
*/
public void testGetDimensionality()
{
System.out.println( "getDimensionality" );
DiagonalMatrixMTJ instance = this.createRandom();
assertEquals( instance.getDimensionality(), instance.getDiagonal().length );
int M = 10;
instance = new DiagonalMatrixMTJ( M );
assertEquals( M, instance.getDimensionality() );
assertEquals( M, instance.getDiagonal().length );
assertEquals( instance.getDimensionality(), instance.getNumRows() );
assertEquals( instance.getDimensionality(), instance.getNumColumns() );
}
/**
* Test of getInternalMatrix method, of class DiagonalMatrixMTJ.
*/
public void testGetInternalMatrix()
{
System.out.println( "getInternalMatrix" );
DiagonalMatrixMTJ instance = this.createRandom();
assertNotNull( instance.getInternalMatrix() );
}
/**
* Test of setInternalMatrix method, of class DiagonalMatrixMTJ.
*/
public void testSetInternalMatrix()
{
System.out.println( "setInternalMatrix" );
DiagonalMatrixMTJ instance = this.createRandom();
instance.getInternalMatrix();
try
{
instance.setInternalMatrix( null );
fail( "Cannot set null internal matrix" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
DiagonalMatrixMTJ m2 = this.createRandom();
assertNotSame( m2.getInternalMatrix(), instance.getInternalMatrix() );
instance.setInternalMatrix( m2.getInternalMatrix() );
assertSame( instance.getInternalMatrix(), m2.getInternalMatrix() );
}
/**
* Test of times method, of class DiagonalMatrixMTJ.
*/
public void testTimes_AbstractMTJMatrix()
{
System.out.println( "times Matrix" );
double[] diag = { 2.0, -2.0, 3.0 };
DiagonalMatrixMTJ m = new DiagonalMatrixMTJ( diag );
Vector3 c0 = new Vector3( 1.0, 2.0, 3.0 );
Vector3 c1 = new Vector3( 4.0, 5.0, 6.0 );
Vector3 c2 = new Vector3( -7.0, -8.0, -9.0 );
Matrix m1 = MatrixFactory.getDefault().copyColumnVectors( c0, c1, c2 );
Vector3 ec0 = new Vector3( 2.0, -4.0, 9.0 );
Vector3 ec1 = new Vector3( 8.0, -10.0, 18.0 );
Vector3 ec2 = new Vector3( -14.0, 16.0, -27.0 );
Matrix e1 = MatrixFactory.getDefault().copyColumnVectors( ec0, ec1, ec2 );
Matrix r1 = m.times( m1 );
System.out.println( "E1:\n" + e1 );
System.out.println( "Result:\n" + r1 );
assertEquals( e1, r1 );
assertTrue( e1.equals( r1, TOLERANCE ) );
assertEquals( m1.transpose().times( m ).transpose(), r1 );
double[][] v2 = {{1.0, 2.0},{3.0, 4.0},{5.0, 6.0}};
Matrix m2 = MatrixFactory.getDefault().copyArray( v2 );
System.out.println( "M2:\n" + m2 );
double[][] ev2 = {{2.0,4.0},{-6.0,-8.0},{15.0,18.0}};
Matrix e2 = MatrixFactory.getDefault().copyArray( ev2 );
Matrix r2 = m.times( m2 );
assertEquals( e2, r2 );
assertEquals( m2.transpose().times( m ).transpose(), r2 );
try
{
m.times( m2.transpose() );
fail( "Dimensions do not match!" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* Test of times method, of class DiagonalMatrixMTJ.
*/
public void testTimes_AbstractMTJVector()
{
System.out.println( "times Vector" );
double[] diag = { 2.0, -2.0, 3.0 };
DiagonalMatrixMTJ m = new DiagonalMatrixMTJ( diag );
Vector v1 = VectorFactory.getDefault().copyArray(
new double[]{1.0,2.0,-3.0} );
Vector e1 = VectorFactory.getDefault().copyArray(
new double[]{2.0,-4.0,-9.0} );
Vector r1 = m.times( v1 );
assertEquals( e1, r1 );
assertEquals( r1, v1.times( m ) );
Vector v2 = VectorFactory.getDefault().copyArray(
new double[]{-3.0,-2.0,1.0} );
Vector e2 = VectorFactory.getDefault().copyArray(
new double[]{-6.0,4.0,3.0} );
Vector r2 = m.times( v2 );
assertEquals( e2, r2 );
assertEquals( r2, v2.times( m ) );
}
/**
* Test of isSquare method, of class DiagonalMatrixMTJ.
*/
public void testIsSquare()
{
System.out.println( "isSquare" );
DiagonalMatrixMTJ instance = this.createRandom();
assertTrue( instance.isSquare() );
}
/**
* Test of isSymmetric method, of class DiagonalMatrixMTJ.
*/
public void testIsSymmetric1()
{
System.out.println( "isSymmetric" );
DiagonalMatrixMTJ instance = this.createRandom();
assertTrue( instance.isSymmetric() );
}
/**
* Test of isSymmetric method, of class DiagonalMatrixMTJ.
*/
public void testIsSymmetric_double()
{
System.out.println( "isSymmetric(double)" );
double effectiveZero = RANDOM.nextDouble();
DiagonalMatrixMTJ instance = this.createRandom();
assertTrue( instance.isSymmetric( effectiveZero ) );
}
/**
* Test of logDeterminant method, of class DiagonalMatrixMTJ.
*/
public void testLogDeterminant()
{
System.out.println( "logDeterminant" );
double[] diagonal = { 1.0, 2.0, 3.0 };
DiagonalMatrixMTJ instance = new DiagonalMatrixMTJ( diagonal );
ComplexNumber logDet = instance.logDeterminant();
assertEquals( 1.791759, logDet.getRealPart(), TOLERANCE );
assertEquals( 0.0, logDet.getImaginaryPart() );
instance.scaleEquals( -2.0 );
logDet = instance.logDeterminant();
assertEquals( 3.871201, logDet.getRealPart(), TOLERANCE );
assertEquals( Math.PI, logDet.getImaginaryPart(), TOLERANCE );
}
/**
* Test of normFrobenius method, of class DiagonalMatrixMTJ.
*/
public void testNormFrobenius()
{
System.out.println( "normFrobenius" );
double[] diagonal = { 2.0, -3.0, 4.0 };
DiagonalMatrixMTJ instance = new DiagonalMatrixMTJ( diagonal );
assertEquals( 5.385165, instance.normFrobenius(), TOLERANCE );
}
/**
* Test of rank method, of class DiagonalMatrixMTJ.
*/
public void testRank()
{
System.out.println( "rank" );
double[] diagonal = { 0.0, -1.0, 2.0 };
DiagonalMatrixMTJ m = new DiagonalMatrixMTJ( diagonal );
assertEquals( 2, m.rank(0.0) );
assertEquals( 2, m.rank() );
assertEquals( 3, m.rank(diagonal[1]) );
assertEquals( 1, m.rank(Math.abs(diagonal[1]) ) );
assertEquals( 0, m.rank(Math.abs(diagonal[2]) ) );
}
/**
* Test of solve method, of class DiagonalMatrixMTJ.
*/
public void testSolve_AbstractMTJVector()
{
System.out.println( "solve" );
DiagonalMatrixMTJ A = this.createRandom();
int M = A.getDimensionality();
final double r = 10.0;
AbstractMTJVector x = (AbstractMTJVector) DenseVectorFactoryMTJ.INSTANCE.createUniformRandom( M, -r, r, RANDOM );
Vector b = A.times( x );
Vector xhat = A.solve( b );
if( !xhat.equals( x, TOLERANCE ) )
{
assertEquals( xhat, x );
}
}
/**
* Test of solve method, of class DiagonalMatrixMTJ.
*/
public void testSolve_gscmmMatrix()
{
System.out.println( "solve" );
DiagonalMatrixMTJ A = this.createRandom();
int M = A.getDimensionality();
int N = RANDOM.nextInt( M ) + 2;
final double r = 10.0;
Matrix X = MatrixFactory.getDefault().createUniformRandom( M, N, r, r, RANDOM);
Matrix B = A.times( X );
Matrix Xhat = A.solve( B );
if( !X.equals( Xhat, TOLERANCE ) )
{
assertEquals( X, Xhat );
}
}
/**
* Test of solve method, of class DiagonalMatrixMTJ.
*/
public void testSolve_Vector()
{
System.out.println( "solve" );
DiagonalMatrixMTJ A = this.createRandom();
int M = A.getDimensionality();
final double r = 10.0;
Vector x = VectorFactory.getDefault().createUniformRandom( M, -r, r, RANDOM );
Vector b = A.times( x );
Vector xhat = A.solve( b );
if( !xhat.equals( x, TOLERANCE ) )
{
assertEquals( xhat, x );
}
}
/**
* Test of getSubMatrix method, of class DiagonalMatrixMTJ.
*/
public void testGetSubMatrix()
{
System.out.println( "getSubMatrix" );
DiagonalMatrixMTJ m = this.createRandom();
int minRow = 1;
int maxRow = 2;
int minColumn = 0;
int maxColumn = m.getDimensionality()-1;
SparseMatrix result = m.getSubMatrix( minRow, maxRow, minColumn, maxColumn );
for( int i = minRow; i <= maxRow; i++ )
{
for( int j = minColumn; j <= maxColumn; j++ )
{
assertEquals( m.getElement( i, j ), result.getElement( i-minRow, j-minColumn ) );
}
}
}
/**
* Test of transpose method, of class DiagonalMatrixMTJ.
*/
public void testTranspose()
{
System.out.println( "transpose" );
DiagonalMatrixMTJ m = this.createRandom();
DiagonalMatrixMTJ t = m.transpose();
assertSame( m, t );
assertEquals( m, t );
}
/**
* Test of getDiagonal method, of class DiagonalMatrixMTJ.
*/
public void testGetDiagonal()
{
System.out.println( "getDiagonal" );
double[] diagonal = { 1.0, -2.0, 3.0 };
DiagonalMatrixMTJ instance = new DiagonalMatrixMTJ( diagonal );
double[] result = instance.getDiagonal();
assertEquals( diagonal.length, instance.getDimensionality() );
assertEquals( diagonal.length, instance.getNumRows() );
assertEquals( diagonal.length, instance.getNumColumns() );
assertEquals( diagonal.length, result.length );
for( int i = 0; i < diagonal.length; i++ )
{
assertEquals( diagonal[i], result[i] );
}
}
/**
* Test of pseudoInverse method, of class DiagonalMatrixMTJ.
*/
public void testPseudoInverse()
{
System.out.println( "pseudoInverse" );
double effectiveZero = 0.0;
double[] diagonal = { 1.0, -2.0, 0.0, 3.0 };
DiagonalMatrixMTJ m1 = new DiagonalMatrixMTJ( diagonal );
double[] ed1 = { 1.0, -0.5, 0.0, 1.0/3.0 };
DiagonalMatrixMTJ e1 = new DiagonalMatrixMTJ( ed1 );
assertEquals( e1, m1.pseudoInverse( effectiveZero ) );
double[] ed2 = { 0.0, -0.5, 0.0, 1.0/3.0 };
DiagonalMatrixMTJ e2 = new DiagonalMatrixMTJ( ed2 );
assertEquals( e2, m1.pseudoInverse( 1.0 ) );
}
/**
* Test of getColumn method, of class DiagonalMatrixMTJ.
*/
public void testGetColumn()
{
System.out.println( "getColumn" );
DiagonalMatrixMTJ m = this.createRandom();
for( int i = 0; i < m.getDimensionality(); i++ )
{
Vector vi = m.getColumn( i );
for( int j = 0; j < vi.getDimensionality(); j++ )
{
if( i == j )
{
assertEquals( m.getElement( i ), vi.getElement( j ) );
}
else
{
assertEquals( 0.0, vi.getElement( j ) );
}
}
}
}
/**
* Test of getRow method, of class DiagonalMatrixMTJ.
*/
public void testGetRow()
{
System.out.println( "getRow" );
DiagonalMatrixMTJ m = this.createRandom();
for( int i = 0; i < m.getDimensionality(); i++ )
{
Vector vi = m.getRow( i );
for( int j = 0; j < vi.getDimensionality(); j++ )
{
if( i == j )
{
assertEquals( m.getElement( i ), vi.getElement( j ) );
}
else
{
assertEquals( 0.0, vi.getElement( j ) );
}
}
}
}
/**
* Test of getElement method, of class DiagonalMatrixMTJ.
*/
public void testGetElement_int_int()
{
System.out.println( "getElement" );
double[] diagonal = { 1.0, -2.0, 3.0 };
DiagonalMatrixMTJ m = new DiagonalMatrixMTJ( diagonal );
for( int i = 0; i < m.getNumRows(); i++ )
{
for( int j = 0; j < m.getNumColumns(); j++ )
{
if( i != j )
{
assertEquals( 0.0, m.getElement( i, j ) );
}
else
{
assertEquals( diagonal[i], m.getElement( i, j ) );
}
}
}
}
/**
* Test of setElement method, of class DiagonalMatrixMTJ.
*/
public void testSetElement_3args()
{
System.out.println( "setElement" );
DiagonalMatrixMTJ m = this.createRandom();
for( int i = 0; i < m.getNumRows(); i++ )
{
for( int j = 0; j < m.getNumColumns(); j++ )
{
if( i != j )
{
try
{
m.setElement( i, j, RANDOM.nextDouble() );
fail( "Cannot set off-diagonal elements" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
else
{
double v = RANDOM.nextDouble();
m.setElement( i, j, v );
assertEquals( v, m.getElement( i, j ) );
}
}
}
}
/**
* Test of getElement method, of class DiagonalMatrixMTJ.
*/
public void testGetElement_int()
{
System.out.println( "getElement" );
double[] diagonal = { 1.0, 2.0, 3.0, 4.0 };
DiagonalMatrixMTJ instance = new DiagonalMatrixMTJ( diagonal );
for( int i = 0; i < instance.getDimensionality(); i++ )
{
assertEquals( diagonal[i], instance.getElement( i ) );
assertEquals( instance.getElement( i, i ), instance.getElement( i ) );
}
try
{
instance.getElement( -1 );
fail( "Cannot index < 0" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
try
{
instance.getElement( instance.getDimensionality() );
fail( "Cannot index >= dimensionality" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* Test of setElement method, of class DiagonalMatrixMTJ.
*/
public void testSetElement_int_double()
{
System.out.println( "setElement" );
DiagonalMatrixMTJ m = this.createRandom();
for( int i = 0; i < m.getDimensionality(); i++ )
{
double v = RANDOM.nextDouble();
m.setElement( i, v );
assertEquals( m.getElement( i ), v );
}
try
{
m.setElement( -1, 0.0 );
fail( "Cannot set < 0" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
try
{
m.setElement( m.getDimensionality(), 0.0 );
fail( "Cannot set >= dimensionality" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
}
/**
* Test of convertToVector method, of class DiagonalMatrixMTJ.
*/
public void testConvertToVector()
{
System.out.println( "convertToVector" );
double[] diagonal = { 1.0, 2.0, 3.0 };
DiagonalMatrixMTJ m = new DiagonalMatrixMTJ( diagonal );
Vector e = VectorFactory.getDefault().copyArray( diagonal );
Vector r = m.convertToVector();
assertEquals( e.getDimensionality(), r.getDimensionality() );
assertEquals( e, r );
}
/**
* Test of convertFromVector method, of class DiagonalMatrixMTJ.
*/
public void testConvertFromVector()
{
System.out.println( "convertFromVector" );
double[] v = { 1.0, 2.0, 3.0 };
Vector parameters = VectorFactory.getDefault().copyArray( v );
DiagonalMatrixMTJ instance = new DiagonalMatrixMTJ( v.length );
assertFalse( parameters.equals( instance.convertToVector() ) );
instance.convertFromVector( parameters );
Vector r = instance.convertToVector();
assertNotSame( parameters, r );
assertEquals( parameters, r );
for( int i = 0; i < v.length; i++ )
{
assertEquals( v[i], r.getElement( i ) );
}
}
/**
* Test of toString method, of class DiagonalMatrixMTJ.
*/
public void testToString()
{
System.out.println( "toString" );
DiagonalMatrixMTJ instance = this.createRandom();
String r = instance.toString();
assertNotNull( r );
System.out.println( "String:\n" + r );
}
}