Fixes issue #70 by providing setObservations(double[], int[], double[]) methods for the mixed CMI calculators (i.e. allowing univariate arrays to be passed in if dimension 1 was defined for both the continuous data and conditional). Unit test validating is included.

This commit is contained in:
jlizier 2018-06-19 23:08:13 +10:00
parent fd13b75be3
commit 5bde6f295b
3 changed files with 122 additions and 0 deletions

View File

@ -55,9 +55,33 @@ public interface ConditionalMutualInfoCalculatorMultiVariateWithDiscreteSource {
public void addObservations(double[][] continuousObservations,
int[] discreteObservations, double[][] conditionedObservations) throws Exception;
/**
* Method to add observations. Can only be called when the continuous observations and
* the conditionals were both set to have dimension 1 in {@link #initialise(int, int, int)}
*
* @param continuousObservations
* @param discreteObservations
* @param conditionedObservations
* @throws Exception
*/
public void addObservations(double[] continuousObservations,
int[] discreteObservations, double[] conditionedObservations) throws Exception;
public void setObservations(double[][] continuousObservations,
int[] discreteObservations, double[][] conditionedObservations) throws Exception;
/**
* Method to set observations. Can only be called when the continuous observations and
* the conditionals were both set to have dimension 1 in {@link #initialise(int, int, int)}
*
* @param continuousObservations
* @param discreteObservations
* @param conditionedObservations
* @throws Exception
*/
public void setObservations(double[] continuousObservations,
int[] discreteObservations, double[] conditionedObservations) throws Exception;
public double computeAverageLocalOfObservations() throws Exception;
public double[] computeLocalOfPreviousObservations() throws Exception;

View File

@ -131,6 +131,13 @@ public abstract class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteSou
throw new RuntimeException("Not implemented yet");
}
@Override
public void addObservations(double[] continuousObservations,
int[] discreteObservations, double[] conditionedObservations)
throws Exception {
throw new RuntimeException("Not implemented yet");
}
public void setObservations(double[][] continuousObservations,
int[] discreteObservations, double[][] conditionedObservations)
throws Exception {
@ -156,6 +163,20 @@ public abstract class ConditionalMutualInfoCalculatorMultiVariateWithDiscreteSou
}
@Override
public void setObservations(double[] continuousObservations,
int[] discreteObservations, double[] conditionedObservations)
throws Exception {
if ((dimensionsContinuous != 1) || (dimensionsConditional != 1)) {
throw new Exception("setObservations(double[], int[], double[]) can only be called when both the continuous observations and conditional observations were initialised to have dimension 1");
}
double[][] contObservationsMatrix = new double[continuousObservations.length][1];
MatrixUtils.copyIntoColumn(contObservationsMatrix, 0, continuousObservations);
double[][] condObservationsMatrix = new double[conditionedObservations.length][1];
MatrixUtils.copyIntoColumn(condObservationsMatrix, 0, conditionedObservations);
setObservations(contObservationsMatrix, discreteObservations, condObservationsMatrix);
}
/**
* Compute the significance of the mutual information of the previously supplied observations.
* We destroy the p(x,d|z) correlations, while retaining the p(x|z) marginals, to check how

View File

@ -0,0 +1,77 @@
package infodynamics.measures.mixed.kraskov;
import infodynamics.utils.RandomGenerator;
import junit.framework.TestCase;
public class ConditionalMutualInfoWithDiscreteKraskovTester extends TestCase {
public void testUnivariateArrayMethods() {
ConditionalMutualInfoCalculatorMultiVariateWithDiscreteKraskov cmiCalc =
new ConditionalMutualInfoCalculatorMultiVariateWithDiscreteKraskov();
boolean exceptionCaught = false;
int dataLength = 1000;
RandomGenerator rg = new RandomGenerator();
double[] univariateContData1 = rg.generateNormalData(dataLength, 0, 1);
double[][] multivariateActualUniContData1 = rg.generateNormalData(dataLength, 1, 0, 1);
double[][] multivariateContData1 = rg.generateNormalData(dataLength, 2, 0, 1);
int[] discData = rg.generateRandomInts(dataLength, 2);
double[] univariateCondData = rg.generateNormalData(dataLength, 0, 1);
double[][] multivariateActualUniCondData = rg.generateNormalData(dataLength, 1, 0, 1);
double[][] multivariateCondData = rg.generateNormalData(dataLength, 2, 0, 1);
// Testing when univariate methods should work
cmiCalc.initialise(1, 2, 1);
try {
cmiCalc.setObservations(univariateContData1, discData, univariateCondData);
cmiCalc.initialise(1, 2, 1);
cmiCalc.setObservations(multivariateActualUniContData1, discData, multivariateActualUniCondData);
} catch (Exception e) {
exceptionCaught = true;
}
assertFalse(exceptionCaught);
// and now supply actual multivariates here which is wrong:
cmiCalc.initialise(1, 2, 1);
try{
cmiCalc.setObservations(multivariateContData1, discData, multivariateCondData);
} catch (Exception e) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
exceptionCaught = false;
// Testing when univariate methods should not work
cmiCalc.initialise(2, 2, 1);
try {
cmiCalc.setObservations(univariateContData1, discData, univariateCondData);
} catch (Exception e) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
exceptionCaught = false;
cmiCalc.initialise(1, 2, 2);
try {
cmiCalc.setObservations(univariateContData1, discData, univariateCondData);
} catch (Exception e) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
exceptionCaught = false;
cmiCalc.initialise(2, 2, 2);
try {
cmiCalc.setObservations(univariateContData1, discData, univariateCondData);
} catch (Exception e) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
exceptionCaught = false;
// and now supply the proper multivariate arrays:
cmiCalc.initialise(2, 2, 2);
try {
cmiCalc.setObservations(multivariateContData1, discData, multivariateCondData);
} catch (Exception e) {
exceptionCaught = true;
}
assertFalse(exceptionCaught);
}
}