From 2d48195ce614bc2bb814537a098a4ff1efb4d6cf Mon Sep 17 00:00:00 2001 From: "joseph.lizier" Date: Fri, 1 Aug 2014 03:32:16 +0000 Subject: [PATCH] Adding examples 7 and 8 to Java Simple Demos (for ensemble approach, and binning data), plus adding bias estimation to example 3 and local TE to example 4 --- ...e7EnsembleMethodTeContinuousDataKraskov.sh | 8 +++ .../java/example8TeContinuousDataByBinning.sh | 8 +++ .../demos/Example3TeContinuousDataKernel.java | 7 ++ .../Example4TeContinuousDataKraskov.java | 5 ++ ...EnsembleMethodTeContinuousDataKraskov.java | 67 +++++++++++++++++++ .../Example8TeContinuousDataByBinning.java | 54 +++++++++++++++ 6 files changed, 149 insertions(+) create mode 100755 demos/java/example7EnsembleMethodTeContinuousDataKraskov.sh create mode 100755 demos/java/example8TeContinuousDataByBinning.sh create mode 100755 demos/java/infodynamics/demos/Example7EnsembleMethodTeContinuousDataKraskov.java create mode 100755 demos/java/infodynamics/demos/Example8TeContinuousDataByBinning.java diff --git a/demos/java/example7EnsembleMethodTeContinuousDataKraskov.sh b/demos/java/example7EnsembleMethodTeContinuousDataKraskov.sh new file mode 100755 index 0000000..65fa7df --- /dev/null +++ b/demos/java/example7EnsembleMethodTeContinuousDataKraskov.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Make sure the latest example source file is compiled. +javac -classpath "../../infodynamics.jar" "infodynamics/demos/Example7EnsembleMethodTeContinuousDataKraskov.java" + +# Run the example: +java -classpath ".:../../infodynamics.jar" infodynamics.demos.Example7EnsembleMethodTeContinuousDataKraskov + diff --git a/demos/java/example8TeContinuousDataByBinning.sh b/demos/java/example8TeContinuousDataByBinning.sh new file mode 100755 index 0000000..79d818e --- /dev/null +++ b/demos/java/example8TeContinuousDataByBinning.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Make sure the latest example source file is compiled. +javac -classpath "../../infodynamics.jar" "infodynamics/demos/Example8TeContinuousDataByBinning.java" + +# Run the example: +java -classpath ".:../../infodynamics.jar" infodynamics.demos.Example8TeContinuousDataByBinning + diff --git a/demos/java/infodynamics/demos/Example3TeContinuousDataKernel.java b/demos/java/infodynamics/demos/Example3TeContinuousDataKernel.java index 7cce3af..ab6b160 100755 --- a/demos/java/infodynamics/demos/Example3TeContinuousDataKernel.java +++ b/demos/java/infodynamics/demos/Example3TeContinuousDataKernel.java @@ -1,5 +1,6 @@ package infodynamics.demos; +import infodynamics.utils.EmpiricalMeasurementDistribution; import infodynamics.utils.RandomGenerator; import infodynamics.measures.continuous.kernel.TransferEntropyCalculatorKernel; @@ -52,5 +53,11 @@ public class Example3TeContinuousDataKernel { System.out.printf("TE result %.4f bits; expected to be close to " + "0 bits for uncorrelated Gaussians but will be biased upwards\n", result2); + + // We can get insight into the bias by examining the null distribution: + EmpiricalMeasurementDistribution nullDist = teCalc.computeSignificance(100); + System.out.printf("Null distribution for unrelated source and destination " + + "(i.e. the bias) has mean %.4f and standard deviation %.4f\n", + nullDist.getMeanOfDistribution(), nullDist.getStdOfDistribution()); } } diff --git a/demos/java/infodynamics/demos/Example4TeContinuousDataKraskov.java b/demos/java/infodynamics/demos/Example4TeContinuousDataKraskov.java index 8a78956..1b9d837 100755 --- a/demos/java/infodynamics/demos/Example4TeContinuousDataKraskov.java +++ b/demos/java/infodynamics/demos/Example4TeContinuousDataKraskov.java @@ -57,5 +57,10 @@ public class Example4TeContinuousDataKraskov { double result2 = teCalc.computeAverageLocalOfObservations(); System.out.printf("TE result %.4f nats; expected to be close to " + "0 nats for these uncorrelated Gaussians\n", result2); + + // We can also compute the local TE values for the time-series samples here: + // (See more about utility of local TE in the CA demos) + @SuppressWarnings("unused") + double[] localTE = teCalc.computeLocalOfPreviousObservations(); } } diff --git a/demos/java/infodynamics/demos/Example7EnsembleMethodTeContinuousDataKraskov.java b/demos/java/infodynamics/demos/Example7EnsembleMethodTeContinuousDataKraskov.java new file mode 100755 index 0000000..35a3ec6 --- /dev/null +++ b/demos/java/infodynamics/demos/Example7EnsembleMethodTeContinuousDataKraskov.java @@ -0,0 +1,67 @@ +package infodynamics.demos; + +import infodynamics.utils.RandomGenerator; +import infodynamics.measures.continuous.kraskov.TransferEntropyCalculatorKraskov; + +/** + * + * = Example 7 - Ensemble method with transfer entropy on continuous data using Kraskov estimators = + * + * Calculation of transfer entropy (TE) by supplying an ensemble of + * samples from multiple time series. + * We use continuous-valued data using the Kraskov-estimator TE calculator + * here. + * + * @author Joseph Lizier + * + */ +public class Example7EnsembleMethodTeContinuousDataKraskov { + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + + // Prepare to generate some random normalised data. + int numObservations = 1000; + double covariance = 0.4; + RandomGenerator rg = new RandomGenerator(); + + // Create a TE calculator and run it: + TransferEntropyCalculatorKraskov teCalc = + new TransferEntropyCalculatorKraskov(); + teCalc.setProperty("k", "4"); // Use Kraskov parameter K=4 for 4 nearest neighbours + teCalc.initialise(1); // Use history length 1 (Schreiber k=1) + teCalc.startAddObservations(); + + for (int trial = 0; trial < 10; trial++) { + + // Create a new trial, with destArray correlated to + // previous value of sourceArray: + double[] sourceArray = rg.generateNormalData(numObservations, 0, 1); + double[] destArray = rg.generateNormalData(numObservations, 0, 1-covariance); + for (int t = 1; t < numObservations; t++) { + destArray[t] += covariance * sourceArray[t-1]; + } + + // Add observations for this trial: + System.out.printf("Adding samples from trial %d ...\n", trial); + teCalc.addObservations(sourceArray, destArray); + } + + // We've finished adding trials: + System.out.println("Finished adding trials"); + teCalc.finaliseAddObservations(); + + // Compute the result: + System.out.println("Computing TE ..."); + double result = teCalc.computeAverageLocalOfObservations(); + // Note that the calculation is a random variable (because the generated + // data is a set of random variables) - the result will be of the order + // of what we expect, but not exactly equal to it; in fact, there will + // be some variance around it (smaller than example 4 since we have more samples). + System.out.printf("TE result %.4f nats; expected to be close to " + + "%.4f nats for these correlated Gaussians\n", + result, Math.log(1.0/(1-Math.pow(covariance,2)))); + } +} diff --git a/demos/java/infodynamics/demos/Example8TeContinuousDataByBinning.java b/demos/java/infodynamics/demos/Example8TeContinuousDataByBinning.java new file mode 100755 index 0000000..17f472c --- /dev/null +++ b/demos/java/infodynamics/demos/Example8TeContinuousDataByBinning.java @@ -0,0 +1,54 @@ +package infodynamics.demos; + +import infodynamics.utils.MatrixUtils; +import infodynamics.utils.RandomGenerator; +import infodynamics.measures.discrete.ApparentTransferEntropyCalculator; + +/** + * + * = Example 8 - Transfer entropy on continuous data by binning = + * + * Simple transfer entropy (TE) calculation on continuous-valued data + * by binning the continuous data to discrete, then using a discrete TE calculator. + * + * @author Joseph Lizier + * + */ +public class Example8TeContinuousDataByBinning { + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + + // Prepare to generate some random normalised data. + int numObservations = 1000; + double covariance = 0.4; + int numDiscreteLevels = 4; + + // Create destArray correlated to previous value of sourceArray: + RandomGenerator rg = new RandomGenerator(); + double[] sourceArray = rg.generateNormalData(numObservations, 0, 1); + double[] destArray = rg.generateNormalData(numObservations, 0, 1-covariance); + for (int t = 1; t < numObservations; t++) { + destArray[t] += covariance * sourceArray[t-1]; + } + + // Discretize or bin the data -- one could also call: + // MatrixUtils.discretiseMaxEntropy for a maximum entropy binning + int[] binnedSource = MatrixUtils.discretise(sourceArray, numDiscreteLevels); + int[] binnedDest = MatrixUtils.discretise(destArray, numDiscreteLevels); + + // Create a TE calculator and run it: + ApparentTransferEntropyCalculator teCalc= + new ApparentTransferEntropyCalculator(numDiscreteLevels, 1); + teCalc.initialise(); + teCalc.addObservations(binnedDest, binnedSource); + double result = teCalc.computeAverageLocalOfObservations(); + // Calculation will be heavily biased because of the binning, + // and the small number of samples + System.out.printf("TE result %.4f bits; expected to be close to " + + "%.4f bits for these correlated Gaussians\n", + result, Math.log(1.0/(1-Math.pow(covariance,2)))/Math.log(2)); + } +}