Making continuous MultiInfoCalculator classes implement the InfoMeasureCalculatorContinuous interface. For the interfaces, this means removing methods where duplicated. For implementing classes, this means adding the missing methods.

This commit is contained in:
jlizier 2017-08-18 23:42:43 +10:00
parent 057f17e338
commit 086bee5945
5 changed files with 60 additions and 29 deletions

View File

@ -76,7 +76,8 @@ import infodynamics.utils.EmpiricalMeasurementDistribution;
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
* <a href="http://lizier.me/joseph/">www</a>)
*/
public interface MultiInfoCalculator {
public interface MultiInfoCalculator
extends InfoMeasureCalculatorContinuous {
/**
* Property name for whether to normalise incoming values to mean 0,
@ -120,6 +121,7 @@ public interface MultiInfoCalculator {
* @param propertyValue value of the property
* @throws Exception for invalid property values
*/
@Override
public void setProperty(String propertyName, String propertyValue) throws Exception;
/**
@ -189,14 +191,6 @@ public interface MultiInfoCalculator {
*/
public void finaliseAddObservations() throws Exception;
/**
* Compute the multi-information from the previously-supplied samples.
*
* @return the estimate of the multi-information
* @throws Exception
*/
public double computeAverageLocalOfObservations() throws Exception;
/**
* <p>Computes the local values of the multi-information,
* for each valid observation in the previously supplied observations
@ -337,20 +331,4 @@ public interface MultiInfoCalculator {
* is not equal to the number N samples that were previously supplied.
*/
public EmpiricalMeasurementDistribution computeSignificance(int[][][] newOrderings) throws Exception;
/**
* Set or clear debug mode for extra debug printing to stdout
*
* @param debug new setting for debug mode (on/off)
*/
public void setDebug(boolean debug);
/**
* Return the multi-information last calculated in a call to {@link #computeAverageLocalOfObservations()}
* or {@link #computeLocalOfPreviousObservations()} after the previous
* {@link #initialise(int)} call.
*
* @return the last computed multi-information value
*/
public double getLastAverage();
}

View File

@ -45,7 +45,7 @@ public abstract class MultiInfoCalculatorCommon implements MultiInfoCalculator {
/**
* Number of joint variables to consider
*/
protected int dimensions = 0;
protected int dimensions = 1;
/**
* Number of samples supplied
*/
@ -81,6 +81,11 @@ public abstract class MultiInfoCalculatorCommon implements MultiInfoCalculator {
private double samplingFactor = 0.1;
private Random rand;
@Override
public void initialise() {
initialise(dimensions);
}
@Override
public void initialise(int dimensions) {
this.dimensions = dimensions;
@ -127,6 +132,17 @@ public abstract class MultiInfoCalculatorCommon implements MultiInfoCalculator {
}
}
@Override
public String getProperty(String propertyName) throws Exception {
if (propertyName.equalsIgnoreCase(PROP_NORMALISE)) {
return Boolean.toString(normalise);
} else if (propertyName.equalsIgnoreCase(SAMPLING_FACTOR_PROP_NAME)) {
return Double.toString(samplingFactor);
} else {
return null;
}
}
@Override
public void setObservations(double[][] observations) throws Exception {
startAddObservations();
@ -258,6 +274,11 @@ public abstract class MultiInfoCalculatorCommon implements MultiInfoCalculator {
return miSurrogateCalculator.computeAverageLocalOfObservations();
}
@Override
public int getNumObservations() throws Exception {
return totalObservations;
}
@Override
public void setDebug(boolean debug) {
this.debug = debug;

View File

@ -2,7 +2,6 @@ package infodynamics.measures.continuous.gaussian;
import infodynamics.measures.continuous.MultiInfoCalculatorCommon;
import infodynamics.utils.MatrixUtils;
import infodynamics.utils.MathsUtils;
/**
* <p>Computes the differential multi-information of a given multivariate

View File

@ -209,6 +209,19 @@ public class MultiInfoCalculatorKernel
}
}
@Override
public String getProperty(String propertyName) throws Exception {
if (propertyName.equalsIgnoreCase(KERNEL_WIDTH_PROP_NAME) ||
propertyName.equalsIgnoreCase(EPSILON_PROP_NAME)) {
return Double.toString(kernelWidth);
} else if (propertyName.equalsIgnoreCase(DYN_CORR_EXCL_TIME_NAME)) {
return Integer.toString(dynCorrExclTime);
} else {
// Try the superclass, including for PROP_NORMALISE
return super.getProperty(propertyName);
}
}
@Override
public void startAddObservations() {
if (dynCorrExcl) {

View File

@ -183,7 +183,7 @@ public abstract class MultiInfoCalculatorKraskov
* <ul>
* <li>{@link #PROP_K} -- number of k nearest neighbours to use in joint kernel space
* in the KSG algorithm (default is 4).</li>
* <li>{@link #PROP_NORM_TYPE} -- normalization type to apply to
* <li>{@link #PROP_NORM_TYPE} -- norm type to apply to
* working out the norms between the points in each marginal space.
* Options are defined by {@link KdTree#setNormType(String)} -
* default is {@link EuclideanUtils#NORM_MAX_NORM}.</li>
@ -198,7 +198,9 @@ public abstract class MultiInfoCalculatorKraskov
* so can be considered as a number of standard deviations of the data.
* (Recommended by Kraskov. MILCA uses 1e-8; but adds in
* a random amount of noise in [0,noiseLevel) ).
* Default 1e-8 to match the noise order in MILCA toolkit..</li>
* Default 1e-8 to match the noise order in MILCA toolkit.</li>
* <li>Any property accepted by the superclass
* {@link MultiInfoCalculatorCommon#setProperty(String, String)}</li>
* </ul>
*
* <p>Unknown property values are ignored.</p>
@ -244,6 +246,24 @@ public abstract class MultiInfoCalculatorKraskov
}
}
@Override
public String getProperty(String propertyName) throws Exception {
if (propertyName.equalsIgnoreCase(PROP_K)) {
return Integer.toString(k);
} else if (propertyName.equalsIgnoreCase(PROP_NORM_TYPE)) {
return KdTree.convertNormTypeToString(normType);
} else if (propertyName.equalsIgnoreCase(PROP_DYN_CORR_EXCL_TIME)) {
return Integer.toString(dynCorrExclTime);
} else if (propertyName.equalsIgnoreCase(PROP_ADD_NOISE)) {
return Double.toString(noiseLevel);
} else if (propertyName.equalsIgnoreCase(PROP_NUM_THREADS)) {
return Integer.toString(numThreads);
} else {
// try the superclass, including for PROP_NORMALISE:
return super.getProperty(propertyName);
}
}
/**
* Set observations from two separate time series: join the rows at each time step
* together to make a joint vector, then effectively call {@link #setObservations(double[][])}