Adding method to compute kNN distances for KSG AIS estimator

This commit is contained in:
Joseph Lizier 2025-04-01 22:55:28 +11:00
parent 2ab3ec347c
commit 333a00fc07
2 changed files with 46 additions and 1 deletions

View File

@ -23,6 +23,7 @@ import java.util.Hashtable;
import infodynamics.measures.continuous.ActiveInfoStorageCalculator; import infodynamics.measures.continuous.ActiveInfoStorageCalculator;
import infodynamics.measures.continuous.ActiveInfoStorageCalculatorViaMutualInfo; import infodynamics.measures.continuous.ActiveInfoStorageCalculatorViaMutualInfo;
import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate; import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
import infodynamics.utils.MatrixUtils;
/** /**
* An Active Information Storage (AIS) calculator (implementing {@link ActiveInfoStorageCalculator}) * An Active Information Storage (AIS) calculator (implementing {@link ActiveInfoStorageCalculator})
@ -230,4 +231,48 @@ public class ActiveInfoStorageCalculatorKraskov
} }
} }
/**
* 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 target-targetPast 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 {
// Defer the call to the underlying KSG CMI estimator
return ((MutualInfoCalculatorMultiVariateKraskov) miCalc).kNNDistances(startTimePoint, numTimePoints);
}
/**
* Debug method to return the k nearest neighbour distances that
* would be utilised in {@link #computeLocalUsingPreviousObservations(double[])}
* for a cross AIS.
* Note that this is specifically the max-norm across the target-targetPast 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 newObservations
* @return
* @throws Exception
*/
public double[] kNNDistancesForNewSamples(int startTimePoint, int numTimePoints,
double[] newObservations) throws Exception {
if (newObservations.length - (k-1)*tau - 1 <= 0) {
// There are no observations to compute for here
throw new Exception("Not enough samples to embed");
}
double[][] newDestPastVectors =
MatrixUtils.makeDelayEmbeddingVector(newObservations, k, tau, (k-1)*tau, newObservations.length - (k-1)*tau - 1);
double[][] newDestNextVectors =
MatrixUtils.makeDelayEmbeddingVector(newObservations, 1, (k-1)*tau + 1, newObservations.length - (k-1)*tau - 1);
return ((MutualInfoCalculatorMultiVariateKraskov) miCalc).
kNNDistancesForNewSamples(startTimePoint, numTimePoints, newDestPastVectors, newDestNextVectors);
}
} }

View File

@ -292,7 +292,7 @@ public class TransferEntropyCalculatorKraskov
} }
if (newDestObservations.length < startTimeForFirstDestEmbedding + 2) { if (newDestObservations.length < startTimeForFirstDestEmbedding + 2) {
// There are no observations to compute for here // There are no observations to compute for here
return new double[newDestObservations.length]; throw new Exception("Not enough samples to embed");
} }
// Now embed as per computeLocalUsingPreviousObservations() in super: // Now embed as per computeLocalUsingPreviousObservations() in super:
double[][] newDestPastVectors = double[][] newDestPastVectors =