mirror of https://github.com/jlizier/jidt
Altered interal names of kernel width variables to be kernel width, instead of epsilon. This is more intuitive for users.
This commit is contained in:
parent
7159ecd4cc
commit
12e6f12147
|
|
@ -8,17 +8,24 @@ import java.util.Hashtable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to maintain probability distribution function for
|
* <p>Class to maintain probability distribution function for
|
||||||
* a single variable, using kernel estimates.
|
* a multivariate set, using kernel estimates.</p>
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* For more details on kernel estimation for computing probability distribution functions,
|
||||||
|
* see Kantz and Schreiber (below).
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Joseph Lizier
|
* @see KernelEstimatorSingleVariate
|
||||||
|
* @see "H. Kantz and T. Schreiber, 'Nonlinear Time Series Analysis'.
|
||||||
|
* Cambridge, MA: Cambridge University Press, 1997"
|
||||||
|
* @author Joseph Lizier, <a href="mailto:joseph.lizier at gmail.com">joseph.lizier at gmail.com</>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class KernelEstimatorMultiVariate implements Cloneable {
|
public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
|
|
||||||
protected double[] epsilon = null;
|
protected double[] suppliedKernelWidths = null;
|
||||||
protected double[] epsilonInUse = null;
|
protected double[] kernelWidthsInUse = null;
|
||||||
protected int dimensions = 1;
|
protected int dimensions = 1;
|
||||||
private int[] bins = null;
|
private int[] bins = null;
|
||||||
private boolean usingIntegerIndexBins = true;
|
private boolean usingIntegerIndexBins = true;
|
||||||
|
|
@ -107,9 +114,9 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public void initialise(int dimensions, double epsilon) {
|
public void initialise(int dimensions, double epsilon) {
|
||||||
this.dimensions = dimensions;
|
this.dimensions = dimensions;
|
||||||
this.epsilon = new double[dimensions];
|
this.suppliedKernelWidths = new double[dimensions];
|
||||||
for (int d = 0; d < dimensions; d++) {
|
for (int d = 0; d < dimensions; d++) {
|
||||||
this.epsilon[d] = epsilon;
|
this.suppliedKernelWidths[d] = epsilon;
|
||||||
}
|
}
|
||||||
finishInitialisation();
|
finishInitialisation();
|
||||||
}
|
}
|
||||||
|
|
@ -121,9 +128,9 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public void initialise(double[] epsilon) {
|
public void initialise(double[] epsilon) {
|
||||||
dimensions = epsilon.length;
|
dimensions = epsilon.length;
|
||||||
this.epsilon = new double[dimensions];
|
this.suppliedKernelWidths = new double[dimensions];
|
||||||
for (int d = 0; d < dimensions; d++) {
|
for (int d = 0; d < dimensions; d++) {
|
||||||
this.epsilon[d] = epsilon[d];
|
this.suppliedKernelWidths[d] = epsilon[d];
|
||||||
}
|
}
|
||||||
finishInitialisation();
|
finishInitialisation();
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +149,7 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
multipliers = null;
|
multipliers = null;
|
||||||
rawData = null;
|
rawData = null;
|
||||||
totalObservations = 0;
|
totalObservations = 0;
|
||||||
epsilonInUse = new double[dimensions];
|
kernelWidthsInUse = new double[dimensions];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -172,11 +179,11 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
// it should expand with the standard deviation.
|
// it should expand with the standard deviation.
|
||||||
// This saves us from normalising all of the incoming data points!
|
// This saves us from normalising all of the incoming data points!
|
||||||
std = MatrixUtils.stdDev(data, d);
|
std = MatrixUtils.stdDev(data, d);
|
||||||
epsilonInUse[d] = epsilon[d] * std;
|
kernelWidthsInUse[d] = suppliedKernelWidths[d] * std;
|
||||||
} else {
|
} else {
|
||||||
epsilonInUse[d] = epsilon[d];
|
kernelWidthsInUse[d] = suppliedKernelWidths[d];
|
||||||
}
|
}
|
||||||
bins[d] = (int) Math.ceil((max - mins[d]) / epsilonInUse[d]);
|
bins[d] = (int) Math.ceil((max - mins[d]) / kernelWidthsInUse[d]);
|
||||||
if (bins[d] == 0) {
|
if (bins[d] == 0) {
|
||||||
// This means the min and max are exactly the same:
|
// This means the min and max are exactly the same:
|
||||||
// for our purposes this is akin to requiring one bin here.
|
// for our purposes this is akin to requiring one bin here.
|
||||||
|
|
@ -196,7 +203,7 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
System.out.println("Dim: " + d + " => Max: " + max + ", min: " + mins[d] +
|
System.out.println("Dim: " + d + " => Max: " + max + ", min: " + mins[d] +
|
||||||
", bins: " + bins[d] +
|
", bins: " + bins[d] +
|
||||||
(normalise ? ", std: " + std : "") +
|
(normalise ? ", std: " + std : "") +
|
||||||
", eps: " + epsilonInUse[d]);
|
", eps: " + kernelWidthsInUse[d]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -774,7 +781,7 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getBinIndex(double value, int dimension) {
|
private int getBinIndex(double value, int dimension) {
|
||||||
int bin = (int) Math.floor((value - mins[dimension]) / epsilonInUse[dimension]);
|
int bin = (int) Math.floor((value - mins[dimension]) / kernelWidthsInUse[dimension]);
|
||||||
// Check for any rounding errors on the bin assignment:
|
// Check for any rounding errors on the bin assignment:
|
||||||
if (bin >= bins[dimension]) {
|
if (bin >= bins[dimension]) {
|
||||||
bin = bins[dimension] - 1;
|
bin = bins[dimension] - 1;
|
||||||
|
|
@ -915,7 +922,7 @@ public class KernelEstimatorMultiVariate implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public int stepKernel(double[] observation, double[] candidate) {
|
public int stepKernel(double[] observation, double[] candidate) {
|
||||||
for (int d = 0; d < dimensions; d++) {
|
for (int d = 0; d < dimensions; d++) {
|
||||||
if (Math.abs(observation[d] - candidate[d]) > epsilonInUse[d]) {
|
if (Math.abs(observation[d] - candidate[d]) > kernelWidthsInUse[d]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,23 @@ import java.util.Vector;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to maintain probability distribution function for
|
* <p>Class to maintain probability distribution function for
|
||||||
* a single variable, using kernel estimates.
|
* a single variable, using kernel estimates.</p>
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* For more details on kernel estimation for computing probability distribution functions,
|
||||||
|
* see Kantz and Schreiber (below).
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Joseph Lizier
|
* @see "H. Kantz and T. Schreiber, 'Nonlinear Time Series Analysis'.
|
||||||
|
* Cambridge, MA: Cambridge University Press, 1997"
|
||||||
|
* @author Joseph Lizier, <a href="mailto:joseph.lizier at gmail.com">joseph.lizier at gmail.com</>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class KernelEstimatorSingleVariate {
|
public class KernelEstimatorSingleVariate {
|
||||||
|
|
||||||
private double epsilon = 0.1;
|
private double suppliedKernelWidth = 0.1;
|
||||||
private double epsilonInUse;
|
private double kernelWidthInUse;
|
||||||
private double min = 0;
|
private double min = 0;
|
||||||
private double max = 0;
|
private double max = 0;
|
||||||
private int bins = 0;
|
private int bins = 0;
|
||||||
|
|
@ -72,7 +78,7 @@ public class KernelEstimatorSingleVariate {
|
||||||
* @param epsilon
|
* @param epsilon
|
||||||
*/
|
*/
|
||||||
public void initialise(double epsilon) {
|
public void initialise(double epsilon) {
|
||||||
this.epsilon = epsilon;
|
this.suppliedKernelWidth = epsilon;
|
||||||
sortedObservations = null;
|
sortedObservations = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,14 +96,14 @@ public class KernelEstimatorSingleVariate {
|
||||||
// it should expand with the standard deviation.
|
// it should expand with the standard deviation.
|
||||||
// This saves us from normalising all of the incoming data points!
|
// This saves us from normalising all of the incoming data points!
|
||||||
double std = MatrixUtils.stdDev(data);
|
double std = MatrixUtils.stdDev(data);
|
||||||
epsilonInUse = epsilon * std;
|
kernelWidthInUse = suppliedKernelWidth * std;
|
||||||
} else {
|
} else {
|
||||||
epsilonInUse = epsilon;
|
kernelWidthInUse = suppliedKernelWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the bins
|
// Create the bins
|
||||||
Vector<TimeStampedObservation>[] observations = null;
|
Vector<TimeStampedObservation>[] observations = null;
|
||||||
bins = (int) Math.ceil((max - min) / epsilonInUse);
|
bins = (int) Math.ceil((max - min) / kernelWidthInUse);
|
||||||
if (bins == 0) {
|
if (bins == 0) {
|
||||||
// The max and min are the same.
|
// The max and min are the same.
|
||||||
// Should still have one bin here to put all the data in,
|
// Should still have one bin here to put all the data in,
|
||||||
|
|
@ -207,7 +213,7 @@ public class KernelEstimatorSingleVariate {
|
||||||
// are no longer within epsilon of the given value.
|
// are no longer within epsilon of the given value.
|
||||||
int topIndex;
|
int topIndex;
|
||||||
for (topIndex = sortedObservations[bin-1].length;
|
for (topIndex = sortedObservations[bin-1].length;
|
||||||
(topIndex > 0) && (sortedObservations[bin-1][topIndex-1].observation > observation - epsilonInUse);
|
(topIndex > 0) && (sortedObservations[bin-1][topIndex-1].observation > observation - kernelWidthInUse);
|
||||||
topIndex--) {
|
topIndex--) {
|
||||||
// This observation is within epsilon.
|
// This observation is within epsilon.
|
||||||
// Before adding to the count just check if it's a dynamic correlation if required:
|
// Before adding to the count just check if it's a dynamic correlation if required:
|
||||||
|
|
@ -233,7 +239,7 @@ public class KernelEstimatorSingleVariate {
|
||||||
int bottomIndex;
|
int bottomIndex;
|
||||||
for (bottomIndex = 0;
|
for (bottomIndex = 0;
|
||||||
(bottomIndex < sortedObservations[bin+1].length) &&
|
(bottomIndex < sortedObservations[bin+1].length) &&
|
||||||
(sortedObservations[bin+1][bottomIndex].observation < observation + epsilonInUse);
|
(sortedObservations[bin+1][bottomIndex].observation < observation + kernelWidthInUse);
|
||||||
bottomIndex++) {
|
bottomIndex++) {
|
||||||
// This observation is within epsilon.
|
// This observation is within epsilon.
|
||||||
// Before adding to the count just check if it's a dynamic correlation if required:
|
// Before adding to the count just check if it's a dynamic correlation if required:
|
||||||
|
|
@ -256,7 +262,7 @@ public class KernelEstimatorSingleVariate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getBinIndex(double value) {
|
private int getBinIndex(double value) {
|
||||||
int bin = (int) Math.floor((value - min) / epsilonInUse);
|
int bin = (int) Math.floor((value - min) / kernelWidthInUse);
|
||||||
// Check for any rounding errors on the bin assignment:
|
// Check for any rounding errors on the bin assignment:
|
||||||
if (bin >= bins) {
|
if (bin >= bins) {
|
||||||
bin = bins - 1;
|
bin = bins - 1;
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,16 @@ import infodynamics.utils.MatrixUtils;
|
||||||
* function on the joint history.
|
* function on the joint history.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Joseph Lizier joseph.lizier at gmail.com
|
* @see KernelEstimatorMultiVariate
|
||||||
|
* @see "H. Kantz and T. Schreiber, 'Nonlinear Time Series Analysis'.
|
||||||
|
* Cambridge, MA: Cambridge University Press, 1997"
|
||||||
|
* @author Joseph Lizier, <a href="mailto:joseph.lizier at gmail.com">joseph.lizier at gmail.com</>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate {
|
public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate {
|
||||||
|
|
||||||
private double epsilonSource;
|
private double suppliedKernelWidthSource;
|
||||||
private double epsilonSourceInUse;
|
private double kernelWidthSourceInUse;
|
||||||
|
|
||||||
private double[] destNext;
|
private double[] destNext;
|
||||||
private double[] source;
|
private double[] source;
|
||||||
|
|
@ -42,13 +45,13 @@ public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate
|
||||||
|
|
||||||
public void initialise(int dimensions, double epsilon) {
|
public void initialise(int dimensions, double epsilon) {
|
||||||
super.initialise(dimensions, epsilon);
|
super.initialise(dimensions, epsilon);
|
||||||
this.epsilonSource = epsilon;
|
this.suppliedKernelWidthSource = epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialise(int dimensions, double epsilonDest,
|
public void initialise(int dimensions, double epsilonDest,
|
||||||
double epsilonSource) {
|
double epsilonSource) {
|
||||||
super.initialise(dimensions, epsilonDest);
|
super.initialise(dimensions, epsilonDest);
|
||||||
this.epsilonSource = epsilonSource;
|
this.suppliedKernelWidthSource = epsilonSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setObservations(double[][] destPastVectors,
|
public void setObservations(double[][] destPastVectors,
|
||||||
|
|
@ -61,9 +64,9 @@ public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate
|
||||||
|
|
||||||
if (normalise) {
|
if (normalise) {
|
||||||
double std = MatrixUtils.stdDev(source);
|
double std = MatrixUtils.stdDev(source);
|
||||||
epsilonSourceInUse = epsilonSource * std;
|
kernelWidthSourceInUse = suppliedKernelWidthSource * std;
|
||||||
} else {
|
} else {
|
||||||
epsilonSourceInUse = epsilonSource;
|
kernelWidthSourceInUse = suppliedKernelWidthSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
|
@ -107,7 +110,7 @@ public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEpsSource(double epsilonSource) {
|
public void setEpsSource(double epsilonSource) {
|
||||||
this.epsilonSource = epsilonSource;
|
this.suppliedKernelWidthSource = epsilonSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -118,13 +121,13 @@ public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate
|
||||||
*/
|
*/
|
||||||
protected void correlatedPointAddedCallback(int correlatedTimeStep) {
|
protected void correlatedPointAddedCallback(int correlatedTimeStep) {
|
||||||
boolean sourceMatches = false;
|
boolean sourceMatches = false;
|
||||||
if (Math.abs(sourceObs - source[correlatedTimeStep]) <= epsilonSourceInUse) {
|
if (Math.abs(sourceObs - source[correlatedTimeStep]) <= kernelWidthSourceInUse) {
|
||||||
countPastSource++;
|
countPastSource++;
|
||||||
sourceMatches = true;
|
sourceMatches = true;
|
||||||
}
|
}
|
||||||
// The epsilons across the destination variables should all be approximately
|
// The epsilons across the destination variables should all be approximately
|
||||||
// equal, so just use the first one.
|
// equal, so just use the first one.
|
||||||
if (Math.abs(destNextObs - destNext[correlatedTimeStep]) <= epsilonInUse[0]) {
|
if (Math.abs(destNextObs - destNext[correlatedTimeStep]) <= kernelWidthsInUse[0]) {
|
||||||
countNextPast++;
|
countNextPast++;
|
||||||
if (sourceMatches) {
|
if (sourceMatches) {
|
||||||
countNextPastSource++;
|
countNextPastSource++;
|
||||||
|
|
@ -139,13 +142,13 @@ public class KernelEstimatorTransferEntropy extends KernelEstimatorMultiVariate
|
||||||
*/
|
*/
|
||||||
protected void correlatedPointRemovedCallback(int removedCorrelatedTimeStep) {
|
protected void correlatedPointRemovedCallback(int removedCorrelatedTimeStep) {
|
||||||
boolean sourceMatches = false;
|
boolean sourceMatches = false;
|
||||||
if (Math.abs(sourceObs - source[removedCorrelatedTimeStep]) <= epsilonSourceInUse) {
|
if (Math.abs(sourceObs - source[removedCorrelatedTimeStep]) <= kernelWidthSourceInUse) {
|
||||||
countPastSource--;
|
countPastSource--;
|
||||||
sourceMatches = true;
|
sourceMatches = true;
|
||||||
}
|
}
|
||||||
// The epsilons across the destination variables should all be approximately
|
// The epsilons across the destination variables should all be approximately
|
||||||
// equal, so just use the first one.
|
// equal, so just use the first one.
|
||||||
if (Math.abs(destNextObs - destNext[removedCorrelatedTimeStep]) <= epsilonInUse[0]) {
|
if (Math.abs(destNextObs - destNext[removedCorrelatedTimeStep]) <= kernelWidthsInUse[0]) {
|
||||||
countNextPast--;
|
countNextPast--;
|
||||||
if (sourceMatches) {
|
if (sourceMatches) {
|
||||||
countNextPastSource--;
|
countNextPastSource--;
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,33 @@ package infodynamics.measures.continuous.kernel;
|
||||||
import infodynamics.utils.MatrixUtils;
|
import infodynamics.utils.MatrixUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Kernel estimator for use with the transfer entropy.</p>
|
* <p>Kernel estimator for use with the transfer entropy on
|
||||||
|
* multivariate source and destination.</p>
|
||||||
*
|
*
|
||||||
* <p>Extends KernelEstimatorMultiVariate, using the super class to manage the history of the destination
|
* <p>Extends KernelEstimatorMultiVariate, using the super class to manage the history of the destination
|
||||||
* variable, and adds the next state and source on top of this. Any calls to the super class methods will only
|
* variable, and adds the next state and source on top of this. Any calls to the super class methods will only
|
||||||
* function on the joint history.
|
* function on the joint history.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Joseph Lizier joseph.lizier at gmail.com
|
* @see KernelEstimatorMultiVariate
|
||||||
|
* @see KernelEstimatorTransferEntropy
|
||||||
|
* @see "H. Kantz and T. Schreiber, 'Nonlinear Time Series Analysis'.
|
||||||
|
* Cambridge, MA: Cambridge University Press, 1997"
|
||||||
|
* @author Joseph Lizier, <a href="mailto:joseph.lizier at gmail.com">joseph.lizier at gmail.com</>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorMultiVariate {
|
public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorMultiVariate {
|
||||||
|
|
||||||
private int sourceDimensions;
|
private int sourceDimensions;
|
||||||
private double[] epsilonSource;
|
private double[] suppliedKernelWidthSource;
|
||||||
private double[] epsilonSourceInUse;
|
private double[] kernelWidthSourceInUse;
|
||||||
|
|
||||||
// Keep a separate epsilon for the destination next state, just in case
|
// Keep a separate epsilon for the destination next state, just in case
|
||||||
// we're doing something funky and using different variables to track
|
// we're doing something funky and using different variables to track
|
||||||
// the destination's past and next state (e.g. in swarm analysis).
|
// the destination's past and next state (e.g. in swarm analysis).
|
||||||
private double epsilonDestNextFixed;
|
private double suppliedKernelWidthDestNextFixed;
|
||||||
private double[] epsilonDestNext;
|
private double[] suppliedKernelWidthDestNext;
|
||||||
private double[] epsilonDestNextInUse;
|
private double[] kernelWidthDestNextInUse;
|
||||||
|
|
||||||
private double[][] destNext;
|
private double[][] destNext;
|
||||||
private double[][] source;
|
private double[][] source;
|
||||||
|
|
@ -56,24 +61,24 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
double epsilonDest, double epsilonSource) {
|
double epsilonDest, double epsilonSource) {
|
||||||
super.initialise(destDimensionsWithPast, epsilonDest);
|
super.initialise(destDimensionsWithPast, epsilonDest);
|
||||||
this.sourceDimensions = sourceDimensions;
|
this.sourceDimensions = sourceDimensions;
|
||||||
this.epsilonSource = new double[sourceDimensions];
|
this.suppliedKernelWidthSource = new double[sourceDimensions];
|
||||||
for (int d = 0; d < sourceDimensions; d++) {
|
for (int d = 0; d < sourceDimensions; d++) {
|
||||||
this.epsilonSource[d] = epsilonSource;
|
this.suppliedKernelWidthSource[d] = epsilonSource;
|
||||||
}
|
}
|
||||||
epsilonSourceInUse = new double[sourceDimensions];
|
kernelWidthSourceInUse = new double[sourceDimensions];
|
||||||
// Track that we're using a fixed epsilon for destination next
|
// Track that we're using a fixed epsilon for destination next
|
||||||
epsilonDestNext = null;
|
suppliedKernelWidthDestNext = null;
|
||||||
epsilonDestNextFixed = epsilonDest;
|
suppliedKernelWidthDestNextFixed = epsilonDest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialise(double[] epsilonDest,
|
public void initialise(double[] epsilonDest,
|
||||||
double[] epsilonSource) {
|
double[] epsilonSource) {
|
||||||
super.initialise(epsilonDest);
|
super.initialise(epsilonDest);
|
||||||
this.epsilonSource = epsilonSource;
|
this.suppliedKernelWidthSource = epsilonSource;
|
||||||
epsilonSourceInUse = new double[sourceDimensions];
|
kernelWidthSourceInUse = new double[sourceDimensions];
|
||||||
// Assume that we are doing an ordinary TE computation (dest past
|
// Assume that we are doing an ordinary TE computation (dest past
|
||||||
// and next state are the same variable)
|
// and next state are the same variable)
|
||||||
epsilonDestNext = epsilonDest;
|
suppliedKernelWidthDestNext = epsilonDest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,11 +101,11 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
if (normalise) {
|
if (normalise) {
|
||||||
for (int d = 0; d < sourceDimensions; d++) {
|
for (int d = 0; d < sourceDimensions; d++) {
|
||||||
double std = MatrixUtils.stdDev(source, d);
|
double std = MatrixUtils.stdDev(source, d);
|
||||||
epsilonSourceInUse[d] = epsilonSource[d] * std;
|
kernelWidthSourceInUse[d] = suppliedKernelWidthSource[d] * std;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int d = 0; d < sourceDimensions; d++) {
|
for (int d = 0; d < sourceDimensions; d++) {
|
||||||
epsilonSourceInUse[d] = epsilonSource[d];
|
kernelWidthSourceInUse[d] = suppliedKernelWidthSource[d];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,22 +114,22 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
// we're doing something funky with different dest past and next
|
// we're doing something funky with different dest past and next
|
||||||
// state variables).
|
// state variables).
|
||||||
int destNextDimensions = destNext[0].length;
|
int destNextDimensions = destNext[0].length;
|
||||||
if (epsilonDestNext == null) {
|
if (suppliedKernelWidthDestNext == null) {
|
||||||
// We must be using a fixed epsilon
|
// We must be using a fixed epsilon
|
||||||
epsilonDestNext = new double[destNextDimensions];
|
suppliedKernelWidthDestNext = new double[destNextDimensions];
|
||||||
for (int d = 0; d < destNextDimensions; d++) {
|
for (int d = 0; d < destNextDimensions; d++) {
|
||||||
epsilonDestNext[d] = epsilonDestNextFixed;
|
suppliedKernelWidthDestNext[d] = suppliedKernelWidthDestNextFixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
epsilonDestNextInUse = new double[destNextDimensions];
|
kernelWidthDestNextInUse = new double[destNextDimensions];
|
||||||
if (normalise) {
|
if (normalise) {
|
||||||
for (int d = 0; d < destNextDimensions; d++) {
|
for (int d = 0; d < destNextDimensions; d++) {
|
||||||
double std = MatrixUtils.stdDev(destNext, d);
|
double std = MatrixUtils.stdDev(destNext, d);
|
||||||
epsilonDestNextInUse[d] = epsilonDestNext[d] * std;
|
kernelWidthDestNextInUse[d] = suppliedKernelWidthDestNext[d] * std;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int d = 0; d < destNextDimensions; d++) {
|
for (int d = 0; d < destNextDimensions; d++) {
|
||||||
epsilonDestNextInUse[d] = epsilonDestNext[d];
|
kernelWidthDestNextInUse[d] = suppliedKernelWidthDestNext[d];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +174,7 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEpsSource(double[] epsilonSource) {
|
public void setEpsSource(double[] epsilonSource) {
|
||||||
this.epsilonSource = epsilonSource;
|
this.suppliedKernelWidthSource = epsilonSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -180,7 +185,7 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
*/
|
*/
|
||||||
protected void correlatedPointAddedCallback(int correlatedTimeStep) {
|
protected void correlatedPointAddedCallback(int correlatedTimeStep) {
|
||||||
boolean sourceMatches = false;
|
boolean sourceMatches = false;
|
||||||
if (stepKernel(sourceObs, source[correlatedTimeStep], epsilonSourceInUse) > 0) {
|
if (stepKernel(sourceObs, source[correlatedTimeStep], kernelWidthSourceInUse) > 0) {
|
||||||
countPastSource++;
|
countPastSource++;
|
||||||
sourceMatches = true;
|
sourceMatches = true;
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +196,7 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
// is achieved simply by passing in epsilon, since
|
// is achieved simply by passing in epsilon, since
|
||||||
// stepKernel just uses the first dimensions elements
|
// stepKernel just uses the first dimensions elements
|
||||||
// of the widths argument).
|
// of the widths argument).
|
||||||
if (stepKernel(destNextObs, destNext[correlatedTimeStep], epsilonDestNextInUse) > 0) {
|
if (stepKernel(destNextObs, destNext[correlatedTimeStep], kernelWidthDestNextInUse) > 0) {
|
||||||
countNextPast++;
|
countNextPast++;
|
||||||
if (sourceMatches) {
|
if (sourceMatches) {
|
||||||
countNextPastSource++;
|
countNextPastSource++;
|
||||||
|
|
@ -206,7 +211,7 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
*/
|
*/
|
||||||
protected void correlatedPointRemovedCallback(int removedCorrelatedTimeStep) {
|
protected void correlatedPointRemovedCallback(int removedCorrelatedTimeStep) {
|
||||||
boolean sourceMatches = false;
|
boolean sourceMatches = false;
|
||||||
if (stepKernel(sourceObs, source[removedCorrelatedTimeStep], epsilonSourceInUse) > 0) {
|
if (stepKernel(sourceObs, source[removedCorrelatedTimeStep], kernelWidthSourceInUse) > 0) {
|
||||||
countPastSource--;
|
countPastSource--;
|
||||||
sourceMatches = true;
|
sourceMatches = true;
|
||||||
}
|
}
|
||||||
|
|
@ -217,7 +222,7 @@ public class KernelEstimatorTransferEntropyMultiVariate extends KernelEstimatorM
|
||||||
// is achieved simply by passing in epsilon, since
|
// is achieved simply by passing in epsilon, since
|
||||||
// stepKernel just uses the first dimensions elements
|
// stepKernel just uses the first dimensions elements
|
||||||
// of the widths argument).
|
// of the widths argument).
|
||||||
if (stepKernel(destNextObs, destNext[removedCorrelatedTimeStep], epsilonDestNextInUse) > 0) {
|
if (stepKernel(destNextObs, destNext[removedCorrelatedTimeStep], kernelWidthDestNextInUse) > 0) {
|
||||||
countNextPast--;
|
countNextPast--;
|
||||||
if (sourceMatches) {
|
if (sourceMatches) {
|
||||||
countNextPastSource--;
|
countNextPastSource--;
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKernel implements
|
||||||
double[][] obsForThisDiscValue = MatrixUtils.extractSelectedPointsMatchingCondition(
|
double[][] obsForThisDiscValue = MatrixUtils.extractSelectedPointsMatchingCondition(
|
||||||
continuousObservations, discreteObservations, i, discCounts[i]);
|
continuousObservations, discreteObservations, i, discCounts[i]);
|
||||||
// Set the kernel width for the relevant kernel estimator:
|
// Set the kernel width for the relevant kernel estimator:
|
||||||
mvkeForEachDiscrete[i].initialise(mvke.epsilonInUse);
|
mvkeForEachDiscrete[i].initialise(mvke.kernelWidthsInUse);
|
||||||
// Set these observations for the relevant kernel estimator:
|
// Set these observations for the relevant kernel estimator:
|
||||||
mvkeForEachDiscrete[i].setObservations(obsForThisDiscValue);
|
mvkeForEachDiscrete[i].setObservations(obsForThisDiscValue);
|
||||||
}
|
}
|
||||||
|
|
@ -599,6 +599,6 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKernel implements
|
||||||
*/
|
*/
|
||||||
public double[] getKernelWidthsInUse() {
|
public double[] getKernelWidthsInUse() {
|
||||||
// Return a copy so that the user can't mess with it
|
// Return a copy so that the user can't mess with it
|
||||||
return Arrays.copyOf(mvke.epsilonInUse, mvke.epsilonInUse.length);
|
return Arrays.copyOf(mvke.kernelWidthsInUse, mvke.kernelWidthsInUse.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue