mirror of https://github.com/jlizier/jidt
Added classes for joint entropy and multivariate mutual information calculation with gaussian assumption.
Restructured MeasurementDistribution to have child classes EmpiricalMeasurementDistribution and AnalyticMeasurementDistribution - this resulted in many classes being altered. Added ChiSquare distribution methods to MathsUtils. Added more covariance methods to MatrixUtils.
This commit is contained in:
parent
6af2a5b0a1
commit
9a86ee8152
|
@ -1,6 +1,6 @@
|
|||
package infodynamics.measures.continuous;
|
||||
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
public interface ActiveInfoStorageCalculator {
|
||||
|
||||
|
@ -77,9 +77,9 @@ public interface ActiveInfoStorageCalculator {
|
|||
|
||||
public double[] computeLocalOfPreviousObservations() throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception;
|
||||
|
||||
public void setDebug(boolean debug);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package infodynamics.measures.continuous;
|
||||
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* An abstract interface for calculators computing measures from a source to a destination.
|
||||
|
@ -51,7 +51,7 @@ public abstract interface ChannelCalculatorCommon {
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
|
||||
/**
|
||||
* <p>As per {@link computeSignificance(int) computeSignificance()} but supplies
|
||||
|
@ -64,7 +64,7 @@ public abstract interface ChannelCalculatorCommon {
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception;
|
||||
|
||||
public void setDebug(boolean debug);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package infodynamics.measures.continuous;
|
||||
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* A conditional mutual information calculator between a joint set of continuous variables,
|
||||
|
@ -31,9 +31,9 @@ public interface ConditionalMutualInfoCalculatorMultiVariateWithDiscrete {
|
|||
public double[] computeLocalUsingPreviousObservations(double[][] contStates,
|
||||
int[] discreteStates, int[] conditionedStates) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception;
|
||||
|
||||
public void setDebug(boolean debug);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package infodynamics.measures.continuous;
|
||||
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* A conditional mutual information calculator between a joint set of continuous variables,
|
||||
|
@ -32,9 +32,9 @@ public interface ConditionalMutualInfoCalculatorMultiVariateWithDiscreteSource {
|
|||
public double[] computeLocalUsingPreviousObservations(double[][] contStates,
|
||||
int[] discreteStates, double[][] conditionedStates) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception;
|
||||
|
||||
public void setDebug(boolean debug);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package infodynamics.measures.continuous;
|
||||
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
public interface MutualInfoCalculatorMultiVariateWithDiscrete {
|
||||
|
||||
|
@ -15,9 +15,9 @@ public interface MutualInfoCalculatorMultiVariateWithDiscrete {
|
|||
|
||||
public double[] computeLocalUsingPreviousObservations(double[][] contStates, int[] discreteStates) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception;
|
||||
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception;
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception;
|
||||
|
||||
public void setDebug(boolean debug);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package infodynamics.measures.continuous.kernel;
|
|||
|
||||
import infodynamics.measures.continuous.ActiveInfoStorageCalculator;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -207,7 +207,7 @@ public class ActiveInfoStorageCalculatorKernel
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
return miKernel.computeSignificance(numPermutationsToCheck);
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public class ActiveInfoStorageCalculatorKernel
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
|
||||
return miKernel.computeSignificance(newOrderings);
|
||||
|
|
|
@ -2,7 +2,7 @@ package infodynamics.measures.continuous.kernel;
|
|||
|
||||
import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
public class MutualInfoCalculatorMultiVariateKernel implements
|
||||
|
@ -187,7 +187,7 @@ public class MutualInfoCalculatorMultiVariateKernel implements
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(observations1.length, numPermutationsToCheck);
|
||||
|
@ -206,7 +206,7 @@ public class MutualInfoCalculatorMultiVariateKernel implements
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
@ -217,7 +217,7 @@ public class MutualInfoCalculatorMultiVariateKernel implements
|
|||
double[][] originalData2 = observations2;
|
||||
double[][] data2;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Arrays;
|
|||
|
||||
import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariateWithDiscrete;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
public class MutualInfoCalculatorMultiVariateWithDiscreteKernel implements
|
||||
|
@ -219,7 +219,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKernel implements
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(contObservations.length, numPermutationsToCheck);
|
||||
|
@ -238,7 +238,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKernel implements
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
@ -247,7 +247,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKernel implements
|
|||
double actualMI = lastAverage;
|
||||
int[] originalDiscrete = discObservations;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import infodynamics.measures.continuous.TransferEntropyCommon;
|
|||
import infodynamics.measures.continuous.kernel.TransferEntropyKernelCounts;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
@ -379,7 +379,7 @@ public class TransferEntropyCalculatorKernel
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
|
@ -397,7 +397,7 @@ public class TransferEntropyCalculatorKernel
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
|
@ -408,7 +408,7 @@ public class TransferEntropyCalculatorKernel
|
|||
double[] oldSourceValues = sourceValues;
|
||||
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the source in the destPastSourceVectors
|
||||
// and destNextPastSourceVectors vectors
|
||||
|
|
|
@ -4,7 +4,7 @@ import infodynamics.measures.continuous.TransferEntropyCalculator;
|
|||
import infodynamics.measures.continuous.TransferEntropyCommon;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -420,12 +420,12 @@ public class TransferEntropyCalculatorKernelPlain
|
|||
return true;
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
throw new RuntimeException("Not implemented in this calculator");
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
throw new RuntimeException("Not implemented in this calculator");
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package infodynamics.measures.continuous.kernel;
|
|||
import infodynamics.measures.continuous.TransferEntropyCalculator;
|
||||
import infodynamics.measures.continuous.TransferEntropyCommon;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -426,12 +426,12 @@ public class TransferEntropyCalculatorKernelPlainIterators
|
|||
return true;
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
throw new RuntimeException("Not implemented in this calculator");
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
throw new RuntimeException("Not implemented in this calculator");
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import infodynamics.measures.continuous.TransferEntropyCommon;
|
|||
import infodynamics.measures.continuous.kernel.KernelEstimatorMultiVariate;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
@ -531,7 +531,7 @@ public class TransferEntropyCalculatorKernelSeparate
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
|
@ -549,7 +549,7 @@ public class TransferEntropyCalculatorKernelSeparate
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
|
@ -560,7 +560,7 @@ public class TransferEntropyCalculatorKernelSeparate
|
|||
double[] originalSourceValuesInJoint = MatrixUtils.selectColumn(destPastSourceVectors, k);
|
||||
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Check that the length of the reorderings is OK
|
||||
if (newOrderings[p].length != totalObservations) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import infodynamics.measures.continuous.TransferEntropyCommon;
|
|||
import infodynamics.measures.continuous.kernel.TransferEntropyKernelCounts;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
@ -578,7 +578,7 @@ public class TransferEntropyCalculatorMultiVariateKernel
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
|
@ -596,7 +596,7 @@ public class TransferEntropyCalculatorMultiVariateKernel
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
|
@ -607,7 +607,7 @@ public class TransferEntropyCalculatorMultiVariateKernel
|
|||
double[][] oldSourceValues = sourceVectors;
|
||||
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the source in the destPastSourceVectors
|
||||
// and destNextPastSourceVectors vectors
|
||||
|
|
|
@ -2,7 +2,7 @@ package infodynamics.measures.continuous.kraskov;
|
|||
|
||||
import infodynamics.utils.EuclideanUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
|
@ -174,7 +174,7 @@ public abstract class ConditionalMutualInfoCalculatorMultiVariateKraskov {
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(data1.length, numPermutationsToCheck);
|
||||
|
@ -193,7 +193,7 @@ public abstract class ConditionalMutualInfoCalculatorMultiVariateKraskov {
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of conditional MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!condMiComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
@ -201,7 +201,7 @@ public abstract class ConditionalMutualInfoCalculatorMultiVariateKraskov {
|
|||
// Store the real observations and their MI:
|
||||
double actualMI = condMi;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import infodynamics.measures.continuous.ConditionalMutualInfoCalculatorMultiVari
|
|||
import infodynamics.utils.EuclideanUtils;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
|
@ -487,7 +487,7 @@ public class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteKraskov impl
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(continuousDataX.length, numPermutationsToCheck);
|
||||
|
@ -506,7 +506,7 @@ public class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteKraskov impl
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
|
@ -515,7 +515,7 @@ public class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteKraskov impl
|
|||
// Store the real observations and their MI:
|
||||
double actualMI = condMi;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -2,7 +2,7 @@ package infodynamics.measures.continuous.kraskov;
|
|||
|
||||
import infodynamics.measures.continuous.MultiInfoCalculator;
|
||||
import infodynamics.utils.EuclideanUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Vector;
|
||||
|
@ -184,7 +184,7 @@ public abstract class MultiInfoCalculatorKraskov implements
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][][] newOrderings = new int[numPermutationsToCheck][][];
|
||||
|
@ -209,7 +209,7 @@ public abstract class MultiInfoCalculatorKraskov implements
|
|||
* third index is the reordered variable number for that position.
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][][] newOrderings) throws Exception {
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
@ -217,7 +217,7 @@ public abstract class MultiInfoCalculatorKraskov implements
|
|||
// Store the real observations and their MI:
|
||||
double actualMI = mi;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package infodynamics.measures.continuous.kraskov;
|
|||
import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
|
||||
import infodynamics.utils.EuclideanUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
|
@ -175,7 +175,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov implements
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(data1.length, numPermutationsToCheck);
|
||||
|
@ -194,7 +194,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov implements
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
@ -202,7 +202,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov implements
|
|||
// Store the real observations and their MI:
|
||||
double actualMI = mi;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -2,7 +2,7 @@ package infodynamics.measures.continuous.kraskov;
|
|||
|
||||
import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
@ -262,7 +262,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskovByMulti implements
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(data1.length, numPermutationsToCheck);
|
||||
|
@ -281,7 +281,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskovByMulti implements
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
@ -289,7 +289,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskovByMulti implements
|
|||
// Store the real observations and their MI:
|
||||
double actualMI = mi;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariateWithDisc
|
|||
import infodynamics.utils.EuclideanUtils;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
|
@ -361,7 +361,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKraskov implements Mutu
|
|||
* @param numPermutationsToCheck
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public synchronized MeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
public synchronized EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(continuousData.length, numPermutationsToCheck);
|
||||
|
@ -380,7 +380,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKraskov implements Mutu
|
|||
* @param newOrderings the specific new orderings to use
|
||||
* @return the proportion of MI scores from the distribution which have higher or equal MIs to ours.
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
if (!miComputed) {
|
||||
|
@ -389,7 +389,7 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteKraskov implements Mutu
|
|||
// Store the real observations and their MI:
|
||||
double actualMI = mi;
|
||||
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
||||
int countWhereMiIsMoreSignificantThanOriginal = 0;
|
||||
for (int i = 0; i < numPermutationsToCheck; i++) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
|
|||
import infodynamics.measures.continuous.TransferEntropyCalculator;
|
||||
import infodynamics.measures.continuous.TransferEntropyCommon;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
@ -351,7 +351,7 @@ public class TransferEntropyCalculatorKraskovByMulti
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
// Generate the re-ordered indices:
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
|
@ -373,7 +373,7 @@ public class TransferEntropyCalculatorKraskovByMulti
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
|
@ -381,7 +381,7 @@ public class TransferEntropyCalculatorKraskovByMulti
|
|||
double actualTE = computeAverageLocalOfObservations();
|
||||
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the source in the destPastSourceVectors
|
||||
// and destNextPastSourceVectors vectors
|
||||
|
@ -423,7 +423,7 @@ public class TransferEntropyCalculatorKraskovByMulti
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public MeasurementDistribution computeSignificanceExplicitlyReordering(
|
||||
public EmpiricalMeasurementDistribution computeSignificanceExplicitlyReordering(
|
||||
int[][] newOrderings) throws Exception {
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
|
@ -437,7 +437,7 @@ public class TransferEntropyCalculatorKraskovByMulti
|
|||
}
|
||||
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the source in the destPastSourceVectors
|
||||
// and destNextPastSourceVectors vectors
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
package infodynamics.measures.continuous.lineargaussian;
|
||||
|
||||
import infodynamics.measures.continuous.EntropyCalculatorMultiVariate;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* <p>Computes the differential entropy of a given multivariate set of observations,
|
||||
* assuming that the probability distribution function for these observations is
|
||||
* a multivariate Gaussian distribution.</p>
|
||||
*
|
||||
* <p>
|
||||
* Usage:
|
||||
* <ol>
|
||||
* <li>Construct</li>
|
||||
* <li>initialise()</li>
|
||||
* <li>setObservations(), or setCovariance().</li>
|
||||
* <li>computeAverageLocalOfObservations() to return the average differential
|
||||
* entropy based on either the set variance or the variance of
|
||||
* the supplied observations, or computeLocalUsingPrevious</li>
|
||||
* </ol>
|
||||
* </p>
|
||||
*
|
||||
* @see Differential entropy for Gaussian random variables defined at
|
||||
* {@link http://mathworld.wolfram.com/DifferentialEntropy.html}
|
||||
* @author Joseph Lizier joseph.lizier_at_gmail.com
|
||||
*
|
||||
*/
|
||||
public class EntropyCalculatorMultiVariateLinearGaussian implements EntropyCalculatorMultiVariate {
|
||||
|
||||
/**
|
||||
* Covariance matrix of the most recently supplied observations
|
||||
*/
|
||||
protected double[][] covariance;
|
||||
|
||||
/**
|
||||
* The set of observations, retained in case the user wants to retrieve the local
|
||||
* entropy values of these
|
||||
*/
|
||||
protected double[][] observations;
|
||||
|
||||
/**
|
||||
* Number of dimenions for our multivariate data
|
||||
*/
|
||||
protected int dimensions;
|
||||
|
||||
protected double lastAverage;
|
||||
|
||||
protected boolean debug;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public EntropyCalculatorMultiVariateLinearGaussian() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the calculator ready for reuse
|
||||
*/
|
||||
public void initialise(int dimensions) {
|
||||
covariance = null;
|
||||
observations = null;
|
||||
this.dimensions = dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the multivariate observations from which to compute the entropy
|
||||
*
|
||||
* @param observations the observations to compute the entropy from.
|
||||
* First index is time, second index is variable number.
|
||||
*/
|
||||
public void setObservations(double[][] observations) {
|
||||
this.observations = observations;
|
||||
covariance = MatrixUtils.covarianceMatrix(observations);
|
||||
// Check that the observations was of the correct number of dimensions:
|
||||
// (done afterwards since the covariance matrix computation checks that
|
||||
// all rows had the right number of columns
|
||||
if (covariance.length != dimensions) {
|
||||
throw new RuntimeException("Supplied observations does not match initialised number of dimensions");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the covariance of the distribution for which we will compute the
|
||||
* entropy.
|
||||
*
|
||||
* @param covariance covariance matrix
|
||||
*/
|
||||
public void setCovariance(double[][] covariance) throws Exception {
|
||||
observations = null;
|
||||
// Make sure the supplied covariance matrix is square:
|
||||
int rows = covariance.length;
|
||||
if (rows != dimensions) {
|
||||
throw new Exception("Supplied covariance matrix does not match initialised number of dimensions");
|
||||
}
|
||||
for (int r = 0; r < rows; r++) {
|
||||
if (covariance[r].length != rows) {
|
||||
throw new Exception("Cannot compute the determinant of a non-square matrix");
|
||||
}
|
||||
}
|
||||
|
||||
this.covariance = covariance;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The joint entropy for a multivariate Gaussian-distribution of dimension n
|
||||
* with covariance matrix C is 0.5*\log_e{(2*pi*e)^n*|det(C)|},
|
||||
* where det() is the matrix determinant of C.</p>
|
||||
*
|
||||
* <p>Here we compute the joint entropy assuming that the recorded estimation of the
|
||||
* covariance is correct (i.e. we will not make a bias correction for limited
|
||||
* observations here).</p>
|
||||
*
|
||||
* @return the joint entropy of the previously provided observations or from the
|
||||
* supplied covariance matrix.
|
||||
*/
|
||||
public double computeAverageLocalOfObservations() {
|
||||
try {
|
||||
lastAverage = 0.5 * (dimensions* (1 + Math.log(2.0*Math.PI)) +
|
||||
Math.log(Math.abs(MatrixUtils.determinant(covariance))));
|
||||
return lastAverage;
|
||||
} catch (Exception e) {
|
||||
// Should not happen, since we check the validity of the supplied
|
||||
// matrix beforehand; so we'll throw an Error in this case
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Set the given property to the given value.</p>
|
||||
*
|
||||
* <p>There are currently no properties to set for this calculator</p>
|
||||
*
|
||||
* @param propertyName name of the property
|
||||
* @param propertyValue value of the property.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void setProperty(String propertyName, String propertyValue)
|
||||
throws Exception {
|
||||
// No properties to set here
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastAverage
|
||||
*/
|
||||
public double getLastAverage() {
|
||||
return lastAverage;
|
||||
}
|
||||
|
||||
public double[] computeLocalUsingPreviousObservations(double[][] states)
|
||||
throws Exception {
|
||||
// TODO Implement me
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public double[] computeLocalOfPreviousObservations() {
|
||||
|
||||
// TODO Implement this function
|
||||
if (true)
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
|
||||
if (observations == null) {
|
||||
throw new RuntimeException("Cannot compute local values since no observations were supplied");
|
||||
}
|
||||
double[] localEntropy = new double[observations.length];
|
||||
for (int t=0; t < observations.length; t++) {
|
||||
// Compute the probability for the given observation, based on
|
||||
// the assumption of a multivariate Gaussian PDF:
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,307 @@
|
|||
package infodynamics.measures.continuous.lineargaussian;
|
||||
|
||||
import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
|
||||
import infodynamics.utils.ChiSquareMeasurementDistribution;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* <p>Computes the differential mutual information of two given multivariate sets of
|
||||
* observations,
|
||||
* assuming that the probability distribution function for these observations is
|
||||
* a multivariate Gaussian distribution.</p>
|
||||
*
|
||||
* <p>
|
||||
* Usage:
|
||||
* <ol>
|
||||
* <li>Construct {@link #MutualInfoCalculatorMultiVariateLinearGaussian()}</li>
|
||||
* <li>{@link #initialise(int, int)}</li>
|
||||
* <li>Provide the observations to the calculator using:
|
||||
* {@link #setObservations(double[][], double[][])}, or
|
||||
* {@link #setCovariance(double[][])}, or
|
||||
* a sequence of:
|
||||
* {@link #startAddObservations()},
|
||||
* multiple calls to either {@link #addObservations(double[][], double[][])}
|
||||
* or @{link {@link #addObservations(double[][], double[][], int, int)}, and then
|
||||
* @{link {@link #finaliseAddObservations()}.</li>
|
||||
* <li>Compute the required information-theoretic results, primarily:
|
||||
* @{link #computeAverageLocalOfObservations()} to return the average differential
|
||||
* entropy based on either the set variance or the variance of
|
||||
* the supplied observations; or other calls to compute
|
||||
* local values or statistical significance.</li>
|
||||
* </ol>
|
||||
* </p>
|
||||
*
|
||||
* @see Differential entropy for Gaussian random variables defined at
|
||||
* {@link http://mathworld.wolfram.com/DifferentialEntropy.html}
|
||||
* @author Joseph Lizier joseph.lizier_at_gmail.com
|
||||
*
|
||||
*/
|
||||
public class MutualInfoCalculatorMultiVariateLinearGaussian implements
|
||||
MutualInfoCalculatorMultiVariate {
|
||||
|
||||
/**
|
||||
* Covariance matrix of the most recently supplied observations
|
||||
*/
|
||||
protected double[][] covariance;
|
||||
|
||||
/**
|
||||
* The set of source observations, retained in case the user wants to retrieve the local
|
||||
* entropy values of these.
|
||||
* They're held in the order in which they were supplied in the
|
||||
* {@link addObservations(double[][], double[][])} functions.
|
||||
*/
|
||||
protected double[][] sourceObservations;
|
||||
|
||||
/**
|
||||
* The set of destination observations, retained in case the user wants to retrieve the local
|
||||
* entropy values of these.
|
||||
* They're held in the order in which they were supplied in the
|
||||
* {@link addObservations(double[][], double[][])} functions.
|
||||
*/
|
||||
protected double[][] destObservations;
|
||||
|
||||
/**
|
||||
* Number of dimenions for each of our multivariate data sets
|
||||
*/
|
||||
protected int dimensionsDest;
|
||||
protected int dimensionsSource;
|
||||
|
||||
protected double lastAverage;
|
||||
|
||||
protected boolean debug;
|
||||
|
||||
public MutualInfoCalculatorMultiVariateLinearGaussian() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any previously supplied probability distributions and prepare
|
||||
* the calculator to be used again.
|
||||
*
|
||||
* @param sourceDimensions number of joing variables in the source
|
||||
* @param destDimensions number of joing variables in the destination
|
||||
*/
|
||||
public void initialise(int sourceDimensions, int destDimensions) {
|
||||
covariance = null;
|
||||
sourceObservations = null;
|
||||
destObservations = null;
|
||||
dimensionsSource = sourceDimensions;
|
||||
dimensionsDest = destDimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the complete set of observations to use to compute the
|
||||
* mutual information.
|
||||
* One cannot use the {@link addObservations(double[][], double[][])}
|
||||
* style methods after this without calling initialise again first.
|
||||
*
|
||||
*/
|
||||
public void setObservations(double[][] source, double[][] destination)
|
||||
throws Exception {
|
||||
sourceObservations = source;
|
||||
destObservations = destination;
|
||||
covariance = MatrixUtils.covarianceMatrix(source, destination);
|
||||
// Check that the observations was of the correct number of dimensions:
|
||||
// (done afterwards since the covariance matrix computation checks that
|
||||
// all rows had the right number of columns
|
||||
if (covariance.length != dimensionsSource + dimensionsDest) {
|
||||
throw new RuntimeException("Supplied observations do not match initialised number of dimensions");
|
||||
}
|
||||
}
|
||||
|
||||
public void addObservations(double[][] source, double[][] destination)
|
||||
throws Exception {
|
||||
// TODO implement these addObservations style functions.
|
||||
// This will not be hard to implement - see the implementation
|
||||
// for TE in TransferEntropyCommon. It might be useful
|
||||
// to have a MutualInfoCommon which pulls the same functionality
|
||||
// together for the MI calculators anyway.
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public void addObservations(double[][] source, double[][] destination,
|
||||
int startTime, int numTimeSteps) throws Exception {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public void setObservations(double[][] source, double[][] destination,
|
||||
boolean[] sourceValid, boolean[] destValid) throws Exception {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public void setObservations(double[][] source, double[][] destination,
|
||||
boolean[][] sourceValid, boolean[][] destValid) throws Exception {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public void startAddObservations() {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public void finaliseAddObservations() {
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the covariance of the distribution for which we will compute the
|
||||
* mutual information.
|
||||
*
|
||||
* @param covariance covariance matrix of the source and destination
|
||||
* variables, considered together (variable indices start with the source
|
||||
* and continue into the destination).
|
||||
*/
|
||||
public void setCovariance(double[][] covariance) throws Exception {
|
||||
sourceObservations = null;
|
||||
destObservations = null;
|
||||
// Make sure the supplied covariance matrix is square:
|
||||
int rows = covariance.length;
|
||||
if (rows != dimensionsSource + dimensionsDest) {
|
||||
throw new Exception("Supplied covariance matrix does not match initialised number of dimensions");
|
||||
}
|
||||
for (int r = 0; r < rows; r++) {
|
||||
if (covariance[r].length != rows) {
|
||||
throw new Exception("Cannot compute the determinant of a non-square matrix");
|
||||
}
|
||||
}
|
||||
|
||||
this.covariance = covariance;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The joint entropy for a multivariate Gaussian-distribution of dimension n
|
||||
* with covariance matrix C is 0.5*\log_e{(2*pi*e)^n*|det(C)|},
|
||||
* where det() is the matrix determinant of C.</p>
|
||||
*
|
||||
* <p>Here we compute the mutual information from the joint entropies
|
||||
* of the source variables (H_s), destination variables (H_d), and all variables
|
||||
* taken together (H_sd), giving MI = H_s + H_d - H_sd.
|
||||
* We assume that the recorded estimation of the
|
||||
* covariance is correct (i.e. we will not make a bias correction for limited
|
||||
* observations here).</p>
|
||||
*
|
||||
* @return the mutual information of the previously provided observations or from the
|
||||
* supplied covariance matrix.
|
||||
*/
|
||||
public double computeAverageLocalOfObservations() throws Exception {
|
||||
try {
|
||||
int[] sourceIndicesInCovariance = MatrixUtils.range(0, dimensionsSource - 1);
|
||||
int[] destIndicesInCovariance = MatrixUtils.range(dimensionsSource,
|
||||
dimensionsSource + dimensionsDest - 1);
|
||||
double[][] sourceCovariance =
|
||||
MatrixUtils.selectRowsAndColumns(covariance,
|
||||
sourceIndicesInCovariance, sourceIndicesInCovariance);
|
||||
double[][] destCovariance =
|
||||
MatrixUtils.selectRowsAndColumns(covariance,
|
||||
destIndicesInCovariance, destIndicesInCovariance);
|
||||
double sourceEntropy = 0.5 *
|
||||
Math.log(Math.abs(MatrixUtils.determinant(sourceCovariance)));
|
||||
double destEntropy = 0.5 *
|
||||
Math.log(Math.abs(MatrixUtils.determinant(destCovariance)));
|
||||
double jointEntropy = 0.5 *
|
||||
Math.log(Math.abs(MatrixUtils.determinant(covariance)));
|
||||
lastAverage = sourceEntropy + destEntropy - jointEntropy;
|
||||
return lastAverage;
|
||||
} catch (Exception e) {
|
||||
// Should not happen, since we check the validity of the supplied
|
||||
// matrix beforehand; so we'll throw an Error in this case
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public double[] computeLocalOfPreviousObservations() throws Exception {
|
||||
// TODO Implement me
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Compute the statistical significance of the mutual information
|
||||
* result analytically, without creating a distribution
|
||||
* under the null hypothesis by bootstrapping.</p>
|
||||
*
|
||||
* <p>Brillinger (see reference below) shows that under the null hypothesis
|
||||
* of no source-destination relationship, the MI for two
|
||||
* Gaussian distributions follows a chi-square distribution with
|
||||
* degrees of freedom equal to the product of the number of variables
|
||||
* in each joint variable.</p>
|
||||
*
|
||||
* @return MeasurementDistribution object with only the
|
||||
* {@link EmpiricalMeasurementDistribution#actualValue} and
|
||||
* {@link EmpiricalMeasurementDistribution#pValue} fields filled out.
|
||||
* This object contains the proportion of MI scores from the distribution
|
||||
* which have higher or equal MIs to ours.
|
||||
*
|
||||
* @see Brillinger, "Some data analyses using mutual information",
|
||||
* {@link http://www.stat.berkeley.edu/~brill/Papers/MIBJPS.pdf}
|
||||
* @see Cheng et al., "Data Information in Contingency Tables: A
|
||||
* Fallacy of Hierarchical Loglinear Models",
|
||||
* {@link http://www.jds-online.com/file_download/112/JDS-369.pdf}
|
||||
* @see Barnett and Bossomaier, "Transfer Entropy as a Log-likelihood Ratio"
|
||||
* {@link http://arxiv.org/abs/1205.6339}
|
||||
*/
|
||||
public ChiSquareMeasurementDistribution computeSignificance() {
|
||||
// TODO Check that the null distribution actually follows chi with
|
||||
// these degrees of freedom
|
||||
return new ChiSquareMeasurementDistribution(lastAverage,
|
||||
dimensionsSource * dimensionsDest);
|
||||
}
|
||||
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
// TODO Implement me
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
throws Exception {
|
||||
// TODO Implement me
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Set the given property to the given value.</p>
|
||||
*
|
||||
* <p>There are currently no properties to set for this calculator</p>
|
||||
*
|
||||
* @param propertyName name of the property
|
||||
* @param propertyValue value of the property.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void setProperty(String propertyName, String propertyValue)
|
||||
throws Exception {
|
||||
// No properties to set here
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the previously computed average mutual information
|
||||
*/
|
||||
public double getLastAverage() {
|
||||
return lastAverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of previously supplied observations for which
|
||||
* the mutual information will be / was computed.
|
||||
*/
|
||||
public int getNumObservations() {
|
||||
return destObservations.length;
|
||||
}
|
||||
|
||||
public double computeAverageLocalOfObservations(int[] newOrdering)
|
||||
throws Exception {
|
||||
// TODO Implement me
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public double[] computeLocalUsingPreviousObservations(double[][] states1,
|
||||
double[][] states2) throws Exception {
|
||||
// TODO Implement me
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@ import infodynamics.measures.discrete.ConditionalMutualInformationCalculator;
|
|||
import infodynamics.utils.FirstIndexComparatorDouble;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
public class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteSymbolic implements
|
||||
|
@ -131,12 +131,12 @@ public class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteSymbolic imp
|
|||
throw new Exception("Local method not implemented yet");
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
return condMiCalc.computeSignificance(numPermutationsToCheck);
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
throws Exception {
|
||||
return condMiCalc.computeSignificance(newOrderings);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import infodynamics.measures.discrete.MutualInformationCalculator;
|
|||
import infodynamics.utils.FirstIndexComparatorDouble;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
public class MutualInfoCalculatorMultiVariateWithDiscreteSymbolic implements
|
||||
|
@ -139,12 +139,12 @@ public class MutualInfoCalculatorMultiVariateWithDiscreteSymbolic implements
|
|||
throw new Exception("Local method not implemented yet");
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
return miCalc.computeSignificance(numPermutationsToCheck);
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
throws Exception {
|
||||
return miCalc.computeSignificance(newOrderings);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import infodynamics.measures.discrete.ApparentTransferEntropyCalculator;
|
|||
import infodynamics.utils.FirstIndexComparatorDouble;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
@ -300,7 +300,7 @@ public class TransferEntropyCalculatorSymbolic
|
|||
return locals;
|
||||
}
|
||||
|
||||
public MeasurementDistribution computeSignificance(
|
||||
public EmpiricalMeasurementDistribution computeSignificance(
|
||||
int numPermutationsToCheck) throws Exception {
|
||||
return teCalc.computeSignificance(numPermutationsToCheck);
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ public class TransferEntropyCalculatorSymbolic
|
|||
* which is not strictly what this method is meant to do.
|
||||
*
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings)
|
||||
throws Exception {
|
||||
System.out.println("TESymbolic.computeSignificance(): Not using the new orderings supplied");
|
||||
return teCalc.computeSignificance(newOrderings.length);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
|
@ -653,7 +653,7 @@ public class ApparentTransferEntropyCalculator extends ContextOfPastMeasureCalcu
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
double actualTE = computeAverageLocalOfObservations();
|
||||
|
||||
// Reconstruct the source values (not necessarily in order)
|
||||
|
@ -698,7 +698,7 @@ public class ApparentTransferEntropyCalculator extends ContextOfPastMeasureCalcu
|
|||
ate2.pastCount = pastCount;
|
||||
ate2.nextPastCount = nextPastCount;
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the source
|
||||
int[] newSourceData = MatrixUtils.extractSelectedTimePoints(sourceValues, newOrderings[p]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* An interface for calculators computing measures from a source to a destination.
|
||||
|
@ -47,5 +47,5 @@ public interface ChannelCalculator {
|
|||
* @param numPermutationsToCheck
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck);
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package infodynamics.measures.discrete;
|
|||
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
|
||||
|
@ -342,7 +342,7 @@ public class CompleteTransferEntropyCalculator extends InfoMeasureCalculator {
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
double actualTE = computeAverageLocalOfObservations();
|
||||
|
||||
// Reconstruct the source values (not necessarily in order)
|
||||
|
@ -400,7 +400,7 @@ public class CompleteTransferEntropyCalculator extends InfoMeasureCalculator {
|
|||
cte.pastOthersCount = pastOthersCount;
|
||||
cte.destPastOthersCount = destPastOthersCount;
|
||||
int countWhereTeIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the source
|
||||
int[] newSourceData = MatrixUtils.extractSelectedTimePoints(sourceValues, newOrderings[p]);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
|
||||
|
@ -185,7 +185,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
int[][] newOrderings = rg.generateDistinctRandomPerturbations(observations, numPermutationsToCheck);
|
||||
return computeSignificance(newOrderings);
|
||||
|
@ -197,7 +197,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
* @param newOrderings the reorderings to use
|
||||
* @return
|
||||
*/
|
||||
public MeasurementDistribution computeSignificance(int[][] newOrderings) {
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) {
|
||||
double actualMI = computeAverageLocalOfObservations();
|
||||
|
||||
int numPermutationsToCheck = newOrderings.length;
|
||||
|
@ -222,7 +222,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
mi2.iCount = iCount;
|
||||
mi2.jCount = jCount;
|
||||
int countWhereMIIsMoreSignificantThanOriginal = 0;
|
||||
MeasurementDistribution measDistribution = new MeasurementDistribution(numPermutationsToCheck);
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
for (int p = 0; p < numPermutationsToCheck; p++) {
|
||||
// Generate a new re-ordered data set for the i variable
|
||||
int[] newDataI = MatrixUtils.extractSelectedTimePoints(iValues, newOrderings[p]);
|
||||
|
|
|
@ -5,7 +5,7 @@ import infodynamics.measures.continuous.MutualInfoCalculatorMultiVariate;
|
|||
import infodynamics.measures.continuous.TransferEntropyCalculatorMultiVariate;
|
||||
import infodynamics.utils.ArrayFileReader;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.ParsedProperties;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
|
@ -455,7 +455,7 @@ public abstract class InterregionalChannelMeasure {
|
|||
// Compute the measure for set s
|
||||
measureForEachSet[s] = channelCalc.computeAverageLocalOfObservations();
|
||||
|
||||
MeasurementDistribution measDist;
|
||||
EmpiricalMeasurementDistribution measDist;
|
||||
if (allValid || !validityForIndividualElements) {
|
||||
// Ask the TE calculator to work out the significance for us
|
||||
measDist = channelCalc.computeSignificance(reorderings);
|
||||
|
@ -463,7 +463,7 @@ public abstract class InterregionalChannelMeasure {
|
|||
// We need to explicitly reorder including the individual validities.
|
||||
// Can't ask the calculator to do it, as it will only use the source-dest
|
||||
// pairings it originally used, which won't match across all subsets
|
||||
measDist = new MeasurementDistribution(reorderingsForSignificance);
|
||||
measDist = new EmpiricalMeasurementDistribution(reorderingsForSignificance);
|
||||
measDist.actualValue = measureForEachSet[s];
|
||||
int countWhereReorderedIsMoreSignificantThanOriginal = 0;
|
||||
for (int p = 0; p < reorderingsForSignificance; p++) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
package infodynamics.networkinference.interregional;
|
||||
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.MeasurementDistribution;
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* Extends MeasurementDistribution for computations over
|
||||
|
@ -17,7 +17,7 @@ import infodynamics.utils.MeasurementDistribution;
|
|||
* @author Joseph Lizier
|
||||
*
|
||||
*/
|
||||
public class MeasurementDistributionPermutationsOverSubsets extends MeasurementDistribution {
|
||||
public class MeasurementDistributionPermutationsOverSubsets extends EmpiricalMeasurementDistribution {
|
||||
|
||||
// The true measurements for each subset s
|
||||
double[] actualValues;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package infodynamics.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure to hold a distribution of info-theoretic measurements,
|
||||
* and a significance value for how an original measurement compared
|
||||
* with these.
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
*/
|
||||
public class EmpiricalMeasurementDistribution extends MeasurementDistribution {
|
||||
|
||||
/**
|
||||
* Distribution of surrogate measurement values
|
||||
*/
|
||||
public double[] distribution;
|
||||
/**
|
||||
* Whether the mean of the surrogate measurement distribution has
|
||||
* been computed
|
||||
*/
|
||||
protected boolean computedMean = false;
|
||||
/**
|
||||
* Computed mean of the surrogate measurement distribution
|
||||
*/
|
||||
protected double meanOfDist;
|
||||
/**
|
||||
* Computed mean of the surrogate measurement distribution
|
||||
*/
|
||||
protected double stdOfDist;
|
||||
|
||||
public EmpiricalMeasurementDistribution(int size) {
|
||||
super(); // Creating the super class with mean and pValue 0
|
||||
// These value will be filled out by the caller later.
|
||||
distribution = new double[size];
|
||||
}
|
||||
|
||||
public EmpiricalMeasurementDistribution(double[] distribution, double actualValue) {
|
||||
super(actualValue, 0); // Using pValue = 0 temporarily ...
|
||||
this.distribution = distribution;
|
||||
int countWhereActualIsNotGreater = 0;
|
||||
for (int i = 0; i < distribution.length; i++) {
|
||||
if (distribution[i] >= actualValue) {
|
||||
countWhereActualIsNotGreater++;
|
||||
}
|
||||
}
|
||||
pValue = (double) countWhereActualIsNotGreater / (double) distribution.length;
|
||||
}
|
||||
|
||||
// TODO Compute the significance under the assumption of a Gaussian distribution
|
||||
/*
|
||||
public double computeGaussianSignificance() {
|
||||
// Need to conpute the significance based on the assumption of
|
||||
// an underlying Gaussian distribution.
|
||||
// Use the t distribution for analysis, since we have a finite
|
||||
// number of samples to comptue the mean and std from.
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
public double getTSscore() {
|
||||
if (! computedMean) {
|
||||
meanOfDist = MatrixUtils.mean(distribution);
|
||||
stdOfDist = MatrixUtils.stdDev(distribution, meanOfDist);
|
||||
computedMean = true;
|
||||
}
|
||||
double t = (actualValue - meanOfDist) / stdOfDist;
|
||||
return t;
|
||||
}
|
||||
|
||||
public double getMeanOfDistribution() {
|
||||
if (! computedMean) {
|
||||
meanOfDist = MatrixUtils.mean(distribution);
|
||||
stdOfDist = MatrixUtils.stdDev(distribution, meanOfDist);
|
||||
computedMean = true;
|
||||
}
|
||||
return meanOfDist;
|
||||
}
|
||||
|
||||
public double getStdOfDistribution() {
|
||||
if (! computedMean) {
|
||||
meanOfDist = MatrixUtils.mean(distribution);
|
||||
stdOfDist = MatrixUtils.stdDev(distribution, meanOfDist);
|
||||
computedMean = true;
|
||||
}
|
||||
return stdOfDist;
|
||||
}
|
||||
}
|
|
@ -281,6 +281,98 @@ public class MathsUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the value of the cummulative distribution function of the
|
||||
* chi-square distribution, evaluated at x, for k degrees of freedom.</p>
|
||||
*
|
||||
* <p>Note that this relies on our approximation of the error function,
|
||||
* which is the limiting part of the accuracy. Testing against
|
||||
* values produced by octave indicates this is accurate to 5-6
|
||||
* decimal places.</p>
|
||||
*
|
||||
* @param x value at which to evaluate the CDF
|
||||
* @param k degrees of freedom (must have k>0)
|
||||
* @return chi squared CDF evaluated at x given k degrees of freedom
|
||||
* @see {@link http://en.wikipedia.org/wiki/Chi-squared_distribution}
|
||||
*/
|
||||
public static double chiSquareCdf(double x, int k) {
|
||||
if (k <= 0) {
|
||||
throw new IllegalArgumentException("k (" + k + ") must be > 0");
|
||||
}
|
||||
return lowerIncompleteGammaFunctionOfArgsOn2(k,x) /
|
||||
gammaOfArgOn2Plus1(k-2); // denominator is Gamma(k/2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the lower Incomplete Gamma function,
|
||||
* given arguments s/2 and x/2.
|
||||
* We assume postive integer parameter s (s could be complex in general,
|
||||
* with positive real part, but we restrict it to real and integer for
|
||||
* this method). We make the evaluation using a recurrence relation,
|
||||
* which terminates at s/2 = 1 or 1/2 (i.e. s = 2 or 1)
|
||||
*
|
||||
* @param s for parameter s/2 to lower incomplete gamma
|
||||
* @param x for value x/2 to lower incomplete gamma
|
||||
* @return value of lower gamma incomplete function
|
||||
* @see {@link http://en.wikipedia.org/wiki/Incomplete_Gamma_function}
|
||||
*/
|
||||
public static double lowerIncompleteGammaFunctionOfArgsOn2(int s, double x) {
|
||||
if (s <= 0) {
|
||||
throw new IllegalArgumentException("s must be > 0");
|
||||
}
|
||||
if (s == 2) {
|
||||
// Terminating condition: evaluate lower gamma(1, x/2):
|
||||
return 1 - Math.exp(-x/2.0);
|
||||
} else if (s == 1) {
|
||||
// Terminating condition: evaluate lower gamma(1/2, x/2):
|
||||
return Math.sqrt(Math.PI) * erf(Math.sqrt(x/2.0));
|
||||
} else {
|
||||
// Else evaluate recurrence relation:
|
||||
return (s/2.0-1.0)*lowerIncompleteGammaFunctionOfArgsOn2(s-2,x) -
|
||||
Math.pow(x/2.0, s/2.0 - 1.0) * Math.exp(-x/2.0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the error function at a given x.
|
||||
* We approximate the error function using elementary functions
|
||||
* as described at the link below (quoting Abramowitz and Stegun).
|
||||
* This approximation is quoted to
|
||||
* have maximum error 1.5e-7 (and indeed this appears to be the
|
||||
* case in comparison to values produced by octave).
|
||||
*
|
||||
* @param x value at which to evaluate the error function
|
||||
* @return erf(x)
|
||||
* @see {@link http://en.wikipedia.org/wiki/Error_function#Approximation_with_elementary_functions}
|
||||
* @see Abramowitz, Milton; Stegun, Irene A., eds. (1972),
|
||||
* "Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables",
|
||||
* New York: Dover Publications, ISBN 978-0-486-61272-0
|
||||
*/
|
||||
public static double erf(double x) {
|
||||
// Constants:
|
||||
double p = 0.3275911;
|
||||
double[] a = {0.254829592, -0.284496736, 1.421413741,
|
||||
-1.453152027, 1.061405429};
|
||||
boolean negArg = (x < 0);
|
||||
|
||||
if (negArg) {
|
||||
// The rest of the method requires x >= 0, but since erf(x)
|
||||
// is an odd function, we just reflect x.
|
||||
x = -x;
|
||||
}
|
||||
|
||||
double t = 1.0 / (1 + p * x);
|
||||
double multiplier = 0.0;
|
||||
double tToPower = t;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
multiplier += a[i] * tToPower;
|
||||
tToPower *= t;
|
||||
}
|
||||
double retVal = 1.0 - multiplier * Math.exp(-x*x);
|
||||
// Remember that erf(x) was an odd function:
|
||||
return negArg ? - retVal: retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of possible combinations of p from n (i.e. n choose p)
|
||||
*
|
||||
|
@ -359,6 +451,12 @@ public class MathsUtils {
|
|||
return upToSetNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some testing:
|
||||
*
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String args[]) throws Exception {
|
||||
/*
|
||||
System.out.println(numOfSets(158,4));
|
||||
|
@ -368,6 +466,7 @@ public class MathsUtils {
|
|||
// int[][] sets = generateAllSets(6,4);
|
||||
// MatrixUtils.printMatrix(System.out, sets);
|
||||
|
||||
/*
|
||||
System.out.printf("digamma() digammaOld()\n");
|
||||
for (int n = 0; n < 100; n++) {
|
||||
System.out.printf("%d %.3f %.3f\n", n, MathsUtils.digamma(n), MathsUtils.digammaByDefinition(n));
|
||||
|
@ -375,5 +474,23 @@ public class MathsUtils {
|
|||
for (int n = 0; n < 101; n++) {
|
||||
System.out.printf("%d %.3f %.3f\n", n, MathsUtils.digamma(n), MathsUtils.digammaByDefinition(n));
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
System.out.println("erf(" + 1 + ")= " + MathsUtils.erf(1));
|
||||
System.out.println("erf(" + 2 + ")= " + MathsUtils.erf(2));
|
||||
System.out.println("erf(" + 0 + ")= " + MathsUtils.erf(0));
|
||||
for (int n=0; n<100; n++) {
|
||||
System.out.println("erf(" + n*0.1 + ")= " + MathsUtils.erf(n*0.1));
|
||||
}*/
|
||||
|
||||
int degFree = 10;
|
||||
System.out.println("chi2cdf(1," + degFree +")= " + MathsUtils.chiSquareCdf(1, degFree));
|
||||
System.out.println("chi2cdf(2," + degFree +")= " + MathsUtils.chiSquareCdf(2, degFree));
|
||||
System.out.println("chi2cdf(3," + degFree +")= " + MathsUtils.chiSquareCdf(3, degFree));
|
||||
for (int n=0; n<100; n++) {
|
||||
System.out.println("chi2cdf(" + n*0.1 + "," + degFree +")= " + MathsUtils.chiSquareCdf(n*0.1, degFree));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,21 @@ import java.util.Vector;
|
|||
*/
|
||||
public class MatrixUtils {
|
||||
|
||||
/**
|
||||
* Return an array with values enumerated through the given range
|
||||
*
|
||||
* @param startValue first value for the array
|
||||
* @param endValue last value for the array
|
||||
* @return
|
||||
*/
|
||||
public static int[] range(int startValue, int endValue) {
|
||||
int[] array = new int[endValue - startValue + 1];
|
||||
for (int i = 0; i < endValue - startValue + 1; i++) {
|
||||
array[i] = startValue + i;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static double sum(double[] input) {
|
||||
double total = 0;
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
|
@ -2249,6 +2264,32 @@ public class MatrixUtils {
|
|||
return c / (double) data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the covariance between two columns of data in
|
||||
* two multivariate arrays.</p>
|
||||
* <p>See - <a href="http://mathworld.wolfram.com/Covariance.html">Mathworld</a>
|
||||
* </p>
|
||||
*
|
||||
* @param data1 first multivariate array of data; first index is time, second is
|
||||
* variable number
|
||||
* @param data2 second multivariate array of data; first index is time, second is
|
||||
* variable number
|
||||
* @param col1 variable number 1 to compute the covariance to
|
||||
* @param col2 variable number 2 to compute the covariance to
|
||||
* @param mean1 mean of variable 1
|
||||
* @param mean2 mean of variable 2
|
||||
* @return the covariance
|
||||
*/
|
||||
public static double covarianceTwoColumns(
|
||||
double[][] data1, double[][] data2, int col1, int col2,
|
||||
double mean1, double mean2) {
|
||||
double c = 0;
|
||||
for (int t = 0; t < data1.length; t++) {
|
||||
c += (data1[t][col1] - mean1)*(data2[t][col2]-mean2);
|
||||
}
|
||||
return c / (double) data1.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the covariance matrix between all column pairs (variables) in the
|
||||
* multivariate data set
|
||||
|
@ -2274,7 +2315,70 @@ public class MatrixUtils {
|
|||
covariances[c][r] = covariances[r][c];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return covariances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the covariance matrix between all column pairs (variables) in the
|
||||
* multivariate data set, which consists of two separate
|
||||
* multivariate vectors.
|
||||
*
|
||||
* @param data1 multivariate array of data; first index is time, second is
|
||||
* variable number
|
||||
* @param data2 a second multivariate array of data, which can be though
|
||||
* of as extensions of rows of the first.
|
||||
* @return covariance matrix, where the columns of dat1 are numbered
|
||||
* first, and the columns of data2 after that.
|
||||
*/
|
||||
public static double[][] covarianceMatrix(
|
||||
double[][] data1, double[][] data2) {
|
||||
int numVariables1 = data1[0].length;
|
||||
int numVariables2 = data2[0].length;
|
||||
int numVariables = numVariables1 + numVariables2;
|
||||
double[][] covariances = new double[numVariables][numVariables];
|
||||
// Compute means of each variable once up front to save time
|
||||
double[] means1 = new double[numVariables1];
|
||||
double[] means2 = new double[numVariables2];
|
||||
for (int r = 0; r < numVariables1; r++) {
|
||||
means1[r] = mean(data1, r);
|
||||
}
|
||||
for (int r = 0; r < numVariables2; r++) {
|
||||
means2[r] = mean(data2, r);
|
||||
}
|
||||
// Now compute the covariances:
|
||||
for (int r = 0; r < numVariables1; r++) {
|
||||
// Compute the covariances internal to data1:
|
||||
for (int c = r; c < numVariables1; c++) {
|
||||
// Compute the covariance between variable r and c:
|
||||
covariances[r][c] = covarianceTwoColumns(data1, r, c,
|
||||
means1[r], means1[c]);
|
||||
// And of course this is symmetric between c and r:
|
||||
covariances[c][r] = covariances[r][c];
|
||||
}
|
||||
// Compute the covariances between data1 and data2
|
||||
for (int c = 0; c < numVariables2; c++) {
|
||||
// Compute the covariance between variable r and c:
|
||||
covariances[r][numVariables1 + c] =
|
||||
covarianceTwoColumns(data1, data2,
|
||||
r, c, means1[r], means2[c]);
|
||||
// And of course this is symmetric between c and r:
|
||||
covariances[numVariables1 + c][r] =
|
||||
covariances[r][numVariables1 + c];
|
||||
}
|
||||
}
|
||||
// Now compute the covariances internal to data2:
|
||||
for (int r = 0; r < numVariables2; r++) {
|
||||
for (int c = r; c < numVariables2; c++) {
|
||||
// Compute the covariance between variable r and c:
|
||||
covariances[numVariables1 + r][numVariables1 + c] =
|
||||
covarianceTwoColumns(data2, r, c,
|
||||
means2[r], means2[c]);
|
||||
// And of course this is symmetric between c and r:
|
||||
covariances[numVariables1 + c][numVariables1 + r] =
|
||||
covariances[numVariables1 + r][numVariables1 + c];
|
||||
}
|
||||
}
|
||||
return covariances;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,85 +1,44 @@
|
|||
package infodynamics.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* Structure to hold a distribution of info-theoretic measurements,
|
||||
* <p>Structure to hold a distribution of info-theoretic measurements,
|
||||
* and a significance value for how an original measurement compared
|
||||
* with these.
|
||||
* with these.</p>
|
||||
*
|
||||
* <p>While in theory this class could be directly used, it is it's
|
||||
* children which are intended to be used.</p>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
*/
|
||||
public class MeasurementDistribution {
|
||||
|
||||
/**
|
||||
* Distribution of surrogate measurement values
|
||||
*/
|
||||
public double[] distribution;
|
||||
/**
|
||||
* Actual observed value of the measurement
|
||||
*/
|
||||
public double actualValue;
|
||||
/**
|
||||
* Probability that surrogate measurement is greater than
|
||||
* the observed value
|
||||
* the observed value.
|
||||
* (Small pValue means that the observed value is highly significant).
|
||||
*/
|
||||
public double pValue;
|
||||
|
||||
protected boolean computedMean = false;
|
||||
protected double meanOfDist;
|
||||
protected double stdOfDist;
|
||||
|
||||
public MeasurementDistribution(int size) {
|
||||
distribution = new double[size];
|
||||
/**
|
||||
* Allow empty constructor for internal use only when actualValue and
|
||||
* pValue will be supplied later
|
||||
*/
|
||||
protected MeasurementDistribution() {
|
||||
}
|
||||
|
||||
public MeasurementDistribution(double[] distribution, double actualValue) {
|
||||
/**
|
||||
* Construct with supplied actual value and p-value for it.
|
||||
*
|
||||
* @param actualValue actual observed value
|
||||
* @param pValue p-value that the surrogate measurement is larger
|
||||
* than the observed value
|
||||
*/
|
||||
public MeasurementDistribution(double actualValue, double pValue) {
|
||||
this.actualValue = actualValue;
|
||||
this.distribution = distribution;
|
||||
int countWhereActualIsNotGreater = 0;
|
||||
for (int i = 0; i < distribution.length; i++) {
|
||||
if (distribution[i] >= actualValue) {
|
||||
countWhereActualIsNotGreater++;
|
||||
}
|
||||
}
|
||||
pValue = (double) countWhereActualIsNotGreater / (double) distribution.length;
|
||||
}
|
||||
|
||||
/*
|
||||
public double computeGaussianSignificance() {
|
||||
// Need to conpute the significance based on the assumption of
|
||||
// an underlying Gaussian distribution.
|
||||
// Use the t distribution for analysis, since we have a finite
|
||||
// number of samples to comptue the mean and std from.
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
public double getTSscore() {
|
||||
if (! computedMean) {
|
||||
meanOfDist = MatrixUtils.mean(distribution);
|
||||
stdOfDist = MatrixUtils.stdDev(distribution, meanOfDist);
|
||||
computedMean = true;
|
||||
}
|
||||
double t = (actualValue - meanOfDist) / stdOfDist;
|
||||
return t;
|
||||
}
|
||||
|
||||
public double getMeanOfDistribution() {
|
||||
if (! computedMean) {
|
||||
meanOfDist = MatrixUtils.mean(distribution);
|
||||
stdOfDist = MatrixUtils.stdDev(distribution, meanOfDist);
|
||||
computedMean = true;
|
||||
}
|
||||
return meanOfDist;
|
||||
}
|
||||
|
||||
public double getStdOfDistribution() {
|
||||
if (! computedMean) {
|
||||
meanOfDist = MatrixUtils.mean(distribution);
|
||||
stdOfDist = MatrixUtils.stdDev(distribution, meanOfDist);
|
||||
computedMean = true;
|
||||
}
|
||||
return stdOfDist;
|
||||
this.pValue = pValue;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue