mirror of https://github.com/jlizier/jidt
Added unit tests for conditional TE continuous calculators.
Added some more tests for TE Kraskov also.
This commit is contained in:
parent
a63e104dc6
commit
926f22992e
|
@ -0,0 +1,170 @@
|
|||
package infodynamics.measures.continuous;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
public abstract class ConditionalTransferEntropyAbstractTester extends TestCase {
|
||||
|
||||
/**
|
||||
* Confirm that the local values average correctly back to the average value
|
||||
*
|
||||
* @param teCalc a pre-constructed ConditionalTransferEntropyCalculator object
|
||||
* @param timeSteps number of time steps for the random data
|
||||
* @param k dest history length for the TE calculator to use
|
||||
*/
|
||||
public void testLocalsAverageCorrectly(ConditionalTransferEntropyCalculator teCalc,
|
||||
int timeSteps, int k)
|
||||
throws Exception {
|
||||
|
||||
teCalc.initialise(k, 1, 1);
|
||||
|
||||
// generate some random data
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
double[] sourceData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
double[] destData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
double[] condData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
|
||||
teCalc.setObservations(sourceData, destData, condData);
|
||||
|
||||
//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 ConditionalTransferEntropyCalculator object
|
||||
* @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(ConditionalTransferEntropyCalculator teCalc,
|
||||
int timeSteps, int k) throws Exception {
|
||||
|
||||
teCalc.initialise(k, 1, 1);
|
||||
|
||||
// generate some random data
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
double[] sourceData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
double[] destData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
double[] condData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
|
||||
teCalc.setObservations(sourceData, destData, condData);
|
||||
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that univariate method signature calls fail if the calculator
|
||||
* was not initialised for univariate conditional data.
|
||||
*
|
||||
* @param teCalc
|
||||
*/
|
||||
public void testUnivariateCallFailsIfWrongInitialisation(ConditionalTransferEntropyCalculator teCalc) throws Exception {
|
||||
|
||||
teCalc.initialise(1, 1, 1);
|
||||
|
||||
// generate some random data
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
double[] sourceData = rg.generateNormalData(10,
|
||||
0, 1);
|
||||
double[] destData = rg.generateNormalData(10,
|
||||
0, 1);
|
||||
double[] condData = rg.generateNormalData(10,
|
||||
0, 1);
|
||||
boolean gotException = false;
|
||||
try {
|
||||
teCalc.setObservations(sourceData, destData, condData);
|
||||
} catch (Exception e) {
|
||||
gotException = true;
|
||||
}
|
||||
assert(gotException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm the workings of the conditional TE calculator
|
||||
* by calculating pairwise TE with a long k, then computing
|
||||
* conditional TE with a shorter history length k, but
|
||||
* other conditional variables copying the values of those further past
|
||||
* values of the destination.
|
||||
*
|
||||
* @param teCalc a pre-constructed TransferEntropyCalculator object
|
||||
* @param condTeCalc a pre-constructed ConditionalTransferEntropyCalculator object
|
||||
* of the same estimator type
|
||||
* @param timeSteps number of time steps for the random data
|
||||
* @param k history length for the TE calculator to use
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testConditionalAgainstOrdinaryTE(
|
||||
TransferEntropyCalculator teCalc,
|
||||
ConditionalTransferEntropyCalculator condTeCalc,
|
||||
int timeSteps, int k) throws Exception {
|
||||
|
||||
if (k < 2) {
|
||||
throw new Exception("Need k >= 2 for testConditionalAgainstOrdinaryTE");
|
||||
}
|
||||
|
||||
// generate some random data
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
double[] sourceData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
double[] destData = rg.generateNormalData(timeSteps,
|
||||
0, 1);
|
||||
|
||||
// First compute ordinary TE
|
||||
teCalc.initialise(k);
|
||||
teCalc.setObservations(sourceData, destData);
|
||||
double te = teCalc.computeAverageLocalOfObservations();
|
||||
System.out.printf("TE(k=%d): Average was %.5f\n", k, te);
|
||||
|
||||
// Next compute conditional TE with some older
|
||||
// parts of the destination as conditional variables
|
||||
// instead of in the destination past.
|
||||
int[] condDims = {k-1};
|
||||
int[] condTaus = {1};
|
||||
int[] condDelays = {2};
|
||||
condTeCalc.initialise(1, 1, 1, 1, 1, condDims, condTaus, condDelays);
|
||||
// Don't need to extract the data ourselves:
|
||||
// double[][] condData =
|
||||
// MatrixUtils.makeDelayEmbeddingVector(destData, k-1,
|
||||
// k-2, destData.length-k+1); // Need an extra unused one here
|
||||
condTeCalc.setObservations(sourceData, destData, destData);
|
||||
double condTe = condTeCalc.computeAverageLocalOfObservations();
|
||||
System.out.printf("CondTE(k=%d): Average was %.5f\n", k, condTe);
|
||||
|
||||
assertEquals(teCalc.getNumObservations(), condTeCalc.getNumObservations());
|
||||
assertEquals(te, condTe, 0.000000001);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package infodynamics.measures.continuous.gaussian;
|
||||
|
||||
import infodynamics.measures.continuous.ConditionalTransferEntropyAbstractTester;
|
||||
|
||||
public class ConditionalTransferEntropyGaussianTester extends
|
||||
ConditionalTransferEntropyAbstractTester {
|
||||
|
||||
public void testUnivariateMethodSignatureFails() throws Exception {
|
||||
ConditionalTransferEntropyCalculatorGaussian teCalc = new ConditionalTransferEntropyCalculatorGaussian();
|
||||
super.testUnivariateCallFailsIfWrongInitialisation(teCalc);
|
||||
}
|
||||
|
||||
public void testLocalsAverageCorrectly() throws Exception {
|
||||
ConditionalTransferEntropyCalculatorGaussian teCalc = new ConditionalTransferEntropyCalculatorGaussian();
|
||||
super.testLocalsAverageCorrectly(teCalc, 100, 2);
|
||||
}
|
||||
|
||||
public void testComputeSignificanceDoesntAlterAverage() throws Exception {
|
||||
ConditionalTransferEntropyCalculatorGaussian teCalc = new ConditionalTransferEntropyCalculatorGaussian();
|
||||
super.testComputeSignificanceDoesntAlterAverage(teCalc, 100, 2);
|
||||
}
|
||||
|
||||
public void testAgainstApparentTE() throws Exception {
|
||||
TransferEntropyCalculatorGaussian teCalc = new TransferEntropyCalculatorGaussian();
|
||||
ConditionalTransferEntropyCalculatorGaussian condTeCalc = new ConditionalTransferEntropyCalculatorGaussian();
|
||||
testConditionalAgainstOrdinaryTE(teCalc, condTeCalc, 100, 2);
|
||||
testConditionalAgainstOrdinaryTE(teCalc, condTeCalc, 100, 3);
|
||||
testConditionalAgainstOrdinaryTE(teCalc, condTeCalc, 100, 4);
|
||||
}
|
||||
}
|
|
@ -2,12 +2,22 @@ package infodynamics.measures.continuous.gaussian;
|
|||
|
||||
import java.util.Vector;
|
||||
|
||||
import infodynamics.measures.continuous.TransferEntropyAbstractTester;
|
||||
import infodynamics.utils.ArrayFileReader;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TransferEntropyGaussianTester extends TestCase {
|
||||
public class TransferEntropyGaussianTester extends TransferEntropyAbstractTester {
|
||||
|
||||
public void testLocalsAverageCorrectly() throws Exception {
|
||||
TransferEntropyCalculatorGaussian teCalc = new TransferEntropyCalculatorGaussian();
|
||||
super.testLocalsAverageCorrectly(teCalc, 100, 2);
|
||||
}
|
||||
|
||||
public void testComputeSignificanceDoesntAlterAverage() throws Exception {
|
||||
TransferEntropyCalculatorGaussian teCalc = new TransferEntropyCalculatorGaussian();
|
||||
super.testComputeSignificanceDoesntAlterAverage(teCalc, 100, 2);
|
||||
}
|
||||
|
||||
public void testEmbedding() throws Exception {
|
||||
ArrayFileReader afr = new ArrayFileReader("demos/data/2coupledRandomCols-1.txt");
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package infodynamics.measures.continuous.kraskov;
|
||||
|
||||
import infodynamics.measures.continuous.ConditionalTransferEntropyAbstractTester;
|
||||
|
||||
public class ConditionalTransferEntropyKraskovTester extends
|
||||
ConditionalTransferEntropyAbstractTester {
|
||||
|
||||
public void testUnivariateMethodSignatureFails() throws Exception {
|
||||
ConditionalTransferEntropyCalculatorKraskov teCalc = new ConditionalTransferEntropyCalculatorKraskov();
|
||||
String kraskov_K = "4";
|
||||
teCalc.setProperty(
|
||||
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_K,
|
||||
kraskov_K);
|
||||
super.testUnivariateCallFailsIfWrongInitialisation(teCalc);
|
||||
}
|
||||
|
||||
public void testLocalsAverageCorrectly() throws Exception {
|
||||
ConditionalTransferEntropyCalculatorKraskov teCalc = new ConditionalTransferEntropyCalculatorKraskov();
|
||||
String kraskov_K = "4";
|
||||
teCalc.setProperty(
|
||||
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_K,
|
||||
kraskov_K);
|
||||
super.testLocalsAverageCorrectly(teCalc, 100, 2);
|
||||
}
|
||||
|
||||
public void testComputeSignificanceDoesntAlterAverage() throws Exception {
|
||||
ConditionalTransferEntropyCalculatorKraskov teCalc = new ConditionalTransferEntropyCalculatorKraskov();
|
||||
String kraskov_K = "4";
|
||||
teCalc.setProperty(
|
||||
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_K,
|
||||
kraskov_K);
|
||||
super.testComputeSignificanceDoesntAlterAverage(teCalc, 100, 2);
|
||||
}
|
||||
|
||||
public void testAgainstApparentTE() throws Exception {
|
||||
TransferEntropyCalculatorKraskov teCalc = new TransferEntropyCalculatorKraskov();
|
||||
String kraskov_K = "4";
|
||||
teCalc.setProperty(
|
||||
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_K,
|
||||
kraskov_K);
|
||||
ConditionalTransferEntropyCalculatorKraskov condTeCalc = new ConditionalTransferEntropyCalculatorKraskov();
|
||||
condTeCalc.setProperty(
|
||||
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_K,
|
||||
kraskov_K);
|
||||
testConditionalAgainstOrdinaryTE(teCalc, condTeCalc, 100, 2);
|
||||
testConditionalAgainstOrdinaryTE(teCalc, condTeCalc, 100, 3);
|
||||
testConditionalAgainstOrdinaryTE(teCalc, condTeCalc, 100, 4);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue