/*
* File: GradientDescendableApproximatorTest.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright November 12, 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.learning.algorithm.gradient;
import gov.sandia.cognition.learning.function.scalar.AtanFunction;
import gov.sandia.cognition.learning.function.vector.DifferentiableGeneralizedLinearModel;
import gov.sandia.cognition.learning.function.vector.ElementWiseDifferentiableVectorFunction;
import gov.sandia.cognition.learning.function.vector.MultivariateDiscriminant;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.math.matrix.Matrix;
import gov.sandia.cognition.math.matrix.MatrixFactory;
import gov.sandia.cognition.math.matrix.VectorizableVectorFunction;
import java.util.Random;
import junit.framework.TestCase;
/**
*
* @author Kevin R. Dixon
*/
public class GradientDescendableApproximatorTest extends TestCase
{
public GradientDescendableApproximatorTest(String testName)
{
super(testName);
}
int NUM_INPUTS = 3;
int NUM_OUTPUTS = 2;
double DELTA_SIZE = 1e-5;
/** The random number generator for the tests. */
private Random random = new Random();
public static class F1
extends MultivariateDiscriminant
{
public int evals = 0;
public F1(
int numInputs,
int numOutputs,
Random random)
{
super(MatrixFactory.getDefault().createUniformRandom(numOutputs, numInputs, -10.0, 10.0, random));
}
public F1(
F1 other)
{
super(other);
}
public F1 clone()
{
return new F1(this);
}
public Vector evaluate(
Vector input)
{
this.evals++;
return super.evaluate(input);
}
}
public static class F2
extends DifferentiableGeneralizedLinearModel
{
public int evals = 0;
public F2(
int numInputs,
int numOutputs,
Random random)
{
super(new MultivariateDiscriminant(
MatrixFactory.getDefault().createUniformRandom(numOutputs, numInputs, -10.0, 10.0, random)),
new ElementWiseDifferentiableVectorFunction(new AtanFunction(1.0)));
// super( MatrixFactory.getDefault().createUniformRandom( numOutputs, numInputs, -10.0, 10.0 )
}
public F2(
F2 other)
{
super(other);
}
public F2 clone()
{
return new F2(this);
}
public Vector evaluate(
Vector input)
{
this.evals++;
return super.evaluate(input);
}
}
public GradientDescendableApproximator createInstance()
{
return new GradientDescendableApproximator(new F2(NUM_INPUTS, NUM_OUTPUTS, random), DELTA_SIZE);
}
public void testConstructors()
{
System.out.println( "Constructors" );
GradientDescendableApproximator instance = new GradientDescendableApproximator();
assertNull( instance.getFunction() );
}
/**
* Test of clone method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testClone()
{
System.out.println("clone");
GradientDescendableApproximator instance = this.createInstance();
GradientDescendableApproximator clone = instance.clone();
assertNotSame(instance, clone);
assertNotSame(instance.getFunction(), clone.getFunction());
assertEquals(instance.getFunction().convertToVector(), clone.getFunction().convertToVector());
}
/**
* Test of getFunction method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testGetFunction()
{
System.out.println("getFunction");
GradientDescendableApproximator instance = this.createInstance();
assertNotNull(instance);
}
/**
* Test of setFunction method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testSetFunction()
{
System.out.println("setFunction");
GradientDescendableApproximator instance = this.createInstance();
assertNotNull(instance);
VectorizableVectorFunction f = instance.getFunction();
instance.setFunction(null);
assertNull(instance.getFunction());
instance.setFunction(f);
assertSame(f, instance.getFunction());
}
/**
* Test of convertToVector method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testConvertToVector()
{
System.out.println("convertToVector");
GradientDescendableApproximator instance = this.createInstance();
assertEquals(instance.getFunction().convertToVector(), instance.convertToVector());
}
/**
* Test of convertFromVector method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testConvertFromVector()
{
System.out.println("convertFromVector");
GradientDescendableApproximator instance = this.createInstance();
GradientDescendableApproximator clone = instance.clone();
Vector p = instance.convertToVector();
p.scaleEquals(Math.random());
instance.convertFromVector(p);
assertEquals(p, instance.convertToVector());
Vector pc = clone.convertToVector();
assertFalse(pc.equals(instance.convertToVector()));
instance.convertFromVector(pc);
assertEquals(pc, instance.convertToVector());
}
/**
* Test of evaluate method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testEvaluate()
{
System.out.println("evaluate");
double r = 1.0;
Vector input = VectorFactory.getDefault().createUniformRandom(NUM_INPUTS, -r, r, random);
GradientDescendableApproximator instance = this.createInstance();
assertEquals(instance.getFunction().evaluate(input), instance.evaluate(input));
}
/**
* Test of computeParameterGradient method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testComputeParameterGradient()
{
System.out.println("computeParameterGradient");
double r = 1.0;
for (int i = 0; i < 10; i++)
{
Vector input = VectorFactory.getDefault().createUniformRandom(NUM_INPUTS, -r, r, random);
GradientDescendableApproximator instance = this.createInstance();
Matrix Jhat = instance.computeParameterGradient(input);
Matrix J = ((GradientDescendable) instance.getFunction()).computeParameterGradient(input);
double delta = J.minus(Jhat).normFrobenius();
System.out.println("Norm = " + delta);
// + ", Evals: " + ((F1) instance.getFunction()).evals + " J: " + J.getNumRows() * J.getNumColumns() );
if (delta > 1e-3)
{
System.out.println("Jacobian:\n" + J);
System.out.println("Jacobian estimate:\n" + Jhat);
}
assertEquals(0.0, delta, 1e-3);
}
}
/**
* Test of getDeltaSize method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testGetDeltaSize()
{
System.out.println("getDeltaSize");
GradientDescendableApproximator instance = this.createInstance();
double result = instance.getDeltaSize();
assertEquals(DELTA_SIZE, result);
}
/**
* Test of setDeltaSize method, of class gov.sandia.cognition.learning.algorithm.gradient.GradientDescendableApproximator.
*/
public void testSetDeltaSize()
{
System.out.println("setDeltaSize");
GradientDescendableApproximator instance = this.createInstance();
double result = instance.getDeltaSize();
assertEquals(DELTA_SIZE, result);
result *= Math.random();
instance.setDeltaSize(result);
assertEquals(result, instance.getDeltaSize());
}
}