Added unit tests for Kraskov Conditional MI against TEs computed by Wibral et al.'s TRENTOOL

This commit is contained in:
joseph.lizier 2013-01-16 11:54:13 +00:00
parent 6196cb5710
commit 111055fc81
1 changed files with 175 additions and 0 deletions

View File

@ -1,5 +1,8 @@
package infodynamics.measures.continuous.kraskov;
import infodynamics.utils.ArrayFileReader;
import infodynamics.utils.MatrixUtils;
public class ConditionalMutualInfoMultiVariateTester
extends infodynamics.measures.continuous.ConditionalMutualInfoMultiVariateAbstractTester {
@ -63,4 +66,176 @@ public class ConditionalMutualInfoMultiVariateTester
checkComputeSignificanceDoesntAlterAverage(2);
}
/**
* Utility function to run Kraskov conditional MI algorithm 1
* as transfer entropy for data with known results
* from TRENTOOL.
*
* @param var1 source multivariate data set
* @param var2 dest multivariate data set
* @param kNNs array of Kraskov k nearest neighbours parameter to check
* @param expectedResults array of expected results for each k
*/
protected void checkTEForGivenData(double[][] var1, double[][] var2,
int[] kNNs, double[] expectedResults) throws Exception {
ConditionalMutualInfoCalculatorMultiVariateKraskov condMiCalc = getNewCalc(1);
// Normalise the data ourselves rather than letting the calculator do it -
// this ensures the extra values in the time series (e.g. last value in source)
// are taken into account, in line with TRENTOOL
var1 = MatrixUtils.normaliseIntoNewArray(var1);
var2 = MatrixUtils.normaliseIntoNewArray(var2);
for (int kIndex = 0; kIndex < kNNs.length; kIndex++) {
int k = kNNs[kIndex];
condMiCalc.setProperty(
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_K,
Integer.toString(k));
// We already normalised above, and this will do a different
// normalisation without taking the extra values in to account if we did it
condMiCalc.setProperty(
ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_NORMALISE,
Boolean.toString(false));
// No longer need to set this property as it's set by default:
//condMiCalc.setProperty(ConditionalMutualInfoCalculatorMultiVariateKraskov.PROP_NORM_TYPE,
// EuclideanUtils.NORM_MAX_NORM_STRING);
condMiCalc.setObservations(MatrixUtils.selectRows(var1, 0, var1.length - 1),
MatrixUtils.selectRows(var2, 1, var2.length - 1),
MatrixUtils.selectRows(var2, 0, var2.length - 1));
double condMi = condMiCalc.computeAverageLocalOfObservations();
//miCalc.setDebug(false);
System.out.printf("k=%d: Average MI %.8f (expected %.8f)\n",
k, condMi, expectedResults[kIndex]);
// 6 decimal places is Matlab accuracy
assertEquals(expectedResults[kIndex], condMi, 0.000001);
}
}
/**
* Test the computed univariate TE as a conditional MI
* against that calculated by Wibral et al.'s TRENTOOL
* on the same data.
*
* To run TRENTOOL (http://www.trentool.de/) for this
* data, run its TEvalues.m matlab script on the multivariate source
* and dest data sets as:
* TEvalues(source, dest, 1, 1, 1, kraskovK, 0)
* with these values ensuring source-dest lag 1, history k=1,
* embedding lag 1, no dynamic correlation exclusion
*
* @throws Exception if file not found
*
*/
public void testUnivariateTEforCoupledVariablesFromFile() throws Exception {
// Test set 1:
ArrayFileReader afr = new ArrayFileReader("demos/data/2coupledRandomCols-1.txt");
double[][] data = afr.getDouble2DMatrix();
// Use various Kraskov k nearest neighbours parameter
int[] kNNs = {4};
// Expected values from TRENTOOL:
double[] expectedFromTRENTOOL = {0.3058006};
System.out.println("Kraskov Cond MI as TE comparison 1 - univariate coupled data 1");
checkTEForGivenData(MatrixUtils.selectColumns(data, new int[] {0}),
MatrixUtils.selectColumns(data, new int[] {1}),
kNNs, expectedFromTRENTOOL);
// And now in the reverse direction:
expectedFromTRENTOOL = new double[] {-0.0029744};
System.out.println(" reverse direction:");
checkTEForGivenData(MatrixUtils.selectColumns(data, new int[] {1}),
MatrixUtils.selectColumns(data, new int[] {0}),
kNNs, expectedFromTRENTOOL);
}
/**
* Test the computed univariate TE as a conditional MI
* against that calculated by Wibral et al.'s TRENTOOL
* on the same data.
*
* To run TRENTOOL (http://www.trentool.de/) for this
* data, run its TEvalues.m matlab script on the multivariate source
* and dest data sets as:
* TEvalues(source, dest, 1, 1, 1, kraskovK, 0)
* with these values ensuring source-dest lag 1, history k=1,
* embedding lag 1, no dynamic correlation exclusion
*
* @throws Exception if file not found
*
*/
public void testUnivariateTEforCoupledLogisticMapFromFile() throws Exception {
// Test set 1:
ArrayFileReader afr = new ArrayFileReader("demos/data/coupledLogisticMapXY.txt");
double[][] data = afr.getDouble2DMatrix();
// Use various Kraskov k nearest neighbours parameter
int[] kNNs = {4};
// Expected values from TRENTOOL:
double[] expectedFromTRENTOOL = {0.508417};
System.out.println("Kraskov Cond MI as TE comparison 1 - univariate coupled logistic map data 1");
checkTEForGivenData(MatrixUtils.selectColumns(data, new int[] {0}),
MatrixUtils.selectColumns(data, new int[] {1}),
kNNs, expectedFromTRENTOOL);
// And now in the reverse direction:
expectedFromTRENTOOL = new double[] {0.016257};
System.out.println(" reverse direction:");
checkTEForGivenData(MatrixUtils.selectColumns(data, new int[] {1}),
MatrixUtils.selectColumns(data, new int[] {0}),
kNNs, expectedFromTRENTOOL);
}
/**
* Test the computed univariate TE as a conditional MI
* against that calculated by Wibral et al.'s TRENTOOL
* on the same data.
*
* To run TRENTOOL (http://www.trentool.de/) for this
* data, run its TEvalues.m matlab script on the multivariate source
* and dest data sets as:
* TEvalues(source, dest, 1, 1, 1, kraskovK, 0)
* with these values ensuring source-dest lag 1, history k=1,
* embedding lag 1, no dynamic correlation exclusion
*
* @throws Exception if file not found
*
*/
public void testUnivariateTEforRandomDataFromFile() throws Exception {
// Test set 1:
ArrayFileReader afr = new ArrayFileReader("demos/data/4randomCols-1.txt");
double[][] data = afr.getDouble2DMatrix();
// Use various Kraskov k nearest neighbours parameter
int[] kNNs = {4};
// Expected values from TRENTOOL:
double[] expectedFromTRENTOOL = {-0.0096556};
System.out.println("Kraskov Cond MI as TE comparison 1 - univariate random data 1");
checkTEForGivenData(MatrixUtils.selectColumns(data, new int[] {0}),
MatrixUtils.selectColumns(data, new int[] {1}),
kNNs, expectedFromTRENTOOL);
// And now for other columns
expectedFromTRENTOOL = new double[] {0.0175389};
System.out.println(" reverse direction:");
checkTEForGivenData(MatrixUtils.selectColumns(data, new int[] {1}),
MatrixUtils.selectColumns(data, new int[] {2}),
kNNs, expectedFromTRENTOOL);
}
}