From a6e09c7fc4e272285a9a7edf12fd19f969d85518 Mon Sep 17 00:00:00 2001 From: "joseph.lizier" Date: Thu, 13 Dec 2012 14:50:33 +0000 Subject: [PATCH] Pulled some common functionality for testing multivariate TE calculators into an abstract class. Added basic tester for Kraskov multivariate TE --- .../TransferEntropyMultiVariateTester.java | 86 +++++++++++++++++++ .../TransferEntropyMultiVariateTester.java | 62 +------------ .../TransferEntropyMultiVariateTester.java | 50 +++++++++++ 3 files changed, 140 insertions(+), 58 deletions(-) create mode 100755 java/unittests/infodynamics/measures/continuous/TransferEntropyMultiVariateTester.java create mode 100755 java/unittests/infodynamics/measures/continuous/kraskov/TransferEntropyMultiVariateTester.java diff --git a/java/unittests/infodynamics/measures/continuous/TransferEntropyMultiVariateTester.java b/java/unittests/infodynamics/measures/continuous/TransferEntropyMultiVariateTester.java new file mode 100755 index 0000000..2c15950 --- /dev/null +++ b/java/unittests/infodynamics/measures/continuous/TransferEntropyMultiVariateTester.java @@ -0,0 +1,86 @@ +package infodynamics.measures.continuous; + +import junit.framework.TestCase; +import infodynamics.utils.MatrixUtils; +import infodynamics.utils.RandomGenerator; + +public abstract class TransferEntropyMultiVariateTester extends TestCase { + + /** + * Confirm that the local values average correctly back to the average value + * + * @param teCalc a pre-constructed TransferEntropyCalculatorMultiVariate object + * @param dimensions number of dimensions for the source and dest data to use + * @param timeSteps number of time steps for the random data + * @param k history length for the TE calculator to use + */ + public void testLocalsAverageCorrectly(TransferEntropyCalculatorMultiVariate teCalc, + int dimensions, int timeSteps, int k) + throws Exception { + + teCalc.initialise(k, dimensions, dimensions); + + // generate some random data + RandomGenerator rg = new RandomGenerator(); + double[][] sourceData = rg.generateNormalData(timeSteps, dimensions, + 0, 1); + double[][] destData = rg.generateNormalData(timeSteps, dimensions, + 0, 1); + + teCalc.setObservations(sourceData, destData); + + //teCalc.setDebug(true); + double te = teCalc.computeAverageLocalOfObservations(); + //teCalc.setDebug(false); + double[] teLocal = teCalc.computeLocalOfPreviousObservations(); + + System.out.printf("Average was %.5f\n", te); + + assertEquals(te, MatrixUtils.mean(teLocal, k, timeSteps-k), 0.00001); + } + + /** + * Confirm that significance testing doesn't alter the average that + * would be returned. + * + * @param teCalc a pre-constructed TransferEntropyCalculatorMultiVariate object + * @param dimensions number of dimensions for the source and dest data to use + * @param timeSteps number of time steps for the random data + * @param k history length for the TE calculator to use + * @throws Exception + */ + public void testComputeSignificanceDoesntAlterAverage(TransferEntropyCalculatorMultiVariate teCalc, + int dimensions, int timeSteps, int k) throws Exception { + + teCalc.initialise(k, dimensions, dimensions); + + // generate some random data + RandomGenerator rg = new RandomGenerator(); + double[][] sourceData = rg.generateNormalData(timeSteps, dimensions, + 0, 1); + double[][] destData = rg.generateNormalData(timeSteps, dimensions, + 0, 1); + + teCalc.setObservations(sourceData, destData); + + //teCalc.setDebug(true); + double te = teCalc.computeAverageLocalOfObservations(); + //teCalc.setDebug(false); + //double[] teLocal = teCalc.computeLocalOfPreviousObservations(); + + System.out.printf("Average was %.5f\n", te); + + // Now look at statistical significance tests + int[][] newOrderings = rg.generateDistinctRandomPerturbations( + timeSteps - k, 100); + + teCalc.computeSignificance(newOrderings); + + // And compute the average value again to check that it's consistent: + for (int i = 0; i < 10; i++) { + double averageCheck1 = teCalc.computeAverageLocalOfObservations(); + assertEquals(te, averageCheck1); + } + } + +} diff --git a/java/unittests/infodynamics/measures/continuous/kernel/TransferEntropyMultiVariateTester.java b/java/unittests/infodynamics/measures/continuous/kernel/TransferEntropyMultiVariateTester.java index 8aba059..4a4f8cb 100755 --- a/java/unittests/infodynamics/measures/continuous/kernel/TransferEntropyMultiVariateTester.java +++ b/java/unittests/infodynamics/measures/continuous/kernel/TransferEntropyMultiVariateTester.java @@ -1,12 +1,8 @@ package infodynamics.measures.continuous.kernel; -import infodynamics.utils.MatrixUtils; -import infodynamics.utils.RandomGenerator; -import junit.framework.TestCase; +public class TransferEntropyMultiVariateTester + extends infodynamics.measures.continuous.TransferEntropyMultiVariateTester { -public class TransferEntropyMultiVariateTester extends TestCase { - - /** * Confirm that the local values average correctly back to the average value * @@ -16,9 +12,6 @@ public class TransferEntropyMultiVariateTester extends TestCase { TransferEntropyCalculatorMultiVariateKernel teCalc = new TransferEntropyCalculatorMultiVariateKernel(); - int dimensions = 2; - int timeSteps = 100; - int k = 1; String kernelWidth = "1"; teCalc.setProperty( @@ -27,25 +20,8 @@ public class TransferEntropyMultiVariateTester extends TestCase { teCalc.setProperty( TransferEntropyCalculatorMultiVariateKernel.EPSILON_PROP_NAME, kernelWidth); - teCalc.initialise(k, dimensions, dimensions); - - // generate some random data - RandomGenerator rg = new RandomGenerator(); - double[][] sourceData = rg.generateNormalData(timeSteps, dimensions, - 0, 1); - double[][] destData = rg.generateNormalData(timeSteps, dimensions, - 0, 1); - - teCalc.setObservations(sourceData, destData); - - //teCalc.setDebug(true); - double te = teCalc.computeAverageLocalOfObservations(); - //teCalc.setDebug(false); - double[] teLocal = teCalc.computeLocalOfPreviousObservations(); - - System.out.printf("Average was %.5f\n", te); - assertEquals(te, MatrixUtils.mean(teLocal, k, timeSteps-k), 0.0001); + super.testLocalsAverageCorrectly(teCalc, 2, 100, 1); } /** @@ -59,9 +35,6 @@ public class TransferEntropyMultiVariateTester extends TestCase { TransferEntropyCalculatorMultiVariateKernel teCalc = new TransferEntropyCalculatorMultiVariateKernel(); - int dimensions = 2; - int timeSteps = 100; - int k = 1; String kernelWidth = "1"; teCalc.setProperty( @@ -70,35 +43,8 @@ public class TransferEntropyMultiVariateTester extends TestCase { teCalc.setProperty( TransferEntropyCalculatorMultiVariateKernel.EPSILON_PROP_NAME, kernelWidth); - teCalc.initialise(k, dimensions, dimensions); - - // generate some random data - RandomGenerator rg = new RandomGenerator(); - double[][] sourceData = rg.generateNormalData(timeSteps, dimensions, - 0, 1); - double[][] destData = rg.generateNormalData(timeSteps, dimensions, - 0, 1); - - teCalc.setObservations(sourceData, destData); - - //teCalc.setDebug(true); - double te = teCalc.computeAverageLocalOfObservations(); - //teCalc.setDebug(false); - //double[] teLocal = teCalc.computeLocalOfPreviousObservations(); - - System.out.printf("Average was %.5f\n", te); - - // Now look at statistical significance tests - int[][] newOrderings = rg.generateDistinctRandomPerturbations( - timeSteps - k, 100); - teCalc.computeSignificance(newOrderings); - - // And compute the average value again to check that it's consistent: - for (int i = 0; i < 10; i++) { - double averageCheck1 = teCalc.computeAverageLocalOfObservations(); - assertEquals(te, averageCheck1); - } + super.testComputeSignificanceDoesntAlterAverage(teCalc, 2, 100, 1); } } diff --git a/java/unittests/infodynamics/measures/continuous/kraskov/TransferEntropyMultiVariateTester.java b/java/unittests/infodynamics/measures/continuous/kraskov/TransferEntropyMultiVariateTester.java new file mode 100755 index 0000000..ab8ac06 --- /dev/null +++ b/java/unittests/infodynamics/measures/continuous/kraskov/TransferEntropyMultiVariateTester.java @@ -0,0 +1,50 @@ +package infodynamics.measures.continuous.kraskov; + +public class TransferEntropyMultiVariateTester + extends infodynamics.measures.continuous.TransferEntropyMultiVariateTester { + + /** + * Confirm that the local values average correctly back to the average value + * + */ + public void testLocalsAverageCorrectly() throws Exception { + + TransferEntropyCalculatorMultiVariateKraskov teCalc = + new TransferEntropyCalculatorMultiVariateKraskov(); + + String kraskov_K = "4"; + + teCalc.setProperty( + TransferEntropyCalculatorMultiVariateKraskov.PROP_KRASKOV_ALG_NUM, + "2"); + teCalc.setProperty( + MutualInfoCalculatorMultiVariateKraskov.PROP_K, + kraskov_K); + + super.testLocalsAverageCorrectly(teCalc, 2, 100, 1); + } + + /** + * Confirm that significance testing doesn't alter the average that + * would be returned. + * + * @throws Exception + */ + public void testComputeSignificanceDoesntAlterAverage() throws Exception { + + TransferEntropyCalculatorMultiVariateKraskov teCalc = + new TransferEntropyCalculatorMultiVariateKraskov(); + + String kraskov_K = "4"; + + teCalc.setProperty( + TransferEntropyCalculatorMultiVariateKraskov.PROP_KRASKOV_ALG_NUM, + "2"); + teCalc.setProperty( + MutualInfoCalculatorMultiVariateKraskov.PROP_K, + kraskov_K); + + super.testComputeSignificanceDoesntAlterAverage(teCalc, 2, 100, 1); + } + +}