Added new interface InfoMeasureCalculatorContinuous to capture common methods for continuous calculators. Also adapted most continuous calculators to implement this, which involved in many cases removing duplicate definitions of these methods in the interfaces for these measures. For ConditionalMI calculator, this meant we needed to add an implementation of the zero-argument initialise() call also. Still need to do MultiInfo, PredictiveInfo and Entropy in future, as they're missing a few methods.

This commit is contained in:
jlizier 2017-08-18 16:54:55 +10:00
parent 04351498aa
commit d6bd16546b
5 changed files with 139 additions and 200 deletions

View File

@ -84,7 +84,8 @@ import infodynamics.utils.EmpiricalNullDistributionComputer;
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
* <a href="http://lizier.me/joseph/">www</a>)
*/
public interface ActiveInfoStorageCalculator extends EmpiricalNullDistributionComputer {
public interface ActiveInfoStorageCalculator extends
InfoMeasureCalculatorContinuous, EmpiricalNullDistributionComputer {
/**
* Property name for embedding length <code>k</code> of
@ -100,13 +101,6 @@ public interface ActiveInfoStorageCalculator extends EmpiricalNullDistributionCo
*/
public static final String TAU_PROP_NAME = "TAU";
/**
* Initialise the calculator for (re-)use, with the existing (or default) values of parameters
* Clears any PDFs of previously supplied observations.
*
*/
public void initialise() throws Exception;
/**
* Initialise the calculator for (re-)use, with some parameters
* supplied here, and existing (or default) values of other parameters
@ -148,23 +142,9 @@ public interface ActiveInfoStorageCalculator extends EmpiricalNullDistributionCo
* @param propertyValue value of the property
* @throws Exception for invalid property values
*/
@Override
public void setProperty(String propertyName, String propertyValue) throws Exception;
/**
* Get current property values for the calculator.
*
* <p>Valid property names, and what their
* values should represent, are the same as those for
* {@link #setProperty(String, String)}</p>
*
* <p>Unknown property values are responded to with a null return value.</p>
*
* @param propertyName name of the property
* @return current value of the property
* @throws Exception for invalid property values
*/
public String getProperty(String propertyName) throws Exception;
/**
* Sets a single time-series from which to compute the PDF for the AIS.
* Cannot be called in conjunction with other methods for setting/adding
@ -247,13 +227,6 @@ public interface ActiveInfoStorageCalculator extends EmpiricalNullDistributionCo
*/
public void addObservations(double[] observations, boolean[] valid) throws Exception;
/**
* Compute the AIS from the previously-supplied samples.
*
* @return the AIS estimate
*/
public double computeAverageLocalOfObservations() throws Exception;
/**
* Compute the local AIS values for each of the
* previously-supplied samples.
@ -294,37 +267,4 @@ public interface ActiveInfoStorageCalculator extends EmpiricalNullDistributionCo
*/
public double[] computeLocalUsingPreviousObservations(double[] newObservations) 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 AIS last calculated in a call to {@link #computeAverageLocalOfObservations()}
* or {@link #computeLocalOfPreviousObservations()} after the previous
* {@link #initialise()} call.
*
* @return the last computed AIS value
*/
public double getLastAverage();
/**
* Get the number of samples to be used for the PDFs here
* which have been supplied by calls to
* {@link #setObservations(double[])}, {@link #addObservations(double[])}
* etc.
*
* <p>Note that the number of samples is not equal to the length of time-series
* supplied (since we need to accumulate the first
* <code>(k-1)*tau + 1</code>
* values of each time-series before taking a sample for AIS).
* </p>
*
* @return the number of samples to be used for the PDFs
* @throws Exception
*/
public int getNumObservations() throws Exception;
}

View File

@ -76,45 +76,9 @@ import infodynamics.utils.EmpiricalNullDistributionComputer;
* @see ChannelCalculatorMultiVariate
*
*/
public abstract interface ChannelCalculatorCommon extends EmpiricalNullDistributionComputer {
public abstract interface ChannelCalculatorCommon
extends InfoMeasureCalculatorContinuous, EmpiricalNullDistributionComputer {
/**
* Initialise the calculator for (re-)use, with the existing
* (or default) values of parameters.
*
* @throws Exception
*/
public void initialise() throws Exception;
/**
* Set properties for the calculator.
* New property values are not guaranteed to take effect until the next call
* to an initialise method.
*
* <p>No general properties are defined at the interface level here, i.e.
* there are only properties defined by child interfaces and classes.</p>
*
* @param propertyName name of the property
* @param propertyValue value of the property
* @throws Exception for invalid property values
*/
public void setProperty(String propertyName, String propertyValue) throws Exception;
/**
* Get current property values for the calculator.
*
* <p>Valid property names, and what their
* values should represent, are the same as those for
* {@link #setProperty(String, String)}</p>
*
* <p>Unknown property values are responded to with a null return value.</p>
*
* @param propertyName name of the property
* @return current value of the property
* @throws Exception for invalid property values
*/
public String getProperty(String propertyName) throws Exception;
/**
* Signal that we will add in the samples for computing the PDF
* from several disjoint time-series or trials via calls to
@ -140,13 +104,6 @@ public abstract interface ChannelCalculatorCommon extends EmpiricalNullDistribut
*/
public boolean getAddedMoreThanOneObservationSet();
/**
* Compute the channel measure from the previously-supplied samples.
*
* @return the estimate of the channel measure
*/
public double computeAverageLocalOfObservations() throws Exception;
/**
* <p>Computes the local values of the implemented channel measure,
* for each valid observation in the previously supplied observations
@ -166,34 +123,4 @@ public abstract interface ChannelCalculatorCommon extends EmpiricalNullDistribut
*/
public double[] computeLocalOfPreviousObservations() 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 channel measure last calculated in a call to {@link #computeAverageLocalOfObservations()}
* or {@link #computeLocalOfPreviousObservations()} after the previous
* {@link #initialise()} call.
*
* @return the last computed channel measure value
*/
public double getLastAverage();
/**
* Get the number of samples to be used for the PDFs here
* which have been supplied by calls to
* {@link #setObservations(double[])}, {@link #addObservations(double[])}
* etc.
*
* <p>Note that the number of samples may not be equal to the length of time-series
* supplied (e.g. for transfer entropy, where we need to accumulate
* a number of samples for the past history of the destination).
* </p>
*
* @return the number of samples to be used for the PDFs
*/
public int getNumObservations() throws Exception;
}

View File

@ -77,7 +77,7 @@ import infodynamics.utils.EmpiricalNullDistributionComputer;
Theory' (John Wiley & Sons, New York, 1991)."
*/
public interface ConditionalMutualInfoCalculatorMultiVariate
extends EmpiricalNullDistributionComputer {
extends InfoMeasureCalculatorContinuous, EmpiricalNullDistributionComputer {
/**
* Initialise the calculator for (re-)use, clearing PDFs,
@ -91,35 +91,6 @@ public interface ConditionalMutualInfoCalculatorMultiVariate
*/
public void initialise(int var1Dimensions, int var2Dimensions, int condDimentions) throws Exception;
/**
* Set properties for the calculator.
* New property values are not guaranteed to take effect until the next call
* to an initialise method.
*
* <p>No general properties are defined at the interface level here, i.e.
* there are only properties defined by child interfaces and classes.</p>
*
* @param propertyName name of the property
* @param propertyValue value of the property
* @throws Exception for invalid property values
*/
public void setProperty(String propertyName, String propertyValue) throws Exception;
/**
* Get current property values for the calculator.
*
* <p>Valid property names, and what their
* values should represent, are the same as those for
* {@link #setProperty(String, String)}</p>
*
* <p>Unknown property values are responded to with a null return value.</p>
*
* @param propertyName name of the property
* @return current value of the property
* @throws Exception for invalid property values
*/
public String getProperty(String propertyName) throws Exception;
/**
* Sets a single series from which to compute the PDF.
* Cannot be called in conjunction with
@ -274,15 +245,6 @@ public interface ConditionalMutualInfoCalculatorMultiVariate
*/
public void finaliseAddObservations() throws Exception;
/**
* Compute the average conditional MI from the previously-supplied samples.
*
* @return the estimate of the conditional MI in either bits or nats
* depending on the estimator
* @throws Exception
*/
public double computeAverageLocalOfObservations() throws Exception;
/**
* <p>Computes the local values of the conditional mutual information,
* for each valid observation in the previously supplied observations
@ -413,32 +375,11 @@ public interface ConditionalMutualInfoCalculatorMultiVariate
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 conditional MI last calculated in a call to {@link #computeAverageLocalOfObservations()}
* or {@link #computeLocalOfPreviousObservations()} after the previous
* {@link #initialise(int, int, int)} call.
*
* @return the last computed conditional MI value
*/
public double getLastAverage();
/**
* Get the number of samples to be used for the PDFs here
* which have been supplied by calls to
* {@link #setObservations(double[][], double[][], double[][])}, {@link #addObservations(double[][], double[][], double[][])}
* etc.
*
* @return the number of samples to be used for the PDFs
* @throws Exception if the implementing class computes MI without
* explicit observations (e.g. see
* {@link infodynamics.measures.continuous.gaussian.ConditionalMutualInfoCalculatorMultiVariateGaussian})
*/
@Override
public int getNumObservations() throws Exception;
/**

View File

@ -165,7 +165,10 @@ public abstract class ConditionalMutualInfoMultiVariateCommon implements
*/
protected double[] condStds = null;
@Override
public void initialise() {
initialise(dimensionsVar1, dimensionsVar2, dimensionsCond);
}
@Override
public void initialise(int var1Dimensions, int var2Dimensions, int condDimensions) {

View File

@ -0,0 +1,128 @@
/*
* Java Information Dynamics Toolkit (JIDT)
* Copyright (C) 2017, Joseph T. Lizier, Ipek Oezdemir and Pedro Mediano
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package infodynamics.measures.continuous;
/**
* <p>Base interface for our information-theoretic calculators
* on continuous (double[]) data,
* providing common functionality
* for user-level measure classes.</p>
*
* <p>
* Usage of the child classes implementing this interface is intended to follow this paradigm:
* </p>
* <ol>
* <li>Construct the calculator;</li>
* <li>set properties via {@link #setProperty(String, String)};</li>
* <li>Initialise the calculator using {@link #initialise()} or
* other initialise methods defined by child classes;</li>
* <li>Provide the observations/samples for the calculator
* to set up the PDFs, using one or more calls to
* sets of "addObservations" methods defined by child classes, then</li>
* <li>Compute the required quantities, being one or more of:
* <ul>
* <li>the average measure: {@link #computeAverageLocalOfObservations()};</li>
* <li>or other quantities as defined by child classes.</li>
* </ul>
* </li>
* <li>
* Return to step 3 to re-use the calculator on a new data set.
* </li>
* </ol>
*
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
* <a href="http://lizier.me/joseph/">www</a>)
*/
public interface InfoMeasureCalculatorContinuous {
/**
* Initialise the calculator for (re-)use, with the existing (or default) values of parameters.
* Clears any PDFs of previously supplied observations.
*/
public void initialise() throws Exception;
/**
* Set properties for the underlying calculator implementation.
* New property values are not guaranteed to take effect until the next call
* to an initialise method.
*
* <p>Property names are defined by the implementing class
* (generally in their documentation).
* Unknown property values are ignored.</p>
*
* @param propertyName name of the property
* @param propertyValue value of the property
* @throws Exception for invalid property values
*/
public void setProperty(String propertyName, String propertyValue) throws Exception;
/**
* Get current property values for the calculator.
*
* <p>Valid property names, and what their
* values should represent, are the same as those for
* {@link #setProperty(String, String)}</p>
*
* <p>Unknown property values are responded to with a null return value.</p>
*
* @param propertyName name of the property
* @return current value of the property
* @throws Exception for invalid property values
*/
public String getProperty(String propertyName) throws Exception;
/**
* Get the number of samples to be used for the PDFs here
* which have been supplied by calls to
* "setObservations", "addObservations" etc.
*
* <p>Note that the number of samples may not be equal to the length of time-series
* supplied (e.g. for transfer entropy, where we need to accumulate
* a number of samples for the past history of the destination).
* </p>
*
* @return the number of samples to be used for the PDFs
*/
public int getNumObservations() throws Exception;
/**
* Compute the average value of the measure
* from the previously-supplied samples.
*
* @return the estimate of the measure
*/
public abstract double computeAverageLocalOfObservations() throws Exception;
/**
* Return the measure last calculated in a call to
* {@link #computeAverageLocalOfObservations()}
* or related methods after the previous
* {@link #initialise()} call.
*
* @return the last computed measure value
*/
public double getLastAverage();
/**
* 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);
}