diff --git a/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov.java b/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov.java index a4f23c5..1e5dcc5 100755 --- a/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov.java +++ b/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov.java @@ -19,6 +19,7 @@ package infodynamics.measures.continuous.kraskov; import java.util.Calendar; +import java.util.PriorityQueue; import infodynamics.measures.continuous.ConditionalMutualInfoCalculatorMultiVariate; import infodynamics.measures.continuous.ConditionalMutualInfoMultiVariateCommon; @@ -27,6 +28,7 @@ import infodynamics.utils.KdTree; import infodynamics.utils.MathsUtils; import infodynamics.utils.MatrixUtils; import infodynamics.utils.NearestNeighbourSearcher; +import infodynamics.utils.NeighbourNodeData; import infodynamics.utils.UnivariateNearestNeighbourSearcher; import infodynamics.utils.EmpiricalMeasurementDistribution; import infodynamics.utils.NativeUtils; @@ -910,4 +912,68 @@ public abstract class ConditionalMutualInfoCalculatorMultiVariateKraskov // public ConditionalMutualInfoCalculatorMultiVariateKraskov clone() { // return this; // } + + /** + * Debug method to return the k nearest neighbour distances that + * would be utilised for each sample point here. + * Note that this is specifically the max-norm across the three variables, which is used for each + * range search in algorithm 1 (although algorithm 2 would use the max distance + * for each variable within the kNNs in their separate range searches). + * + * @param startTimePoint + * @param numTimePoints + * @return + * @throws Exception + */ + public double[] kNNDistances(int startTimePoint, int numTimePoints) throws Exception { + double[] kNNdistances = new double[numTimePoints]; + + for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { + // Compute eps for this time step by + // finding the kth closest neighbour for point t: + PriorityQueue nnPQ = + kdTreeJoint.findKNearestNeighbours(k, t, dynCorrExclTime); + // First element in the PQ is the kth NN, + // and epsilon = kthNnData.distance + NeighbourNodeData kthNnData = nnPQ.poll(); + + kNNdistances[t - startTimePoint] = kthNnData.distance; + } + return kNNdistances; + } + + /** + * Debug method to return the k nearest neighbour distances that + * would be utilised in {@link #computeLocalUsingPreviousObservations(double[][], double[][], double[][])} + * for a cross conditional MI. + * Note that this is specifically the max-norm across the three variables, which is used for each + * range search in algorithm 1 (although algorithm 2 would use the max distance + * for each variable within the kNNs in their separate range searches). + * + * @param startTimePoint + * @param numTimePoints + * @param newVar1Observations + * @param newVar2Observations + * @return + * @throws Exception + */ + public double[] kNNDistancesForNewSamples(int startTimePoint, int numTimePoints, + double[][] newStates1, double[][] newStates2, double[][] newCondStates) throws Exception { + + double[] kNNdistances = new double[numTimePoints]; + + for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { + // Compute eps for this time step by + // finding the kth closest neighbour for the new sample: + PriorityQueue nnPQ = + kdTreeJoint.findKNearestNeighbours(k, + new double[][] {newStates1[t], newStates2[t], newCondStates[t]}); + // First element in the PQ is the kth NN, + // and epsilon = kthNnData.distance + NeighbourNodeData kthNnData = nnPQ.poll(); + + kNNdistances[t - startTimePoint] = kthNnData.distance; + } + return kNNdistances; + } } diff --git a/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov1.java b/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov1.java index dcb4320..0ef07ee 100755 --- a/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov1.java +++ b/java/source/infodynamics/measures/continuous/kraskov/ConditionalMutualInfoCalculatorMultiVariateKraskov1.java @@ -18,19 +18,13 @@ package infodynamics.measures.continuous.kraskov; -import java.util.Arrays; import java.util.Calendar; import java.util.PriorityQueue; import infodynamics.measures.continuous.ConditionalMutualInfoCalculatorMultiVariate; -import infodynamics.utils.EmpiricalMeasurementDistribution; -import infodynamics.utils.FirstIndexComparatorDouble; -import infodynamics.utils.KdTree; import infodynamics.utils.MathsUtils; import infodynamics.utils.MatrixUtils; -import infodynamics.utils.NearestNeighbourSearcher; import infodynamics.utils.NeighbourNodeData; -import infodynamics.utils.UnivariateNearestNeighbourSearcher; /** *

Computes the differential conditional mutual information of two multivariate @@ -340,7 +334,7 @@ public class ConditionalMutualInfoCalculatorMultiVariateKraskov1 for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { // Compute eps for this time step by - // finding the kth closest neighbour for point t: + // finding the kth closest neighbour for the new sample: long methodStartTime = Calendar.getInstance().getTimeInMillis(); PriorityQueue nnPQ = kdTreeJoint.findKNearestNeighbours(k, diff --git a/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov.java b/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov.java index 88bd932..5cc8e6d 100755 --- a/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov.java +++ b/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov.java @@ -1106,5 +1106,72 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov } return totalErrors; - } + } + + /** + * Debug method to return the k nearest neighbour distances that + * would be utilised for each sample point here. + * Note that this is specifically the max-norm across the two variables, which is used for both + * variables in the range searches in algorithm 1 (although algorithm 2 would use the max distance + * for each variable within the kNNs in their separate range searches). + * + * @param startTimePoint + * @param numTimePoints + * @return + * @throws Exception + */ + public double[] kNNDistances(int startTimePoint, int numTimePoints) throws Exception { + + double[] kNNdistances = new double[numTimePoints]; + + for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { + // Compute eps for this time step by + // finding the kth closest neighbour for point t: + PriorityQueue nnPQ = + kdTreeJoint.findKNearestNeighbours(k, t, dynCorrExclTime); + // First element in the PQ is the kth NN, + // and epsilon = kthNnData.distance + NeighbourNodeData kthNnData = nnPQ.poll(); + + kNNdistances[t - startTimePoint] = kthNnData.distance; + } + return kNNdistances; + } + + + /** + * Debug method to return the k nearest neighbour distances that + * would be utilised in {@link #computeLocalUsingPreviousObservations(double[][], double[][])} + * for a cross MI. + * Note that this is specifically the max-norm across the two variables, which is used for both + * variables in the range searches in algorithm 1 (although algorithm 2 would use the max distance + * for each variable within the kNNs in their separate range searches). + * + * @param startTimePoint + * @param numTimePoints + * @param newVar1Observations + * @param newVar2Observations + * @return + * @throws Exception + */ + public double[] kNNDistancesForNewSamples(int startTimePoint, int numTimePoints, + double[][] newVar1Observations, double[][] newVar2Observations) throws Exception { + + double[] kNNdistances = new double[numTimePoints]; + + for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { + // Compute eps for this time step by + // finding the kth closest neighbour for the new sample: + PriorityQueue nnPQ = + kdTreeJoint.findKNearestNeighbours(k, + new double[][] {newVar1Observations[t], newVar2Observations[t]}); + // First element in the PQ is the kth NN, + // and epsilon = kthNnData.distance + NeighbourNodeData kthNnData = nnPQ.poll(); + + kNNdistances[t - startTimePoint] = kthNnData.distance; + } + return kNNdistances; + } + } diff --git a/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov1.java b/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov1.java index c68040e..bdd86b5 100644 --- a/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov1.java +++ b/java/source/infodynamics/measures/continuous/kraskov/MutualInfoCalculatorMultiVariateKraskov1.java @@ -72,7 +72,7 @@ public class MutualInfoCalculatorMultiVariateKraskov1 double sumNx = 0; double sumNy = 0; double sum2xkNNDist = 0; - + for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { // Compute eps for this time step by // finding the kth closest neighbour for point t: @@ -196,7 +196,7 @@ public class MutualInfoCalculatorMultiVariateKraskov1 for (int t = startTimePoint; t < startTimePoint + numTimePoints; t++) { // Compute eps for this time step by - // finding the kth closest neighbour for point t: + // finding the kth closest neighbour for the new sample: PriorityQueue nnPQ = kdTreeJoint.findKNearestNeighbours(k, new double[][] {newVar1Observations[t], newVar2Observations[t]});