/*
* File: AbstractVectorSpace.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Jun 23, 2011, 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.collection.ScalarMap;
import gov.sandia.cognition.math.RingTestHarness;
import static junit.framework.TestCase.assertEquals;
/**
* Tests for class VectorSpaceTestHarness.
* @param <VectorType>
* Type of Vector
* @author krdixon
*/
public abstract class VectorSpaceTestHarness<VectorType extends VectorSpace<VectorType,?>>
extends RingTestHarness<VectorType>
{
/**
* Num samples.
*/
public static int NUM_SAMPLES = 10;
/**
* Creates a new instance of VectorTestHarness
* @param testName Name of the test
*/
public VectorSpaceTestHarness(
String testName)
{
super(testName);
}
/**
* Creates a vector with the given dimension
* @param numDim
* Number of dimensions
* @return
* Vector with the specified dimensions
*/
abstract protected VectorType createVector(
int numDim);
/**
* Copies the Vector to the local class
* @param vector
* Vector to copy
* @return
* Copy of the Vector
*/
abstract protected VectorType createCopy(
Vector vector);
/**
* Creates a new RANDOM Vector with a given dimension and range
* @param numDim dimension of the vector
* @param minRange minimum value for the entries
* @param maxRange maximum value for the entries
* @return Vector of dimension "numDim" and uniformly distributed elements
*/
protected VectorType createRandom(
int numDim,
double minRange,
double maxRange)
{
return this.createCopy(VectorFactory.getDefault().createUniformRandom(
numDim, minRange, maxRange, RANDOM));
}
/**
* Max dimensions
*/
protected static int DEFAULT_MAX_DIMENSION = 10;
@Override
protected VectorType createRandom()
{
int M = RANDOM.nextInt( DEFAULT_MAX_DIMENSION ) + 1;
return this.createRandom(M, -RANGE, RANGE);
}
/**
* Tests the constructors of class VectorSpaceTestHarness.
*/
public void testConstructors()
{
}
/**
* Test of sum method, of class VectorSpace.
*/
public void testSum()
{
System.out.println("sum");
VectorType instance = this.createRandom();
double sum = 0.0;
for( VectorSpace.Entry entry : instance )
{
sum += entry.getValue();
}
assertEquals( sum, instance.sum(), TOLERANCE );
instance.scaleEquals(-2.0);
assertEquals(-2.0 * sum, instance.sum(), TOLERANCE);
}
/**
* Test of norm1 method, of class VectorSpace.
*/
public void testNorm1()
{
System.out.println("norm1");
VectorType instance = this.createRandom();
assertEquals( instance.norm(1.0), instance.norm1(), TOLERANCE );
}
/**
* Test of norm2 method, of class VectorSpace.
*/
public void testNorm2()
{
System.out.println("norm2");
VectorType instance = this.createRandom();
assertEquals( instance.norm(2.0), instance.norm2(), TOLERANCE);
}
/**
* Test of norm2Squared method, of class VectorSpace.
*/
public void testNorm2Squared()
{
System.out.println("norm2Squared");
VectorType instance = this.createRandom();
assertEquals( instance.norm2()*instance.norm2(), instance.norm2Squared(), TOLERANCE );
}
/**
* Test of normInfinity method, of class VectorSpace.
*/
public void testNormInfinity()
{
System.out.println("normInfinity");
VectorType instance = this.createRandom();
double max = 0.0;
for( VectorSpace.Entry entry : instance )
{
final double value = Math.abs(entry.getValue());
if( max < value )
{
max = value;
}
}
assertEquals( max, instance.normInfinity() );
// Infinity norm shouldn't be effected by scaling by -1.0
instance.scaleEquals(-1.0);
assertEquals( max, instance.normInfinity() );
}
/**
* Test of norm method, of class VectorSpace.
*/
public void testNorm()
{
System.out.println("norm");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
double power = RANDOM.nextDouble() * 100.0;
VectorType instance = this.createRandom();
double sump = 0.0;
for( VectorSpace.Entry entry : instance )
{
final double value = Math.abs(entry.getValue());
sump += Math.pow( value, power );
}
final double normp = Math.pow( sump, 1.0/power );
assertEquals( normp, instance.norm(power), TOLERANCE );
assertEquals( instance.normInfinity(), instance.norm(Double.POSITIVE_INFINITY), TOLERANCE );
}
try
{
VectorType instance = this.createRandom();
instance.norm(0.0);
fail( "power must be > 0.0" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
try
{
VectorType instance = this.createRandom();
instance.norm(-1.0);
fail( "power must be > 0.0" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
try
{
VectorType instance = this.createRandom();
instance.norm(Double.NEGATIVE_INFINITY);
fail( "power must be > 0.0" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
try
{
VectorType instance = this.createRandom();
instance.norm(Double.NaN);
fail( "power can't be NaN" );
}
catch (Exception e)
{
System.out.println( "Good: " + e );
}
VectorType instance = this.createRandom();
instance.zero();
assertEquals( 0.0, instance.norm(RANDOM.nextDouble()*100.0), TOLERANCE );
instance = this.createVector(0);
assertEquals( 0.0, instance.norm( 1.0 ), TOLERANCE );
}
/**
* Test of dot method, of class VectorSpace.
*/
public void testDot()
{
System.out.println("dot");
VectorType a = this.createCopy(VectorFactory.getDefault().copyValues(1.0, 2.0, 3.0));
VectorType b = this.createCopy(VectorFactory.getDefault().copyValues(2.0, 1.0, 3.0));
assertEquals(13.0, a.dot(b), TOLERANCE);
assertEquals(a.dot(b), b.dot(a), TOLERANCE);
assertEquals(a.dotProduct(b), a.dot(b), TOLERANCE);
}
/**
* Test of dotProduct method, of class VectorSpace.
*/
public void testDotProduct()
{
System.out.println("dotProduct");
VectorType a = this.createCopy(VectorFactory.getDefault().copyValues(1.0, 2.0, 3.0));
VectorType b = this.createCopy(VectorFactory.getDefault().copyValues(2.0, 1.0, 3.0));
assertEquals( 13.0, a.dotProduct(b), TOLERANCE );
assertEquals( a.dotProduct(b), b.dotProduct(a), TOLERANCE );
}
/**
* Test of angle method, of class VectorSpace.
*/
public void testAngle()
{
System.out.println("angle");
VectorType a = this.createCopy(VectorFactory.getDefault().copyValues(1.0, 2.0, 3.0));
VectorType b = this.createCopy(VectorFactory.getDefault().copyValues(2.0, 1.0, 3.0));
assertEquals( 0.380251206692933, a.angle(b), TOLERANCE );
assertEquals( a.angle(b), b.angle(a), TOLERANCE );
}
/**
* Test of cosine method, of class VectorSpace.
*/
public void testCosine()
{
System.out.println("cosine");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
VectorType a = this.createRandom( 10, -RANGE, RANGE );
VectorType b = this.createRandom( 10, -RANGE, RANGE );
double dot = a.dotProduct(b);
double na = a.norm2Squared();
double nb = b.norm2Squared();
double cosine = dot/Math.sqrt(na*nb);
assertEquals( cosine, a.cosine(b) );
assertEquals( cosine, b.cosine(a) );
}
VectorType a = this.createRandom();
VectorType b = a.clone();
assertEquals( 1.0, a.cosine(b), TOLERANCE );
assertEquals( 1.0, b.cosine(a), TOLERANCE );
b.zero();
assertEquals( 0.0, a.cosine(b), TOLERANCE );
assertEquals( 0.0, b.cosine(a), TOLERANCE );
}
/**
* Test of euclideanDistance method, of class VectorSpace.
*/
public void testEuclideanDistance()
{
System.out.println("euclideanDistance");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
VectorType a = this.createRandom( 10, -RANGE, RANGE );
VectorType b = this.createRandom( 10, -RANGE, RANGE );
assertEquals( a.minus(b).norm2(), a.euclideanDistance(b) );
assertEquals( a.minus(b).norm2(), b.euclideanDistance(a) );
assertEquals( 0.0, a.euclideanDistance(a) );
assertEquals( 0.0, b.euclideanDistance(b) );
}
}
/**
* Test of euclideanDistanceSquared method, of class VectorSpace.
*/
public void testEuclideanDistanceSquared()
{
System.out.println("euclideanDistanceSquared");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
VectorType a = this.createRandom( 10, -RANGE, RANGE );
VectorType b = this.createRandom( 10, -RANGE, RANGE );
assertEquals( a.minus(b).norm2Squared(), a.euclideanDistanceSquared(b), TOLERANCE );
assertEquals( a.minus(b).norm2Squared(), b.euclideanDistanceSquared(a), TOLERANCE );
assertEquals( 0.0, a.euclideanDistanceSquared(a) );
assertEquals( 0.0, b.euclideanDistanceSquared(b) );
}
}
/**
* Test of unitVector method, of class VectorSpace.
*/
public void testUnitVector()
{
System.out.println("unitVector");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
VectorType instance = this.createRandom();
VectorType unit = instance.unitVector();
assertTrue( instance.scale( 1.0 / instance.norm2() ).equals( unit, TOLERANCE ) );
}
}
/**
* Test of unitVectorEquals method, of class VectorSpace.
*/
public void testUnitVectorEquals()
{
System.out.println("unitVectorEquals");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
VectorType instance = this.createRandom();
VectorType clone = instance.clone();
assertEquals( instance, clone );
instance.unitVectorEquals();
assertFalse( instance.equals(clone) );
VectorType unit = clone.unitVector();
assertEquals( unit, instance );
assertEquals( 1.0, instance.norm2(), TOLERANCE );
}
VectorType instance = this.createRandom();
instance.zero();
instance.unitVectorEquals();
assertEquals( 0.0, instance.norm2() );
}
/**
* Test of isUnitVector method, of class VectorSpace.
*/
public void testIsUnitVector()
{
System.out.println("isUnitVector");
for( int n = 0; n < NUM_SAMPLES; n++ )
{
VectorType instance = this.createRandom();
assertFalse( instance.isUnitVector() );
instance.unitVectorEquals();
assertTrue( instance.isUnitVector(TOLERANCE) );
instance.zero();
assertFalse( instance.isUnitVector() );
}
}
/**
* Test of getMinValue method, of class VectorSpace.
*/
public void testGetMinValue()
{
System.out.println("getMin");
VectorType instance = this.createRandom();
double min = Double.POSITIVE_INFINITY;
for (VectorSpace.Entry entry : instance)
{
double value = entry.getValue();
if (min > value)
{
min = value;
}
}
assertEquals(min, instance.getMinValue(), 0.0);
}
/**
* Test of getMaxValue method, of class VectorSpace.
*/
public void testGetMaxValue()
{
System.out.println("getMax");
VectorType instance = this.createRandom();
double max = Double.NEGATIVE_INFINITY;
for (VectorSpace.Entry entry : instance)
{
double value = entry.getValue();
if (max < value)
{
max = value;
}
}
assertEquals(max, instance.getMaxValue(), 0.0);
}
}