/*
* File: MultivariateMonteCarloIntegratorTest.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Feb 12, 2010, 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.statistics.montecarlo;
import gov.sandia.cognition.learning.function.vector.LinearVectorFunction;
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.statistics.distribution.ChiSquareDistribution;
import gov.sandia.cognition.statistics.distribution.MultivariateGaussian;
import gov.sandia.cognition.util.DefaultWeightedValue;
import java.util.ArrayList;
import junit.framework.TestCase;
import java.util.Random;
/**
* Unit tests for MultivariateMonteCarloIntegratorTest.
*
* @author krdixon
*/
public class MultivariateMonteCarloIntegratorTest
extends TestCase
{
/**
* Random number generator to use for a fixed random seed.
*/
public final Random RANDOM = new Random( 1 );
/**
* Default tolerance of the regression tests, {@value}.
*/
public final double TOLERANCE = 1e-5;
/**
* Samples
*/
public int NUM_SAMPLES = 1000;
/**
* Dimension
*/
public int DIM = 3;
/**
* range
*/
public double RANGE = 3.0;
/**
* Tests for class MultivariateMonteCarloIntegratorTest.
* @param testName Name of the test.
*/
public MultivariateMonteCarloIntegratorTest(
String testName)
{
super(testName);
}
/**
* Tests the constructors of class MultivariateMonteCarloIntegratorTest.
*/
public void testConstructors()
{
System.out.println( "Constructors" );
assertNotNull( MultivariateMonteCarloIntegrator.INSTANCE );
assertNotNull( new MultivariateMonteCarloIntegrator() );
}
/**
* Clone
*/
public void testClone()
{
System.out.println( "clone" );
MultivariateMonteCarloIntegrator instance =
new MultivariateMonteCarloIntegrator();
MultivariateMonteCarloIntegrator clone =
(MultivariateMonteCarloIntegrator) instance.clone();
assertNotSame( instance, clone );
assertNotNull( clone );
}
/**
* Test of integrate method, of class MultivariateMonteCarloIntegrator.
*/
public void testIntegrate_Collection_Evaluator()
{
System.out.println("integrate");
Vector mean = VectorFactory.getDefault().createUniformRandom(
DIM, -RANGE, RANGE, RANDOM );
Matrix variance = MatrixFactory.getDefault().createIdentity(DIM, DIM).scale( RANDOM.nextDouble() * RANGE + 2.0 );
MultivariateGaussian.PDF targetDistribution =
new MultivariateGaussian.PDF( mean, variance );
MultivariateMonteCarloIntegrator instance =
new MultivariateMonteCarloIntegrator();
int num = 100;
ArrayList<Vector> means = new ArrayList<Vector>( num );
ArrayList<Vector> variances = new ArrayList<Vector>( num );
LinearVectorFunction linear = new LinearVectorFunction(1.0);
for( int n = 0; n < num; n++ )
{
ArrayList<Vector> samples =
targetDistribution.sample(RANDOM, NUM_SAMPLES);
MultivariateGaussian.PDF g =
instance.integrate(samples, linear);
means.add( g.getMean() );
variances.add( g.getCovariance().convertToVector() );
}
MultivariateGaussian sampleMeanDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(means, 0.0);
MultivariateGaussian sampleVarianceDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(variances, 0.0);
Vector meanTarget = targetDistribution.getMean();
double zsquared = sampleMeanDistribution.computeZSquared( meanTarget );
double p = 1.0-ChiSquareDistribution.CDF.evaluate( zsquared, DIM );
System.out.println( "====== Mean ========" );
System.out.println( "Target = " + targetDistribution.getMean() );
System.out.println( "Sample = " + sampleMeanDistribution.getMean() );
System.out.println( "Z-squared= " + zsquared );
System.out.println( "P-value = " + p );
assertEquals( 1.0, p, 0.95 );
Vector varianceTarget = targetDistribution.getCovariance().convertToVector();
zsquared = sampleVarianceDistribution.computeZSquared(
varianceTarget );
p = 1.0-ChiSquareDistribution.CDF.evaluate( zsquared, DIM*DIM );
System.out.println( "====== Variance =======" );
System.out.println( "Target = " + varianceTarget );
System.out.println( "Sample = " + sampleVarianceDistribution.getMean() );
System.out.println( "Z-squared= " + zsquared );
System.out.println( "P-value = " + p );
assertEquals( 1.0, p, 0.95 );
}
/**
* Test of integrate method, of class MultivariateMonteCarloIntegrator.
*/
public void testIntegrate_List_Evaluator()
{
System.out.println("integrate");
Vector mean = VectorFactory.getDefault().createUniformRandom(
DIM, -RANGE, RANGE, RANDOM );
Matrix variance = MatrixFactory.getDefault().createIdentity(DIM, DIM).scale( RANDOM.nextDouble() * RANGE + 2.0 );
MultivariateGaussian.PDF targetDistribution =
new MultivariateGaussian.PDF( mean, variance );
MultivariateMonteCarloIntegrator instance =
new MultivariateMonteCarloIntegrator();
MultivariateGaussian.PDF importanceDistribution =
new MultivariateGaussian.PDF( mean.scale(2.0), variance.scale(2.0) );
ImportanceSampler<Vector> sampler =
new ImportanceSampler<Vector>( importanceDistribution );
System.out.println( "Target = " + targetDistribution.getMean() );
System.out.println( "Importance = " + importanceDistribution.getMean() );
int num = 100;
ArrayList<Vector> means = new ArrayList<Vector>( num );
ArrayList<Vector> variances = new ArrayList<Vector>( num );
LinearVectorFunction linear = new LinearVectorFunction(1.0);
for( int n = 0; n < num; n++ )
{
MultivariateGaussian.PDF g =
instance.integrate( sampler.sample(targetDistribution, RANDOM, NUM_SAMPLES ), linear );
means.add( g.getMean() );
variances.add( g.getCovariance().convertToVector() );
}
MultivariateGaussian sampleMeanDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(means, 0.0);
MultivariateGaussian sampleVarianceDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(variances, 0.0);
Vector meanTarget = targetDistribution.getMean();
double zsquared = sampleMeanDistribution.computeZSquared( meanTarget );
double p = 1.0-ChiSquareDistribution.CDF.evaluate( zsquared, DIM );
System.out.println( "====== Mean ========" );
System.out.println( "Target = " + targetDistribution.getMean() );
System.out.println( "Sample = " + sampleMeanDistribution.getMean() );
System.out.println( "Z-squared= " + zsquared );
System.out.println( "P-value = " + p );
assertEquals( 1.0, p, 0.95 );
}
/**
* Test of getMean method, of class MultivariateMonteCarloIntegrator.
*/
public void testGetMean_Collection()
{
System.out.println("getMean");
Vector mean = VectorFactory.getDefault().createUniformRandom(
DIM, -RANGE, RANGE, RANDOM );
Matrix variance = MatrixFactory.getDefault().createIdentity(DIM, DIM).scale( RANDOM.nextDouble() * RANGE + 2.0 );
MultivariateGaussian.PDF targetDistribution =
new MultivariateGaussian.PDF( mean, variance );
MultivariateMonteCarloIntegrator instance =
new MultivariateMonteCarloIntegrator();
int num = 100;
ArrayList<Vector> means = new ArrayList<Vector>( num );
ArrayList<Vector> variances = new ArrayList<Vector>( num );
for( int n = 0; n < num; n++ )
{
MultivariateGaussian.PDF g =
instance.getMean( targetDistribution.sample(RANDOM, NUM_SAMPLES) );
means.add( g.getMean() );
variances.add( g.getCovariance().convertToVector() );
}
MultivariateGaussian sampleMeanDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(means, 0.0);
MultivariateGaussian sampleVarianceDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(variances, 0.0);
Vector meanTarget = targetDistribution.getMean();
double zsquared = sampleMeanDistribution.computeZSquared( meanTarget );
double p = 1.0-ChiSquareDistribution.CDF.evaluate( zsquared, DIM );
System.out.println( "====== Mean ========" );
System.out.println( "Target = " + targetDistribution.getMean() );
System.out.println( "Sample = " + sampleMeanDistribution.getMean() );
System.out.println( "Z-squared= " + zsquared );
System.out.println( "P-value = " + p );
assertEquals( 1.0, p, 0.95 );
Vector varianceTarget = targetDistribution.getCovariance().scale(1.0/NUM_SAMPLES).convertToVector();
zsquared = sampleVarianceDistribution.computeZSquared(
varianceTarget );
p = 1.0-ChiSquareDistribution.CDF.evaluate( zsquared, DIM*DIM );
System.out.println( "====== Variance =======" );
System.out.println( "Target = " + varianceTarget );
System.out.println( "Sample = " + sampleVarianceDistribution.getMean() );
System.out.println( "Z-squared= " + zsquared );
System.out.println( "P-value = " + p );
assertEquals( 1.0, p, 0.95 );
}
/**
* Test of getMean method, of class MultivariateMonteCarloIntegrator.
*/
public void testGetMean_List()
{
System.out.println("getMean");
Vector mean = VectorFactory.getDefault().createUniformRandom(
DIM, -RANGE, RANGE, RANDOM );
Matrix variance = MatrixFactory.getDefault().createIdentity(DIM, DIM).scale( RANDOM.nextDouble() * RANGE + 2.0 );
MultivariateGaussian.PDF targetDistribution =
new MultivariateGaussian.PDF( mean, variance );
MultivariateMonteCarloIntegrator instance =
new MultivariateMonteCarloIntegrator();
MultivariateGaussian.PDF importanceDistribution =
new MultivariateGaussian.PDF( mean.scale(2.0), variance.scale(2.0) );
ImportanceSampler<Vector> sampler =
new ImportanceSampler<Vector>( importanceDistribution );
System.out.println( "Target = " + targetDistribution.getMean() );
System.out.println( "Importance = " + importanceDistribution.getMean() );
int num = 100;
ArrayList<Vector> means = new ArrayList<Vector>( num );
ArrayList<Vector> variances = new ArrayList<Vector>( num );
for( int n = 0; n < num; n++ )
{
MultivariateGaussian.PDF g =
instance.getMean( sampler.sample(targetDistribution, RANDOM, NUM_SAMPLES ) );
means.add( g.getMean() );
variances.add( g.getCovariance().convertToVector() );
}
MultivariateGaussian sampleMeanDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(means, 0.0);
MultivariateGaussian sampleVarianceDistribution =
MultivariateGaussian.MaximumLikelihoodEstimator.learn(variances, 0.0);
Vector meanTarget = targetDistribution.getMean();
double zsquared = sampleMeanDistribution.computeZSquared( meanTarget );
double p = 1.0-ChiSquareDistribution.CDF.evaluate( zsquared, DIM );
System.out.println( "====== Mean ========" );
System.out.println( "Target = " + targetDistribution.getMean() );
System.out.println( "Sample = " + sampleMeanDistribution.getMean() );
System.out.println( "Z-squared= " + zsquared );
System.out.println( "P-value = " + p );
assertEquals( 1.0, p, 0.95 );
}
/**
* Equivalence of Weighted/Unweighted methods
*/
public void testGetMean_Equivalence()
{
System.out.println( "Equivalence of Weighted/Unweighted methods" );
final double weight = RANDOM.nextDouble() * 10.0;
Vector mean = VectorFactory.getDefault().createUniformRandom(
DIM, -RANGE, RANGE, RANDOM );
Matrix variance = MatrixFactory.getDefault().createIdentity(DIM, DIM).scale( RANDOM.nextDouble() * RANGE + 2.0 );
MultivariateGaussian.PDF targetDistribution =
new MultivariateGaussian.PDF( mean, variance );
MultivariateMonteCarloIntegrator instance =
new MultivariateMonteCarloIntegrator();
ArrayList<Vector> samples = targetDistribution.sample(RANDOM, NUM_SAMPLES);
ArrayList<DefaultWeightedValue<Vector>> weightedSamples =
new ArrayList<DefaultWeightedValue<Vector>>( samples.size() );
for( Vector sample : samples )
{
weightedSamples.add( new DefaultWeightedValue<Vector>( sample, weight ) );
}
MultivariateGaussian ur = instance.getMean(samples);
MultivariateGaussian wr = instance.getMean(weightedSamples);
System.out.println( "Unweighted = " + ur.getMean() );
System.out.println( "Weighted = " + wr.getMean() );
// System.out.println( "U/W Ratio = " + ur.get() / wr.getVariance() );
if( !ur.getMean().equals( wr.getMean(), TOLERANCE ) )
{
assertEquals( ur.getMean(), wr.getMean() );
}
if( !ur.getCovariance().equals( wr.getCovariance(), TOLERANCE ) )
{
assertEquals( ur.getCovariance(), wr.getCovariance() );
}
// Now add a whole bunch of samples to the weighted method with zero
// weights. This should return the sample variance.
weightedSamples.ensureCapacity( weightedSamples.size() + NUM_SAMPLES );
for( int n = 0; n < NUM_SAMPLES; n++ )
{
weightedSamples.add( new DefaultWeightedValue<Vector>( samples.get(n), 0.0 ) );
}
MultivariateGaussian wr2 = instance.getMean(weightedSamples);
System.out.println( "Weighted2 = " + wr2.getMean() );
assertEquals( wr.getMean(), wr2.getMean() );
assertEquals( wr.getCovariance(), wr2.getCovariance() );
}
}