mirror of https://github.com/jlizier/jidt
Javadocs finalised for discrete package. Also added some new methods to ChannelCalculator, SingleAgentMeasure, EntropyRateCalculator, ActiveInfoStorageCalculator made to inherit/extend from SingleAgentMeasureInContextOfPastCalculator.
This commit is contained in:
parent
e27c9b0882
commit
8ea3368224
|
|
@ -19,100 +19,83 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.MathsUtils;
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localActiveInformation()
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* <p>Active Information Storage calculator for univariate discrete (int[]) data.
|
||||
* See definition of Active Information Storage (AIS) by Lizier et al. below.
|
||||
* Basically, AIS is the mutual information between the past <i>state</i>
|
||||
* of a time-series process <i>X</i> and its next value. The past <i>state</i> at time <code>n</code>
|
||||
* is represented by an embedding vector of <code>k</code> values from <code>X_n</code> backwards,
|
||||
* each separated by <code>\tau</code> steps, giving
|
||||
* <code><b>X^k_n</b> = [ X_{n-(k-1)\tau}, ... , X_{n-\tau}, X_n]</code>.
|
||||
* We call <code>k</code> the embedding dimension, and <code>\tau</code>
|
||||
* the embedding delay (only delay = 1 is implemented at the moment).
|
||||
* AIS is then the mutual information between <b>X^k_n</b> and X_{n+1}.</p>
|
||||
*
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator: {@link #ActiveInformationCalculator(int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average entropy: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local entropy values, such as {@link #computeLocal(int[])};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[])},
|
||||
* {@link #computeAverageLocal(int[])} etc.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>J.T. Lizier, M. Prokopenko and A.Y. Zomaya,
|
||||
* <a href="http://dx.doi.org/10.1016/j.ins.2012.04.016">
|
||||
* "Local measures of information storage in complex distributed computation"</a>,
|
||||
* Information Sciences, vol. 208, pp. 39-54, 2012.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class ActiveInformationCalculator {
|
||||
public class ActiveInformationCalculator extends SingleAgentMeasureInContextOfPastCalculator {
|
||||
|
||||
private double average = 0.0;
|
||||
private double max = 0.0;
|
||||
private double min = 0.0;
|
||||
private int observations = 0;
|
||||
private int k = 0; // history length k.
|
||||
private int base = 0; // number of individual states.
|
||||
private int[][] jointCount = null; // Count for (i[t+1], i[t]) tuples
|
||||
private int[] prevCount = null; // Count for i[t]
|
||||
private int[] nextCount = null; // Count for i[t+1]
|
||||
private int[] maxShiftedValue = null; // states * (base^(history-1))
|
||||
|
||||
private int base_power_k = 0;
|
||||
private double log_base = 0;
|
||||
|
||||
/**
|
||||
* User was formerly forced to create new instances through this factory method.
|
||||
* Retained for backwards compatibility.
|
||||
*
|
||||
* @param base
|
||||
* @param history
|
||||
*
|
||||
* @deprecated
|
||||
* @return
|
||||
*/
|
||||
public static ActiveInformationCalculator newInstance(int base, int history) {
|
||||
return new ActiveInformationCalculator(base, history);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance
|
||||
*
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedded history length of the destination to condition on -
|
||||
* this is k in Schreiber's notation.
|
||||
*/
|
||||
public ActiveInformationCalculator(int base, int history) {
|
||||
super();
|
||||
|
||||
this.base = base;
|
||||
k = history;
|
||||
base_power_k = MathsUtils.power(base, k);
|
||||
log_base = Math.log(base);
|
||||
|
||||
if (history < 1) {
|
||||
throw new RuntimeException("History k " + history + " is not >= 1 for Active info storage Calculator");
|
||||
}
|
||||
if (k > Math.log(Integer.MAX_VALUE) / log_base) {
|
||||
throw new RuntimeException("Base and history combination too large");
|
||||
}
|
||||
|
||||
// Create storage for counts of observations
|
||||
jointCount = new int[base][base_power_k];
|
||||
prevCount = new int[base_power_k];
|
||||
nextCount = new int[base];
|
||||
|
||||
// Create constants for tracking prevValues
|
||||
maxShiftedValue = new int[base];
|
||||
for (int v = 0; v < base; v++) {
|
||||
maxShiftedValue[v] = v * MathsUtils.power(base, k-1);
|
||||
}
|
||||
super(base, history);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*
|
||||
*/
|
||||
public void initialise(){
|
||||
average = 0.0;
|
||||
max = 0.0;
|
||||
min = 0.0;
|
||||
observations = 0;
|
||||
|
||||
MatrixUtils.fill(jointCount, 0);
|
||||
MatrixUtils.fill(prevCount, 0);
|
||||
MatrixUtils.fill(nextCount, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
*
|
||||
* @param states time series of agent states
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[]) {
|
||||
int timeSteps = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -130,8 +113,8 @@ public class ActiveInformationCalculator {
|
|||
for (int t = k; t < timeSteps; t++) {
|
||||
// Add to the count for this particular transition:
|
||||
nextVal = states[t];
|
||||
jointCount[nextVal][prevVal]++;
|
||||
prevCount[prevVal]++;
|
||||
nextPastCount[nextVal][prevVal]++;
|
||||
pastCount[prevVal]++;
|
||||
nextCount[nextVal]++;
|
||||
// Update the previous value:
|
||||
prevVal -= maxShiftedValue[states[t-k]];
|
||||
|
|
@ -140,13 +123,7 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][]) {
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -170,8 +147,8 @@ public class ActiveInformationCalculator {
|
|||
// Add to the count for this particular transition:
|
||||
// (cell's assigned as above)
|
||||
nextVal = states[r][c];
|
||||
jointCount[nextVal][prevVal[c]]++;
|
||||
prevCount[prevVal[c]]++;
|
||||
nextPastCount[nextVal][prevVal[c]]++;
|
||||
pastCount[prevVal[c]]++;
|
||||
nextCount[nextVal]++;
|
||||
// Update the previous value:
|
||||
prevVal[c] -= maxShiftedValue[states[r-k][c]];
|
||||
|
|
@ -181,13 +158,7 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][]) {
|
||||
int timeSteps = states.length;
|
||||
if (timeSteps == 0) {
|
||||
|
|
@ -221,8 +192,8 @@ public class ActiveInformationCalculator {
|
|||
// Add to the count for this particular transition:
|
||||
// (cell's assigned as above)
|
||||
nextVal = states[t][r][c];
|
||||
jointCount[nextVal][prevVal[r][c]]++;
|
||||
prevCount[prevVal[r][c]]++;
|
||||
nextPastCount[nextVal][prevVal[r][c]]++;
|
||||
pastCount[prevVal[r][c]]++;
|
||||
nextCount[nextVal]++;
|
||||
// Update the previous value:
|
||||
prevVal[r][c] -= maxShiftedValue[states[t-k][r][c]];
|
||||
|
|
@ -233,14 +204,7 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][], int col) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -260,8 +224,8 @@ public class ActiveInformationCalculator {
|
|||
// Add to the count for this particular transition:
|
||||
// (cell's assigned as above)
|
||||
nextVal = states[r][col];
|
||||
jointCount[nextVal][prevVal]++;
|
||||
prevCount[prevVal]++;
|
||||
nextPastCount[nextVal][prevVal]++;
|
||||
pastCount[prevVal]++;
|
||||
nextCount[nextVal]++;
|
||||
// Update the previous value:
|
||||
prevVal -= maxShiftedValue[states[r-k][col]];
|
||||
|
|
@ -270,14 +234,7 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
int timeSteps = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -297,8 +254,8 @@ public class ActiveInformationCalculator {
|
|||
// Add to the count for this particular transition:
|
||||
// (cell's assigned as above)
|
||||
nextVal = states[t][agentIndex1][agentIndex2];
|
||||
jointCount[nextVal][prevVal]++;
|
||||
prevCount[prevVal]++;
|
||||
nextPastCount[nextVal][prevVal]++;
|
||||
pastCount[prevVal]++;
|
||||
nextCount[nextVal]++;
|
||||
// Update the previous value:
|
||||
prevVal -= maxShiftedValue[states[t-k][agentIndex1][agentIndex2]];
|
||||
|
|
@ -307,12 +264,7 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local active information storage from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double mi = 0.0;
|
||||
double miCont = 0.0;
|
||||
|
|
@ -324,9 +276,9 @@ public class ActiveInformationCalculator {
|
|||
double p_next = (double) nextCount[nextVal] / (double) observations;
|
||||
for (int prevVal = 0; prevVal < base_power_k; prevVal++) {
|
||||
// compute p_prev
|
||||
double p_prev = (double) prevCount[prevVal] / (double) observations;
|
||||
double p_prev = (double) pastCount[prevVal] / (double) observations;
|
||||
// compute p(prev, next)
|
||||
double p_joint = (double) jointCount[nextVal][prevVal] / (double) observations;
|
||||
double p_joint = (double) nextPastCount[nextVal][prevVal] / (double) observations;
|
||||
// Compute MI contribution:
|
||||
if (p_joint > 0.0) {
|
||||
double logTerm = p_joint / (p_next * p_prev);
|
||||
|
|
@ -352,7 +304,7 @@ public class ActiveInformationCalculator {
|
|||
* Returns the average local entropy rate from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
* @return average entropy rate
|
||||
*/
|
||||
public double computeAverageLocalEntropyRateOfObservations() {
|
||||
double entRate = 0.0;
|
||||
|
|
@ -361,9 +313,9 @@ public class ActiveInformationCalculator {
|
|||
for (int nextVal = 0; nextVal < base; nextVal++) {
|
||||
for (int prevVal = 0; prevVal < base_power_k; prevVal++) {
|
||||
// compute p_prev
|
||||
double p_prev = (double) prevCount[prevVal] / (double) observations;
|
||||
double p_prev = (double) pastCount[prevVal] / (double) observations;
|
||||
// compute p(prev, next)
|
||||
double p_joint = (double) jointCount[nextVal][prevVal] / (double) observations;
|
||||
double p_joint = (double) nextPastCount[nextVal][prevVal] / (double) observations;
|
||||
// Compute entropy rate contribution:
|
||||
if (p_joint > 0.0) {
|
||||
double logTerm = p_joint / p_prev;
|
||||
|
|
@ -382,29 +334,24 @@ public class ActiveInformationCalculator {
|
|||
|
||||
/**
|
||||
* Computes local active info storage for the given (single)
|
||||
* specific values
|
||||
* specific values.
|
||||
*
|
||||
* @param destNext
|
||||
* @param destPast
|
||||
* @param sourceCurrent
|
||||
* @return
|
||||
* See {@link TransferEntropyCalculator#getPastCount(int)} for how the
|
||||
* joint embedded values representing the past are calculated.
|
||||
*
|
||||
* @param next next value of the variable
|
||||
* @param past int representing the joint state of the past of the variable x[n]^k
|
||||
* @return local active info storage value
|
||||
*/
|
||||
public double computeLocalFromPreviousObservations(int next, int past){
|
||||
double logTerm = ( (double) jointCount[next][past] ) /
|
||||
double logTerm = ( (double) nextPastCount[next][past] ) /
|
||||
( (double) nextCount[next] *
|
||||
(double) prevCount[past] );
|
||||
(double) pastCount[past] );
|
||||
logTerm *= (double) observations;
|
||||
return Math.log(logTerm) / log_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local active information storage for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
*
|
||||
* @param states time series of states
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[]){
|
||||
int timeSteps = states.length;
|
||||
|
||||
|
|
@ -425,9 +372,9 @@ public class ActiveInformationCalculator {
|
|||
double logTerm = 0.0;
|
||||
for (int t = k; t < timeSteps; t++) {
|
||||
nextVal = states[t];
|
||||
logTerm = ( (double) jointCount[nextVal][prevVal] ) /
|
||||
logTerm = ( (double) nextPastCount[nextVal][prevVal] ) /
|
||||
( (double) nextCount[nextVal] *
|
||||
(double) prevCount[prevVal] );
|
||||
(double) pastCount[prevVal] );
|
||||
// Now account for the fact that we've
|
||||
// just used counts rather than probabilities,
|
||||
// and we've got two counts on the bottom
|
||||
|
|
@ -451,15 +398,7 @@ public class ActiveInformationCalculator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local active information storage for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][] computeLocalFromPreviousObservations(int states[][]){
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -484,9 +423,9 @@ public class ActiveInformationCalculator {
|
|||
for (int r = k; r < rows; r++) {
|
||||
for (int c = 0; c < columns; c++) {
|
||||
nextVal = states[r][c];
|
||||
logTerm = ( (double) jointCount[nextVal][prevVal[c]] ) /
|
||||
logTerm = ( (double) nextPastCount[nextVal][prevVal[c]] ) /
|
||||
( (double) nextCount[nextVal] *
|
||||
(double) prevCount[prevVal[c]] );
|
||||
(double) pastCount[prevVal[c]] );
|
||||
// Now account for the fact that we've
|
||||
// just used counts rather than probabilities,
|
||||
// and we've got two counts on the bottom
|
||||
|
|
@ -511,15 +450,7 @@ public class ActiveInformationCalculator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local active information storage for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][][] computeLocalFromPreviousObservations(int states[][][]){
|
||||
int timeSteps = states.length;
|
||||
int agentRows = states[0].length;
|
||||
|
|
@ -548,9 +479,9 @@ public class ActiveInformationCalculator {
|
|||
for (int r = 0; r < agentRows; r++) {
|
||||
for (int c = 0; c < agentColumns; c++) {
|
||||
nextVal = states[t][r][c];
|
||||
logTerm = ( (double) jointCount[nextVal][prevVal[r][c]] ) /
|
||||
logTerm = ( (double) nextPastCount[nextVal][prevVal[r][c]] ) /
|
||||
( (double) nextCount[nextVal] *
|
||||
(double) prevCount[prevVal[r][c]] );
|
||||
(double) pastCount[prevVal[r][c]] );
|
||||
// Now account for the fact that we've
|
||||
// just used counts rather than probabilities,
|
||||
// and we've got two counts on the bottom
|
||||
|
|
@ -575,15 +506,7 @@ public class ActiveInformationCalculator {
|
|||
return localActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local active information storage for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int col){
|
||||
int rows = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
@ -605,9 +528,9 @@ public class ActiveInformationCalculator {
|
|||
double logTerm = 0.0;
|
||||
for (int r = k; r < rows; r++) {
|
||||
nextVal = states[r][col];
|
||||
logTerm = ( (double) jointCount[nextVal][prevVal] ) /
|
||||
logTerm = ( (double) nextPastCount[nextVal][prevVal] ) /
|
||||
( (double) nextCount[nextVal] *
|
||||
(double) prevCount[prevVal] );
|
||||
(double) pastCount[prevVal] );
|
||||
// Now account for the fact that we've
|
||||
// just used counts rather than probabilities,
|
||||
// and we've got two counts on the bottom
|
||||
|
|
@ -631,16 +554,9 @@ public class ActiveInformationCalculator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local active information storage for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @return
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][], int agentIndex1, int agentIndex2){
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][],
|
||||
int agentIndex1, int agentIndex2){
|
||||
int timeSteps = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
||||
|
|
@ -661,9 +577,9 @@ public class ActiveInformationCalculator {
|
|||
double logTerm = 0.0;
|
||||
for (int t = k; t < timeSteps; t++) {
|
||||
nextVal = states[t][agentIndex1][agentIndex2];
|
||||
logTerm = ( (double) jointCount[nextVal][prevVal] ) /
|
||||
logTerm = ( (double) nextPastCount[nextVal][prevVal] ) /
|
||||
( (double) nextCount[nextVal] *
|
||||
(double) prevCount[prevVal] );
|
||||
(double) pastCount[prevVal] );
|
||||
// Now account for the fact that we've
|
||||
// just used counts rather than probabilities,
|
||||
// and we've got two counts on the bottom
|
||||
|
|
@ -688,207 +604,29 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local active information storage across an
|
||||
* array of the states of homogeneous agents
|
||||
* Return an array of local values.
|
||||
* First history rows are zeros
|
||||
* Generate a bootstrapped distribution of what the AIS would look like,
|
||||
* under a null hypothesis that the past <code>k</code> values of our
|
||||
* samples had no relation to the next value.
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - time series array of states
|
||||
* @return
|
||||
*/
|
||||
public double[] computeLocal(int states[]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local active information storage across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for
|
||||
* an MI (like the AIS).
|
||||
* </p>
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - 2D array of states
|
||||
* @return
|
||||
*/
|
||||
public double[][] computeLocal(int states[][]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local active information storage across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(int[], int[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - array of states - 1st dimension is time, 2nd and 3rd are agent indices
|
||||
* @return
|
||||
*/
|
||||
public double[][][] computeLocal(int states[][][]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local active information storage across an
|
||||
* array of the states of homogeneous agents
|
||||
* Return the averagen
|
||||
* <p>This method (in contrast to {@link #computeSignificance(int[][])})
|
||||
* creates <i>random</i> shufflings of the next values for the surrogate AIS
|
||||
* calculations.</p>
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - narray of states
|
||||
* @return
|
||||
*/
|
||||
public double computeAverageLocal(int states[]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local active information storage across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - 2D array of states
|
||||
* @return
|
||||
*/
|
||||
public double computeAverageLocal(int states[][]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local active information storage across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - array of states - 1st dimension is time, 2nd and 3rd are agent indices
|
||||
* @return
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local active information storage for one agent in a 2D spatiotemporal
|
||||
* array of the states of agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method should be used for heterogeneous agents
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - 2D array of states
|
||||
* @param col - column number of the agent in the states array
|
||||
* @return
|
||||
*/
|
||||
public double[] computeLocal(int states[][], int col) {
|
||||
|
||||
initialise();
|
||||
addObservations(states, col);
|
||||
return computeLocalFromPreviousObservations(states, col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local active information storage for one agent in a 2D spatiotemporal
|
||||
* array of the states of agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method should be used for heterogeneous agents
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - array of states - 1st dimension is time, 2nd and 3rd are agent indices
|
||||
* @param agentIndex1 row index of agent
|
||||
* @param agentIndex2 column index of agent
|
||||
* @return
|
||||
*/
|
||||
public double[] computeLocal(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
|
||||
initialise();
|
||||
addObservations(states, agentIndex1, agentIndex2);
|
||||
return computeLocalFromPreviousObservations(states, agentIndex1, agentIndex2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local active information storage
|
||||
* for a single agent
|
||||
* Returns the average
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - 2D array of states
|
||||
* @param col - column number of the agent in the states array
|
||||
* @return
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int col) {
|
||||
|
||||
initialise();
|
||||
addObservations(states, col);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local active information storage
|
||||
* for a single agent
|
||||
* Returns the average
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param history - parameter k
|
||||
* @param maxEmbeddingLength - base of the states
|
||||
* @param states - array of states - 1st dimension is time, 2nd and 3rd are agent indices
|
||||
* @param agentIndex1 row index of agent
|
||||
* @param agentIndex2 column index of agent
|
||||
* @return
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
|
||||
initialise();
|
||||
addObservations(states, agentIndex1, agentIndex2);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average from the given observations
|
||||
*
|
||||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
* @param numPermutationsToCheck number of surrogate samples to bootstrap
|
||||
* to generate the distribution.
|
||||
* @return the distribution of AIS scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
|
|
@ -898,10 +636,38 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average from the given observations
|
||||
* Generate a bootstrapped distribution of what the AIS would look like,
|
||||
* under a null hypothesis that the previous <code>k</code> values of our
|
||||
* samples had no relation to the next value in the time-series.
|
||||
*
|
||||
* @param newOrderings the reorderings to use
|
||||
* @return
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for AIS
|
||||
* as a mutual information. Basically, the marginal PDFs
|
||||
* of the past <code>k</code> values, and that of the next value,
|
||||
* are preserved, while their joint PDF is destroyed, and the
|
||||
* distribution of AIS under these conditions is generated.</p>
|
||||
*
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(double[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* <p>This method (in contrast to {@link #computeSignificance(int)})
|
||||
* allows the user to specify how to construct the surrogates,
|
||||
* such that repeatable results may be obtained.</p>
|
||||
*
|
||||
* @param newOrderings a specification of how to shuffle the next values
|
||||
* to create the surrogates to generate the distribution with. The first
|
||||
* index is the permutation number (i.e. newOrderings.length is the number
|
||||
* of surrogate samples we use to bootstrap to generate the distribution here.)
|
||||
* Each array newOrderings[i] should be an array of length N (where
|
||||
* would be the value returned by {@link #getNumObservations()}),
|
||||
* containing a permutation of the values in 0..(N-1).
|
||||
* @return the distribution of AIS scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
* @throws Exception where the length of each permutation in newOrderings
|
||||
* is not equal to the number N samples that were previously supplied.
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) {
|
||||
double actualMI = computeAverageLocalOfObservations();
|
||||
|
|
@ -913,8 +679,8 @@ public class ActiveInformationCalculator {
|
|||
int[] nextValues = new int[observations];
|
||||
int t_prev = 0;
|
||||
int t_next = 0;
|
||||
for (int prevVal = 0; prevVal < prevCount.length; prevVal++) {
|
||||
int numberOfSamplesPrev = prevCount[prevVal];
|
||||
for (int prevVal = 0; prevVal < pastCount.length; prevVal++) {
|
||||
int numberOfSamplesPrev = pastCount[prevVal];
|
||||
MatrixUtils.fill(prevValues, prevVal, t_prev, numberOfSamplesPrev);
|
||||
t_prev += numberOfSamplesPrev;
|
||||
}
|
||||
|
|
@ -928,7 +694,7 @@ public class ActiveInformationCalculator {
|
|||
ais2 = new ActiveInformationCalculator(base, k);
|
||||
ais2.initialise();
|
||||
ais2.observations = observations;
|
||||
ais2.prevCount = prevCount;
|
||||
ais2.pastCount = pastCount;
|
||||
ais2.nextCount = nextCount;
|
||||
int countWhereMIIsMoreSignificantThanOriginal = 0;
|
||||
EmpiricalMeasurementDistribution measDistribution = new EmpiricalMeasurementDistribution(numPermutationsToCheck);
|
||||
|
|
@ -936,9 +702,9 @@ public class ActiveInformationCalculator {
|
|||
// Generate a new re-ordered data set for the next variable
|
||||
int[] newDataNext = MatrixUtils.extractSelectedTimePoints(nextValues, newOrderings[p]);
|
||||
// compute the joint probability distribution
|
||||
MatrixUtils.fill(ais2.jointCount, 0);
|
||||
MatrixUtils.fill(ais2.nextPastCount, 0);
|
||||
for (int t = 0; t < observations; t++) {
|
||||
ais2.jointCount[newDataNext[t]][prevValues[t]]++;
|
||||
ais2.nextPastCount[newDataNext[t]][prevValues[t]]++;
|
||||
}
|
||||
// And get an MI value for this realisation:
|
||||
double newMI = ais2.computeAverageLocalOfObservations();
|
||||
|
|
@ -955,20 +721,8 @@ public class ActiveInformationCalculator {
|
|||
return measDistribution;
|
||||
}
|
||||
|
||||
public double getLastAverage() {
|
||||
return average;
|
||||
}
|
||||
|
||||
public double getLastMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public double getLastMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the current probability distribution functions
|
||||
* Debug method to write the current probability distribution functions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -982,9 +736,9 @@ public class ActiveInformationCalculator {
|
|||
double p_next = (double) nextCount[nextVal] / (double) observations;
|
||||
for (int prevVal = 0; prevVal < base_power_k; prevVal++) {
|
||||
// compute p_prev
|
||||
double p_prev = (double) prevCount[prevVal] / (double) observations;
|
||||
double p_prev = (double) pastCount[prevVal] / (double) observations;
|
||||
// compute p(prev, next)
|
||||
double p_joint = (double) jointCount[nextVal][prevVal] / (double) observations;
|
||||
double p_joint = (double) nextPastCount[nextVal][prevVal] / (double) observations;
|
||||
// Compute MI contribution:
|
||||
if (p_joint * p_next * p_prev > 0.0) {
|
||||
double logTerm = p_joint / (p_next * p_prev);
|
||||
|
|
@ -1006,12 +760,17 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* Utility function to compute a unique number to represent the
|
||||
* combined past values of x up to and including time step t:
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
*
|
||||
* @param x
|
||||
* @param t
|
||||
* @return
|
||||
* See {@link TransferEntropyCalculator#getPastCount(int)} for
|
||||
* how the joint value representing the past is calculated.
|
||||
*
|
||||
* @param x time series
|
||||
* @param t time step at which to compute the combined past
|
||||
* @return an int representing the joint state of the past of x, x[t]^k
|
||||
*
|
||||
*/
|
||||
public int computePastValue(int[] x, int t) {
|
||||
int pastVal = 0;
|
||||
|
|
@ -1023,37 +782,53 @@ public class ActiveInformationCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* Utility function to compute a unique number to represent the
|
||||
* combined past values of x (which is a column in data)
|
||||
* up to and including time step t:
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
*
|
||||
* @param x
|
||||
* @param agentNumber
|
||||
* @param t
|
||||
* @return
|
||||
* See {@link TransferEntropyCalculator#getPastCount(int)} for
|
||||
* how the joint value representing the past is calculated.
|
||||
*
|
||||
* @param data 2D time series, first index is time,
|
||||
* second is variable number
|
||||
* @param column column of data which is variable x
|
||||
* @param t time step at which to compute the combined past
|
||||
* @return an int representing the joint state of the past of x, x[t]^k
|
||||
*/
|
||||
public int computePastValue(int[][] x, int agentNumber, int t) {
|
||||
public int computePastValue(int[][] data, int column, int t) {
|
||||
int pastVal = 0;
|
||||
for (int p = 0; p < k; p++) {
|
||||
pastVal *= base;
|
||||
pastVal += x[t - k + 1 + p][agentNumber];
|
||||
pastVal += data[t - k + 1 + p][column];
|
||||
}
|
||||
return pastVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* Utility function to compute a unique number to represent the
|
||||
* combined past values of x (which is a variable in data)
|
||||
* up to and including time step t:
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
*
|
||||
* @param x
|
||||
* @param agentNumber
|
||||
* @param t
|
||||
* @return
|
||||
* See {@link TransferEntropyCalculator#getPastCount(int)} for
|
||||
* how the joint value representing the past is calculated.
|
||||
*
|
||||
* @param data 3D time series, first index is time,
|
||||
* second is variable row number, third is variable column number
|
||||
* @param agentRow row of data for variable x
|
||||
* @param agentColumn column of data for variable x
|
||||
* @param t time step at which to compute the combined past
|
||||
* @return an int representing the joint state of the past of x, x[t]^k
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
*/
|
||||
public int computePastValue(int[][][] x, int agentRow, int agentColumn, int t) {
|
||||
public int computePastValue(int[][][] data, int agentRow,
|
||||
int agentColumn, int t) {
|
||||
int pastVal = 0;
|
||||
for (int p = 0; p < k; p++) {
|
||||
pastVal *= base;
|
||||
pastVal += x[t - k + 1 + p][agentRow][agentColumn];
|
||||
pastVal += data[t - k + 1 + p][agentRow][agentColumn];
|
||||
}
|
||||
return pastVal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,26 +22,50 @@ import infodynamics.utils.MathsUtils;
|
|||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* Computes entropy over blocks of consecutive states in time.
|
||||
*
|
||||
* <p>Block entropy calculator for univariate discrete (int[]) data
|
||||
* (ie computes entropy over blocks of consecutive states in time).
|
||||
* Implemented separately from the single state entropy
|
||||
* calculator to allow the single state calculator
|
||||
* to have optimal performance.
|
||||
*
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localActiveInformation()
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* to have optimal performance.</p>
|
||||
*
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator: {@link #BlockEntropyCalculator(int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average entropy: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local entropy values, such as {@link #computeLocal(int[])};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[])},
|
||||
* {@link #computeAverageLocal(int[])} etc.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. M. Cover and J. A. Thomas, 'Elements of Information
|
||||
Theory' (John Wiley & Sons, New York, 1991).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class BlockEntropyCalculator extends EntropyCalculator {
|
||||
|
||||
protected int blocksize = 0; // temporal blocksize to compute entropy over. Need initialised to 0 for changedSizes
|
||||
/**
|
||||
* Number of consecutive time-steps to compute entropy over.
|
||||
*/
|
||||
protected int blocksize = 0; // Need initialised to 0 for changedSizes
|
||||
protected int[] maxShiftedValue = null; // states * (base^(blocksize-1))
|
||||
|
||||
protected int base_power_blocksize = 0;
|
||||
|
|
@ -52,16 +76,18 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
*
|
||||
* @param blocksize
|
||||
* @param base
|
||||
* @return
|
||||
* @deprecated
|
||||
*/
|
||||
public static EntropyCalculator newInstance(int blocksize, int base) {
|
||||
return new BlockEntropyCalculator(blocksize, base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance
|
||||
*
|
||||
* @param blocksize
|
||||
* @param base
|
||||
* @param blocksize Number of consecutive time-steps to compute entropy over.
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
*/
|
||||
public BlockEntropyCalculator(int blocksize, int base) {
|
||||
|
||||
|
|
@ -89,22 +115,13 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
MatrixUtils.fill(stateCount, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
*
|
||||
* @param states index is time
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[]) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -133,13 +150,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][]) {
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -174,13 +185,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][]) {
|
||||
int timeSteps = states.length;
|
||||
if (timeSteps == 0) {
|
||||
|
|
@ -226,14 +231,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][], int col) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -262,14 +260,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
int timeSteps = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -298,12 +289,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local entropy from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double ent = 0.0;
|
||||
double entCont = 0.0;
|
||||
|
|
@ -332,15 +318,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
return ent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][] computeLocalFromPreviousObservations(int states[][]){
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -388,15 +366,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][][] computeLocalFromPreviousObservations(int states[][][]){
|
||||
int timeSteps = states.length;
|
||||
int agentRows, agentColumns;
|
||||
|
|
@ -459,15 +429,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int col){
|
||||
int rows = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
@ -512,15 +474,7 @@ public class BlockEntropyCalculator extends EntropyCalculator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][], int agentIndex1, int agentIndex2){
|
||||
int timeSteps = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
|
|||
|
|
@ -21,48 +21,110 @@ package infodynamics.measures.discrete;
|
|||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
|
||||
/**
|
||||
* An interface for calculators computing measures from a source to a destination.
|
||||
* A basic interface for calculators computing measures on a univariate <i>channel</i>
|
||||
* for discrete (ie int[]) data from a
|
||||
* source to a destination time-series (ie mutual information and transfer entropy).
|
||||
* In the following, we refer to the abstract measure computed by this calculator
|
||||
* as the <i>"channel measure"</i>.
|
||||
*
|
||||
* <p>
|
||||
* Usage of the child classes implementing this interface is intended to follow this paradigm:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator;</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()} or
|
||||
* other initialise methods defined by child classes;
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* the set of {@link #addObservations(int[], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average channel measure: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>the distribution of channel measure values under the null hypothesis
|
||||
* of no relationship between source and
|
||||
* destination values: {@link #computeSignificance(int)};</li>
|
||||
* <li>or other quantities as defined by child classes.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Joseph Lizier, jlizier at gmail.com
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public interface ChannelCalculator {
|
||||
|
||||
/**
|
||||
* Initialise the calculator
|
||||
*
|
||||
* Initialise the calculator for (re-)use, with the existing
|
||||
* (or default) values of parameters.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void initialise();
|
||||
|
||||
/**
|
||||
* Add observations for the source and destination
|
||||
* <p>Adds a new set of observations to update the PDFs with.
|
||||
* It is intended to be called multiple times.
|
||||
*
|
||||
* @param states
|
||||
* @param sourceIndex
|
||||
* @param destIndex
|
||||
*/
|
||||
public void addObservations(int states[][], int sourceIndex, int destIndex);
|
||||
|
||||
/**
|
||||
* Add observations for the source and destination
|
||||
* @param source
|
||||
* @param dest
|
||||
* <p><b>Important:</b> this does not append these observations to the previously
|
||||
* supplied observations, but treats them independently - i.e. measurements
|
||||
* such as the transfer entropy will not join them up to examine k
|
||||
* consecutive values in time.</p>
|
||||
*
|
||||
* @param source series of observations for the source variable.
|
||||
* @param destination series of observations for the destination
|
||||
* variable. Length must match <code>source</code>, and their indices
|
||||
* must correspond.
|
||||
*/
|
||||
public void addObservations(int[] source, int[] dest);
|
||||
|
||||
/**
|
||||
* Compute the value of the measure
|
||||
* <p>Adds a new set of observations to update the PDFs with,
|
||||
* from within a multivariate time-series.
|
||||
* It is intended to be called multiple times.
|
||||
*
|
||||
* @return
|
||||
* <p><b>Important:</b> this does not append these observations to the previously
|
||||
* supplied observations, but treats them independently - i.e. measurements
|
||||
* such as the transfer entropy will not join them up to examine k
|
||||
* consecutive values in time.</p>
|
||||
*
|
||||
* @param states 2D multivariate time series (first index is time
|
||||
* second indexes the variable)
|
||||
* @param sourceIndex column index for the source variable.
|
||||
* @param destIndex column index for the destination variable.
|
||||
*/
|
||||
public void addObservations(int states[][], int sourceIndex, int destIndex);
|
||||
|
||||
/**
|
||||
* Compute the channel measure from the previously-supplied samples.
|
||||
*
|
||||
* @return the estimate of the channel measure
|
||||
*/
|
||||
public double computeAverageLocalOfObservations();
|
||||
|
||||
/**
|
||||
* Compute the significance of the average value for the channel measure here
|
||||
* Generate a bootstrapped distribution of what the channel measure would look like,
|
||||
* under a null hypothesis that the source values of our
|
||||
* samples had no relation to the destination value.
|
||||
* (Precise null hypothesis varies between MI and TE).
|
||||
*
|
||||
* @param numPermutationsToCheck
|
||||
* @return
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for MI,
|
||||
* conditional MI and TE.
|
||||
* </p>
|
||||
*
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(int[], int[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* @param numPermutationsToCheck number of surrogate samples to bootstrap
|
||||
* to generate the distribution.
|
||||
* @return the distribution of channel measure scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,18 +22,21 @@ import infodynamics.utils.MathsUtils;
|
|||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* A combined calculator for the active information, entropy rate and entropy.
|
||||
* A combined calculator for the active information,
|
||||
* entropy rate and entropy.
|
||||
*
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localActiveInformation()
|
||||
* <p>This class is preliminary, so the Javadocs are incomplete --
|
||||
* please see {@link ActiveInformationCalculator},
|
||||
* {@link EntropyRateCalculator} and {@link EntropyCalculator}
|
||||
* for documentation on the corresponding functions
|
||||
* and typical usage pattern.
|
||||
* </p>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
* TODO Make this inherit from {@link SingleAgentMeasureInContextOfPastCalculator}
|
||||
* like {@link ActiveInformationCalculator} and fix the Javadocs
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class CombinedActiveEntRateCalculator {
|
||||
|
||||
|
|
@ -524,11 +527,4 @@ public class CombinedActiveEntRateCalculator {
|
|||
public double getLastMinEntropy() {
|
||||
return minEntropy;
|
||||
}
|
||||
|
||||
// Compute the metrics in several different ways over test data.
|
||||
// Designed to be called from a JUnit test.
|
||||
public double[][] test() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,25 +26,48 @@ import infodynamics.utils.EmpiricalMeasurementDistribution;
|
|||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
* Implements conditional mutual information
|
||||
* <p>Conditional Mutual information (MI) calculator for univariate discrete (int[]) data.</p>
|
||||
*
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations before computing :
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations() or computeAverageLocalOfObservations()
|
||||
* 2. Standalone computation from a single set of observations:
|
||||
* Call: computeLocal() or computeAverageLocal()
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator:
|
||||
* {@link #ConditionalMutualInformationCalculator(int, int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[], int[], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average MI: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local MI values, such as
|
||||
* {@link #computeLocalFromPreviousObservations(int[], int[], int[])};</li>
|
||||
* <li>comparison to null distribution, such as
|
||||
* {@link #computeSignificance()};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[], int[], int[])}.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* joseph.lizier at gmail.com
|
||||
* http://lizier.me/joseph/
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. M. Cover and J. A. Thomas, 'Elements of Information
|
||||
Theory' (John Wiley & Sons, New York, 1991).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class ConditionalMutualInformationCalculator extends InfoMeasureCalculator implements AnalyticNullDistributionComputer {
|
||||
public class ConditionalMutualInformationCalculator
|
||||
extends InfoMeasureCalculator implements AnalyticNullDistributionComputer {
|
||||
|
||||
/**
|
||||
* Store the bases for each variable
|
||||
* Store the number of symbols for each variable
|
||||
*/
|
||||
protected int base1;
|
||||
protected int base2;
|
||||
|
|
@ -61,16 +84,26 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
* User was formerly forced to create new instances through this factory method.
|
||||
* Retained for backwards compatibility.
|
||||
*
|
||||
* @param base1 base of first MI variable
|
||||
* @param base2 base of second MI variable
|
||||
* @param condBase base of conditional variable
|
||||
*
|
||||
* @return
|
||||
* @param base1 number of symbols for first variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param base2 number of symbols for second variable.
|
||||
* @param condBase number of symbols for conditional variable.
|
||||
* @deprecated As of JIDT 1.0, call {@link #ConditionalMutualInformationCalculator(int, int, int)}
|
||||
* directly.
|
||||
* @return new calculator object
|
||||
*/
|
||||
public static ConditionalMutualInformationCalculator newInstance(int base1, int base2, int condBase) {
|
||||
return new ConditionalMutualInformationCalculator(base1, base2, condBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance
|
||||
*
|
||||
* @param base1 number of symbols for first variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param base2 number of symbols for second variable.
|
||||
* @param condBase number of symbols for conditional variable.
|
||||
*/
|
||||
public ConditionalMutualInformationCalculator(int base1, int base2, int condBase) {
|
||||
|
||||
// Create super object, just with first base
|
||||
|
|
@ -88,12 +121,7 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
condCount = new int[condBase];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
|
||||
|
|
@ -106,12 +134,13 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for the given var1,var2,cond tuples of the multi-agent system
|
||||
* Add observations for the given var1,var2,cond tuples
|
||||
* of the variables
|
||||
* to our estimates of the pdfs.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
*/
|
||||
public void addObservations(int var1[], int var2[], int cond[]) {
|
||||
int rows = var1.length;
|
||||
|
|
@ -129,14 +158,15 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for the given var1,var2,cond tuples of the multi-agent system
|
||||
* Add observations for the given var1,var2,cond tuples
|
||||
* of the variables
|
||||
* to our estimates of the pdfs.
|
||||
* This method signature allows applications using byte data (to save memory)
|
||||
* to operate correctly.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
*/
|
||||
public void addObservations(byte var1[], byte var2[], byte cond[]) {
|
||||
int rows = var1.length;
|
||||
|
|
@ -154,14 +184,16 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for the given var1,var2,cond tuples of the multi-agent system
|
||||
* Add observations for the given var1,var2,cond tuples
|
||||
* of the variables
|
||||
* to our estimates of the pdfs, only when those observations are confirmed
|
||||
* as valid.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @param valid whether each observation is valid to be counted in the PDFs
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
* @param valid series of whether each observation is valid
|
||||
* to be counted in the PDFs
|
||||
*/
|
||||
public void addObservations(int var1[], int var2[], int cond[],
|
||||
boolean[] valid) {
|
||||
|
|
@ -182,16 +214,18 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for the given var1,var2,cond tuples of the multi-agent system
|
||||
* Add observations for the given var1,var2,cond tuples
|
||||
* of the variables
|
||||
* to our estimates of the pdfs, only when those observations are confirmed
|
||||
* as valid.
|
||||
* This method signature allows applications using byte data (to save memory)
|
||||
* to operate correctly.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @param valid whether each observation is valid to be counted in the PDFs
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
* @param valid whether each observation is valid
|
||||
* to be counted in the PDFs
|
||||
*/
|
||||
public void addObservations(byte var1[], byte var2[], byte cond[],
|
||||
boolean[] valid) {
|
||||
|
|
@ -212,12 +246,19 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for the given var1,var2,cond tuples of the multi-agent system
|
||||
* Add observations for the given var1,var2,cond tuples
|
||||
* of the variables
|
||||
* to our estimates of the pdfs.
|
||||
* This method signature allows multiple trials to have their
|
||||
* observations added to the PDFs by one method call.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @param var1 series of values for the first variable;
|
||||
* first index is time or observation number, second
|
||||
* index is trial (a second observation number if you will)
|
||||
* @param var2 series of values for the second variable,
|
||||
* indexed as per var1
|
||||
* @param cond series of values for the conditional variable,
|
||||
* indexed as per var1
|
||||
*/
|
||||
public void addObservations(int var1[][], int var2[][], int cond[][]) {
|
||||
int rows = var1.length;
|
||||
|
|
@ -237,12 +278,7 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local conditional MI from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double condMi = 0.0;
|
||||
double condMiCont = 0.0;
|
||||
|
|
@ -329,10 +365,10 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @return
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
* @return series of local conditional MI values
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int var1[], int var2[], int cond[]){
|
||||
int rows = var1.length;
|
||||
|
|
@ -367,12 +403,29 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average from the given observations,
|
||||
* assuming that the temporal relationship between variable1 and variable2-conditional
|
||||
* was destroyed, while variable2-conditional relationship was retained.
|
||||
* Generate a bootstrapped distribution of what the conditional MI would look like,
|
||||
* under a null hypothesis that the source values of our
|
||||
* samples had no relation to the destination value (in the
|
||||
* context of the conditional).
|
||||
*
|
||||
* @param numPermutationsToCheck number of new orderings of the variable1 to compare against
|
||||
* @return
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for MI,
|
||||
* conditional MI and TE.
|
||||
* <b>Note that this method currently fixes the relationship
|
||||
* between variable 2 and the conditional, and shuffles
|
||||
* variable 1 with respect to these.</b>
|
||||
* </p>
|
||||
*
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(int[], int[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* @param numPermutationsToCheck number of surrogate samples to bootstrap
|
||||
* to generate the distribution.
|
||||
* @return the distribution of conditional MI scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
|
|
@ -382,16 +435,46 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average from the given observations,
|
||||
* assuming that the temporal relationship between variable1 and variable2-conditional
|
||||
* was detroyed, while variable2-conditional relationship was retained.
|
||||
* Generate a bootstrapped distribution of what the conditional MI would look like,
|
||||
* under a null hypothesis that the source values of our
|
||||
* samples had no relation to the destination values.
|
||||
*
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for
|
||||
* a conditional mutual information. Basically, the marginal PDFs
|
||||
* of each marginal
|
||||
* are preserved, while their joint PDF is destroyed, and the
|
||||
* distribution of conditional MI under these conditions is generated.
|
||||
* <b>Note that this method currently fixes the relationship
|
||||
* between variable 2 and the conditional, and shuffles
|
||||
* variable 1 with respect to these.</b>
|
||||
* </p>
|
||||
* TODO Need to alter the method signature to allow callers to specify
|
||||
* which variable is shuffled. (Note to self: when doing this, will
|
||||
* need to update machine learning code to the new method signature)
|
||||
*
|
||||
* @param newOrderings the reorderings for variable1 to use
|
||||
* @return
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(double[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* <p>This method (in contrast to {@link #computeSignificance(int)})
|
||||
* allows the user to specify how to construct the surrogates,
|
||||
* such that repeatable results may be obtained.</p>
|
||||
*
|
||||
* @param newOrderings a specification of how to shuffle the values
|
||||
* of variable 1
|
||||
* to create the surrogates to generate the distribution with. The first
|
||||
* index is the permutation number (i.e. newOrderings.length is the number
|
||||
* of surrogate samples we use to bootstrap to generate the distribution here.)
|
||||
* Each array newOrderings[i] should be an array of length N (where
|
||||
* would be the value returned by {@link #getNumObservations()}),
|
||||
* containing a permutation of the values in 0..(N-1).
|
||||
* @return the distribution of conditional MI scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
* @throws Exception where the length of each permutation in newOrderings
|
||||
* is not equal to the number N samples that were previously supplied.
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) {
|
||||
|
||||
|
|
@ -456,38 +539,7 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
return measDistribution;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Compute the statistical significance of the conditional mutual information
|
||||
* result analytically, without creating a distribution
|
||||
* under the null hypothesis by bootstrapping.</p>
|
||||
*
|
||||
* <p>Brillinger (see reference below) showed that under the null hypothesis
|
||||
* of no source-destination relationship, the MI for two
|
||||
* discrete distributions follows a chi-square distribution with
|
||||
* degrees of freedom equal to the product of the number of discrete values
|
||||
* minus one, for each variable.</p>
|
||||
*
|
||||
* <p>Cheng extend this to show that for conditional MI, the number of
|
||||
* degrees of freedom for this distribution is:
|
||||
* (base1 - 1)*(base2 - 1)*condBase
|
||||
* </p>
|
||||
*
|
||||
* <p>Barnett and Bossomaier later echoed this for the transfer entropy
|
||||
* (which is of course a conditional MI)
|
||||
* </p>
|
||||
*
|
||||
* @return ChiSquareMeasurementDistribution object
|
||||
* This object contains the proportion of conditional MI scores from the distribution
|
||||
* which have higher or equal conditional 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}
|
||||
*/
|
||||
@Override
|
||||
public AnalyticMeasurementDistribution computeSignificance() {
|
||||
if (!condMiComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
|
@ -498,13 +550,13 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local conditional MI across given variables.
|
||||
* compute local conditional MI for given variables.
|
||||
* Return a temporal array of local values.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @return
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
* @return series of local conditional MI values
|
||||
*/
|
||||
public double[] computeLocal(int var1[], int var2[], int cond[]) {
|
||||
|
||||
|
|
@ -515,13 +567,12 @@ public class ConditionalMutualInformationCalculator extends InfoMeasureCalculato
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local conditional MI across given variables.
|
||||
* Returns the average
|
||||
* compute average conditional MI for a given set of variables.
|
||||
*
|
||||
* @param var1 values for the first variable
|
||||
* @param var2 values for the second variable
|
||||
* @param cond values for the conditional variable
|
||||
* @return
|
||||
* @param var1 series of values for the first variable
|
||||
* @param var2 series of values for the second variable
|
||||
* @param cond series of values for the conditional variable
|
||||
* @return average conditional MI for these values
|
||||
*/
|
||||
public double computeAverageLocal(int var1[], int var2[], int cond[]) {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,18 +23,51 @@ import infodynamics.utils.MatrixUtils;
|
|||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Implements <i>conditional</i> transfer entropy,
|
||||
* and <i>local conditional</i> transfer entropy
|
||||
* (see Lizier et al., PRE, 2008, and Lizier et al., Chaos, 2010).
|
||||
* This class can be used for to compute <i>complete</i> transfer entropy
|
||||
* (see Lizier et al, PRE, 2008) which conditions on <b>all</b>
|
||||
* other causal information contributors to the destination.</p>
|
||||
*
|
||||
* <p>Specifically, this implements the complete transfer entropy for
|
||||
* <i>discrete</i>-valued variables.</p>
|
||||
*
|
||||
* <p>Implements <b>conditional transfer entropy</b>
|
||||
* for univariate discrete time-series data.
|
||||
* That is, it is applied to <code>int[]</code> data, indexed
|
||||
* by time.
|
||||
* See Schreiber below for the definition of transfer entropy,
|
||||
* and Lizier et al (2008, 2010). for the definition of local transfer entropy
|
||||
* and conditional TE, which is TE conditioned on one or
|
||||
* more other potential sources.
|
||||
* This is also called complete TE when all other causal sources
|
||||
* are conditioned on.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Usage of the child classes implementing this interface is intended to follow this paradigm:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator via
|
||||
* {@link #ConditionalTransferEntropyCalculator(int, int, int)};</li>
|
||||
* <li>Initialise the calculator using
|
||||
* {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* the set of {@link #addObservations(int[], int[], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average TE: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>the local TE values for these samples: {@link #computeLocalOfPreviousObservations()}</li>
|
||||
* <li>local TE values for a specific set of samples: e.g.
|
||||
* {@link #computeLocalFromPreviousObservations(int[], int[])} etc.</li>
|
||||
* <li>the distribution of TE values under the null hypothesis
|
||||
* of no relationship between source and
|
||||
* destination values: {@link #computeSignificance(int)} or
|
||||
* {@link #computeSignificance(int[][])}.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[], int[])} or
|
||||
* {@link #computeAverageLocal(int[][], int)}.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>
|
||||
* The conditional sources (specified using either their
|
||||
* offsets from the destination variable or their absolute column numbers
|
||||
|
|
@ -43,53 +76,34 @@ import infodynamics.utils.RandomGenerator;
|
|||
* be incorrect.
|
||||
* </p>
|
||||
*
|
||||
* <p>Ideally, this class would extend ContextOfPastMeasure, however
|
||||
* <p><i>Note for developers</i>: Ideally, this class would extend ContextOfPastMeasure, however
|
||||
* by conditioning on other info contributors, we need to alter
|
||||
* the arrays pastCount and nextPastCount to consider all
|
||||
* conditioned variables (i.e. other sources) also.
|
||||
* </p>
|
||||
*
|
||||
* <p>Usage:
|
||||
* <ol>
|
||||
* <li>Construct: {@link #CompleteTransferEntropyCalculator(int, int)}</li>
|
||||
* <li>Initialise: {@link #initialise()}</li>
|
||||
* <li>Either:
|
||||
* <ol>
|
||||
* <li>Continuous accumulation of observations then measurement; call:
|
||||
* <ol>
|
||||
* <li>{@link #addObservations(int[][], int, int[])} or related calls
|
||||
* several times over - <b>note:</b> each method call adding
|
||||
* observations can be viewed as updating the PDFs; they do not
|
||||
* append the separate time series (this would be incorrect behaviour
|
||||
* for the transfer entropy, since the start of one time series
|
||||
* is not necessarily related to the end of the other).</li>
|
||||
* <li>The compute relevant quantities, e.g.
|
||||
* {@link #computeLocalFromPreviousObservations(int[][], int, int[])} or
|
||||
* {@link #computeAverageLocalOfObservations()}</li>
|
||||
* </ol>
|
||||
* <li>or Standalone computation from a single set of observations;
|
||||
* call e.g.: {@link #computeLocal(int[][], int, int[])} or
|
||||
* {@link #computeAverageLocal(int[][], int, int, int[])}.>/li>
|
||||
* </ol>
|
||||
* </ol>
|
||||
* </p>
|
||||
* TODO Add methods for passing in single time series.
|
||||
* This is done for addObservations, but not other routines.
|
||||
*
|
||||
* @see "Schreiber, Physical Review Letters 85 (2) pp.461-464, 2000;
|
||||
* <a href='http://dx.doi.org/10.1103/PhysRevLett.85.461'>download</a>
|
||||
* (for definition of transfer entropy)"
|
||||
* @see "Lizier, Prokopenko and Zomaya, Physical Review E 77, 026110, 2008;
|
||||
* <a href='http://dx.doi.org/10.1103/PhysRevE.77.026110'>download</a>
|
||||
* (for definition of <i>local</i> transfer entropy and
|
||||
* <i>complete</i> transfer entropy)"
|
||||
* @see "Lizier, Prokopenko and Zomaya, Chaos vol. 20, no. 3, 037109, 2010;
|
||||
* <a href='http://dx.doi.org/10.1063/1.3486801'>download</a>
|
||||
* (for definition of <i>conditional</i> transfer entropy)"
|
||||
*
|
||||
* @author Joseph Lizier, <a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>
|
||||
* TODO Implement AnalyticNullDistributionComputer
|
||||
*
|
||||
* TODO Add methods for passing in single time series
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. Schreiber, <a href="http://dx.doi.org/10.1103/PhysRevLett.85.461">
|
||||
* "Measuring information transfer"</a>,
|
||||
* Physical Review Letters 85 (2) pp.461-464, 2000.</li>
|
||||
* <li>J. T. Lizier, M. Prokopenko and A. Zomaya,
|
||||
* <a href="http://dx.doi.org/10.1103/PhysRevE.77.026110">
|
||||
* "Local information transfer as a spatiotemporal filter for complex systems"</a>
|
||||
* Physical Review E 77, 026110, 2008.</li>
|
||||
* <li>J. T. Lizier, M. Prokopenko and A. Zomaya,
|
||||
* <a href=http://dx.doi.org/10.1063/1.3486801">
|
||||
* "Information modification and particle collisions in distributed computation"</a>
|
||||
* Chaos 20, 3, 037109 (2010).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator {
|
||||
|
||||
|
|
@ -116,7 +130,7 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* @param base
|
||||
* @param history
|
||||
* @param numOtherInfoContributors
|
||||
*
|
||||
* @deprecated
|
||||
* @return
|
||||
*/
|
||||
public static ConditionalTransferEntropyCalculator
|
||||
|
|
@ -138,13 +152,15 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance
|
||||
*
|
||||
*
|
||||
* @param base
|
||||
* @param history
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedded history length of the destination to condition on -
|
||||
* this is k in Schreiber's notation.
|
||||
* @param numOtherInfoContributors number of information contributors
|
||||
* (other than the past of the destination, if history < 1,
|
||||
* of the source) to condition on.
|
||||
* (other than the past of the destination
|
||||
* or the source) to condition on.
|
||||
*/
|
||||
public ConditionalTransferEntropyCalculator
|
||||
(int base, int history, int numOtherInfoContributors) {
|
||||
|
|
@ -188,12 +204,7 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
|
||||
|
|
@ -204,11 +215,16 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single source-destination-conditionals set
|
||||
* Add observations for source-destination-conditionals time-series
|
||||
* to our estimates of the pdfs.
|
||||
*
|
||||
* @param source source time series
|
||||
* @param dest destination time series
|
||||
* @param conditionals conditionals multivariate time series
|
||||
* @param dest destination time series. Must be of same length as
|
||||
* source.
|
||||
* @param conditionals conditionals multivariate time series,
|
||||
* indexed first by time, then by variable number.
|
||||
* Must be of same length in time as source, and must be
|
||||
* {@link #numOtherInfoContributors} conditionals here.
|
||||
*/
|
||||
public void addObservations(int[] source, int[] dest, int[][] conditionals)
|
||||
throws Exception {
|
||||
|
|
@ -272,10 +288,16 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* {@link MatrixUtils#computeCombinedValues(int[][], int)}. This cannot be
|
||||
* checked here however, so use at your own risk!
|
||||
* </p>
|
||||
*
|
||||
* @param source source time series
|
||||
* @param dest destination time series
|
||||
* @param conditionals conditionals univariate time series - it is assumed
|
||||
* that the user has combined the values of the multivariate conditionals time series
|
||||
* @param dest destination time series. Must be of same length as
|
||||
* source.
|
||||
* @param conditionals conditionals univariate time series,
|
||||
* indexed first by time, then by variable number.
|
||||
* Must be of same length in time as source, and we must have
|
||||
* either {@link #numOtherInfoContributors}=1, or the user has
|
||||
* combined the values of the multivariate conditionals time series
|
||||
* into single (unique) values at each time step (this is not checked however).
|
||||
*/
|
||||
public void addObservations(int[] source, int[] dest, int[] conditionals)
|
||||
throws Exception {
|
||||
|
|
@ -321,22 +343,42 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* Add observations in to our estimates of the pdfs
|
||||
* from a multivariate time-series of homogeneous variables.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs, and all are assumed
|
||||
* to have other info contributors at same offsets.
|
||||
*
|
||||
* @param states
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. src i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors.
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param j number of columns to compute transfer entropy across
|
||||
* (i.e. for each destination variable i, we have a source
|
||||
* at i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors
|
||||
* from each destination.
|
||||
* (i.e. offsets from each other information source to the destination -
|
||||
* offset is signed the same way as j!)
|
||||
* the offset is signed the same way as j!)
|
||||
* othersOffsets is permitted to include j, it will be ignored.
|
||||
*/
|
||||
public void addObservations(int states[][], int j, int otherSourcesToDestOffsets[]) {
|
||||
addObservations(states, j, otherSourcesToDestOffsets, false);
|
||||
}
|
||||
/**
|
||||
* Private method to implement {@link #addObservations(int[][], int, int[])}
|
||||
*
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param j number of columns to compute transfer entropy across
|
||||
* (i.e. for each destination variable i, we have a source
|
||||
* at i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors
|
||||
* from each destination.
|
||||
* (i.e. offsets from each other information source to the destination -
|
||||
* the offset is signed the same way as j!)
|
||||
* othersOffsets is permitted to include j, it will be ignored.
|
||||
* @param cleanedOthers whether it has been checked if j is included in otherSourcesToDestOffsets
|
||||
* or not
|
||||
*/
|
||||
private void addObservations(int states[][], int j, int otherSourcesToDestOffsets[], boolean cleanedOthers) {
|
||||
|
||||
int[] cleanedOthersOffsets;
|
||||
|
|
@ -392,16 +434,36 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single source-destination pair of the multi-agent system
|
||||
* Add observations for a single source-destination-conditionals set of the
|
||||
* multivariate time series.
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param sourceCol column index of the source
|
||||
* @param destCol column index of the destination
|
||||
* @param othersAbsolute column indices of the conditional variables.
|
||||
* othersAbsolute is permitted to include sourceCol or destCol (if k>0),
|
||||
* they will be ignored.
|
||||
*/
|
||||
public void addObservations(int states[][], int sourceCol, int destCol, int[] othersAbsolute) {
|
||||
addObservations(states, sourceCol, destCol, othersAbsolute, false);
|
||||
}
|
||||
/**
|
||||
* Private method to implement {@link #addObservations(int[][], int, int, int[])}
|
||||
*
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param sourceCol column index of the source
|
||||
* @param destCol column index of the destination
|
||||
* @param othersAbsolute column indices of the conditional variables.
|
||||
* othersAbsolute is permitted to include sourceCol or destCol (if k>0),
|
||||
* they will be ignored.
|
||||
* @param cleanedOthers whether it has been checked if othersAbsolute
|
||||
* contains sourceCol or destCol
|
||||
*/
|
||||
private void addObservations(int states[][], int sourceCol, int destCol, int[] othersAbsolute, boolean cleanedOthers) {
|
||||
|
||||
int[] cleanedOthersAbsolute;
|
||||
|
|
@ -451,12 +513,7 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local transfer entropy from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double te = 0.0;
|
||||
double teCont = 0.0;
|
||||
|
|
@ -508,14 +565,27 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average TE from the given observations
|
||||
* Generate a bootstrapped distribution of what the
|
||||
* conditional TE would look like,
|
||||
* under a null hypothesis that the source values of our
|
||||
* samples had no relation to the destination value
|
||||
* (in the context of the destination past and conditionals).
|
||||
*
|
||||
* This is as per Chavez et. al., "Statistical assessment of nonlinear causality:
|
||||
* application to epileptic EEG signals", Journal of Neuroscience Methods 124 (2003) 113-128.
|
||||
* except that we've using conditional/complete TE here.
|
||||
*
|
||||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for MI,
|
||||
* conditional MI and TE.
|
||||
* </p>
|
||||
*
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(int[], int[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* @param numPermutationsToCheck number of surrogate samples to bootstrap
|
||||
* to generate the distribution.
|
||||
* @return the distribution of conditional TE scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
double actualTE = computeAverageLocalOfObservations();
|
||||
|
|
@ -604,26 +674,47 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Computes local complete transfer entropy for the given
|
||||
* Computes local conditional transfer entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 2D multivariate time series of states
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* i.e. offset of destination from the source
|
||||
* (i.e. src i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors.
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param j number of columns to compute transfer entropy across
|
||||
* (i.e. for each destination variable i, we have a source
|
||||
* at i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors
|
||||
* from each destination.
|
||||
* (i.e. offsets from each other information source to the destination -
|
||||
* offset is signed the same way as j!)
|
||||
* the offset is signed the same way as j!)
|
||||
* othersOffsets is permitted to include j, it will be ignored.
|
||||
* @return
|
||||
* @return 2D time-series of local conditional TE values (indexed
|
||||
* as per states)
|
||||
*/
|
||||
public double[][] computeLocalFromPreviousObservations
|
||||
(int states[][], int j, int otherSourcesToDestOffsets[]){
|
||||
|
||||
return computeLocalFromPreviousObservations(states, j, otherSourcesToDestOffsets, false);
|
||||
}
|
||||
/**
|
||||
* Private method to implement {@link #computeLocalFromPreviousObservations(int[][], int, int[])}
|
||||
*
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param j number of columns to compute transfer entropy across
|
||||
* (i.e. for each destination variable i, we have a source
|
||||
* at i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors
|
||||
* from each destination.
|
||||
* (i.e. offsets from each other information source to the destination -
|
||||
* the offset is signed the same way as j!)
|
||||
* othersOffsets is permitted to include j, it will be ignored.
|
||||
* @param cleanedOthers whether it has been checked if j is included in otherSourcesToDestOffsets
|
||||
* or not
|
||||
* @return 2D time-series of local conditional TE values (indexed
|
||||
* as per states)
|
||||
*/
|
||||
private double[][] computeLocalFromPreviousObservations
|
||||
(int states[][], int j, int othersOffsets[], boolean cleanedOthers){
|
||||
|
||||
|
|
@ -697,14 +788,34 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* sent in via the addObservations method.
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states
|
||||
* @return
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param sourceCol column index of the source
|
||||
* @param destCol column index of the destination
|
||||
* @param othersAbsolute column indices of the conditional variables.
|
||||
* othersAbsolute is permitted to include sourceCol or destCol (if k>0),
|
||||
* they will be ignored.
|
||||
* @return time-series of local conditional TE values
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations
|
||||
(int states[][], int sourceCol, int destCol, int[] othersAbsolute){
|
||||
|
||||
return computeLocalFromPreviousObservations(states, sourceCol, destCol, othersAbsolute, false);
|
||||
}
|
||||
/**
|
||||
* Private method to implement {@link #computeLocalFromPreviousObservations(int[][], int, int, int[])}
|
||||
*
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param sourceCol column index of the source
|
||||
* @param destCol column index of the destination
|
||||
* @param othersAbsolute column indices of the conditional variables.
|
||||
* othersAbsolute is permitted to include sourceCol or destCol (if k>0),
|
||||
* they will be ignored.
|
||||
* @param cleanedOthers whether it has been checked if othersAbsolute
|
||||
* contains sourceCol or destCol
|
||||
* @return time-series of local conditional TE values
|
||||
*/
|
||||
private double[] computeLocalFromPreviousObservations
|
||||
(int states[][], int sourceCol, int destCol, int[] othersAbsolute, boolean cleanedOthers){
|
||||
|
||||
|
|
@ -770,17 +881,24 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 2D spatiotemporal
|
||||
* compute local conditional transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param j - TE across j cells to the right
|
||||
* @param otherSourcesToDestOffsets - column offsets from other causal info contributors
|
||||
* to the destination
|
||||
* @return
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param j number of columns to compute transfer entropy across
|
||||
* (i.e. for each destination variable i, we have a source
|
||||
* at i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors
|
||||
* from each destination.
|
||||
* (i.e. offsets from each other information source to the destination -
|
||||
* the offset is signed the same way as j!)
|
||||
* othersOffsets is permitted to include j, it will be ignored.
|
||||
* @return 2D time-series of local conditional TE values (indexed
|
||||
* as per states)
|
||||
*/
|
||||
public double[][] computeLocal(int states[][], int j, int[] otherSourcesToDestOffsets) {
|
||||
|
||||
|
|
@ -792,16 +910,22 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 2D spatiotemporal
|
||||
* compute average conditional transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param j - TE across j cells to the right
|
||||
* @param otherSourcesToDestOffsets - column offsets from other causal info contributors
|
||||
* to the destination
|
||||
* @return
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param j number of columns to compute transfer entropy across
|
||||
* (i.e. for each destination variable i, we have a source
|
||||
* at i-j, dest i: transfer is j cells to the right)
|
||||
* @param otherSourcesToDestOffsets offsets of the other information contributors
|
||||
* from each destination.
|
||||
* (i.e. offsets from each other information source to the destination -
|
||||
* the offset is signed the same way as j!)
|
||||
* othersOffsets is permitted to include j, it will be ignored.
|
||||
* @return average conditional TE from these observations
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int j, int[] otherSourcesToDestOffsets) {
|
||||
|
||||
|
|
@ -812,17 +936,21 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* compute local conditional transfer entropy for a specific set of
|
||||
* source-destination-conditionals in a multivariate time-series.
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method suitable for heterogeneous agents
|
||||
* First history rows are zeros.
|
||||
* This method suitable for heterogeneous agents.
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param sourceCol - column index for the source agent
|
||||
* @param destCol - column index for the destination agent
|
||||
* @param othersAbsolute - column indices for other causal info contributors
|
||||
* @return
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param sourceCol column index of the source
|
||||
* @param destCol column index of the destination
|
||||
* @param othersAbsolute column indices of the conditional variables.
|
||||
* othersAbsolute is permitted to include sourceCol or destCol (if k>0),
|
||||
* they will be ignored.
|
||||
* @return time-series of local conditional TE values for these
|
||||
* observations
|
||||
*/
|
||||
public double[] computeLocal(int states[][], int sourceCol, int destCol, int[] othersAbsolute) {
|
||||
|
||||
|
|
@ -835,16 +963,18 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Returns the average
|
||||
* compute average conditional transfer entropy for a specific set of
|
||||
* source-destination-conditionals in a multivariate time-series.
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param sourceCol - column index for the source agent
|
||||
* @param destCol - column index for the destination agent
|
||||
* @param othersAbsolute - column indices for other causal info contributors
|
||||
* @return
|
||||
* @param states multivariate time series, indexed first by time
|
||||
* then by variable number.
|
||||
* @param sourceCol column index of the source
|
||||
* @param destCol column index of the destination
|
||||
* @param othersAbsolute column indices of the conditional variables.
|
||||
* othersAbsolute is permitted to include sourceCol or destCol (if k>0),
|
||||
* they will be ignored.
|
||||
* @return average conditional transfer entropy for these observations
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int sourceCol, int destCol, int[] othersAbsolute) {
|
||||
|
||||
|
|
@ -854,15 +984,19 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Counts the information contributors to this node which
|
||||
* are not equal to the source to dest offset j or the node itself (offset 0,
|
||||
* node itself not included only when removeDest is set to true)
|
||||
* Counts the unique information contributors to this node which
|
||||
* are not equal to the source at offset j from the destination,
|
||||
* or the node itself (offset 0,
|
||||
* node itself not included only when removeDest is set to true).
|
||||
*
|
||||
* <p>This is primarily intended for use inside the method, but
|
||||
* made public as a utility.</p>
|
||||
*
|
||||
* @param otherSourcesToDestOffsets array of offsets of the destination from each source
|
||||
* @param j offset of the destination from the source
|
||||
* @param removeDest remove the destination itself from the count
|
||||
* of offset others.
|
||||
* @return
|
||||
* @return the number of unique such sources
|
||||
*/
|
||||
public static int countOfOffsetOthers(int[] otherSourcesToDestOffsets, int j,
|
||||
boolean removeDest) {
|
||||
|
|
@ -881,12 +1015,15 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* are not equal to src or the node itself (offset 0,
|
||||
* node itself not included only when removeDest is set to true)
|
||||
*
|
||||
* @param others
|
||||
* @param src
|
||||
* @param dest
|
||||
* <p>This is primarily intended for use inside the method, but
|
||||
* made public as a utility.</p>
|
||||
*
|
||||
* @param others array of source indices
|
||||
* @param src current source index we are considering
|
||||
* @param dest current dest index we are considering
|
||||
* @param removeDest remove the destination itself from the count
|
||||
* of absolute others.
|
||||
* @return
|
||||
* @return the number of unique such sources
|
||||
*/
|
||||
public static int countOfAbsoluteOthers(int[] others, int src, int dest,
|
||||
boolean removeDest) {
|
||||
|
|
@ -908,7 +1045,8 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* @param j offset from the source to the destination
|
||||
* @param removeDest remove the destination itself from the count
|
||||
* of absolute others.
|
||||
* @return
|
||||
* @return whether the number of such sources matches what we expect
|
||||
* @throws Exception if the number of such sources does not match.
|
||||
*/
|
||||
public boolean confirmEnoughOffsetOthers(int[] othersOffsets, int j,
|
||||
boolean removeDest) {
|
||||
|
|
@ -923,12 +1061,13 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* Check that the supplied array of absolutes as other info
|
||||
* contributors is long enough compared to our expectation
|
||||
*
|
||||
* @param othersAbsolute
|
||||
* @param src
|
||||
* @param dest
|
||||
* @param othersAbsolute array of source indices
|
||||
* @param src current source index we are considering
|
||||
* @param dest current dest index we are considering
|
||||
* @param removeDest remove the destination itself from the count
|
||||
* of absolute others.
|
||||
* @return
|
||||
* @return whether the number of such sources matches what we expect
|
||||
* @throws Exception if the number of such sources does not match.
|
||||
*/
|
||||
public boolean confirmEnoughAbsoluteOthers(int[] othersAbsolute, int src,
|
||||
int dest, boolean removeDest) {
|
||||
|
|
@ -951,7 +1090,8 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* other sources (if it is there). Should not be done
|
||||
* if k == 0 (because then the destination is not included
|
||||
* in the past history)
|
||||
* @return
|
||||
* @return othersOffsets with entries for the offending
|
||||
* contributors removed (i.e. array may be shortened)
|
||||
*/
|
||||
public int[] cleanOffsetOthers(int[] othersOffsets, int j, boolean removeDest) {
|
||||
int[] cleaned = new int[numOtherInfoContributors];
|
||||
|
|
@ -984,14 +1124,15 @@ public class ConditionalTransferEntropyCalculator extends InfoMeasureCalculator
|
|||
* removed only if removeDest is true).
|
||||
* Checks that there are enough other information contributors.
|
||||
*
|
||||
* @param others
|
||||
* @param src
|
||||
* @param dest
|
||||
* @param others array of source indices
|
||||
* @param src current source index we are considering
|
||||
* @param dest current dest index we are considering
|
||||
* @param removeDest Remove the destination itself from the cleaned
|
||||
* other sources (if it is there). Should not be done
|
||||
* if k == 0 (because then the destination is not included
|
||||
* in the past history)
|
||||
* @return
|
||||
* @return others with entries for the offending
|
||||
* contributors removed (i.e. array may be shortened)
|
||||
*/
|
||||
public int[] cleanAbsoluteOthers(int[] others, int src, int dest,
|
||||
boolean removeDest) {
|
||||
|
|
|
|||
|
|
@ -22,38 +22,55 @@ import infodynamics.utils.MathsUtils;
|
|||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* @author Joseph Lizier
|
||||
* A base class for calculators computing measures which
|
||||
* require knowledge of the embedded past state of a univariate
|
||||
* discrete (ie int[]) variable.
|
||||
*
|
||||
* Info theoretic measure calculator base class for
|
||||
* measures which require the context of the past
|
||||
* history of the destination variable.
|
||||
* Usage is as per {@link InfoMeasureCalculator}, but with some
|
||||
* extra utility functions provided for computing embedding vectors.
|
||||
*
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations before computing :
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations() or computeAverageLocalOfObservations()
|
||||
* 2. Standalone computation from a single set of observations:
|
||||
* Call: computeLocal() or computeAverageLocal()
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* joseph.lizier at gmail.com
|
||||
* http://lizier.me/joseph/
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public abstract class ContextOfPastMeasureCalculator extends
|
||||
InfoMeasureCalculator {
|
||||
|
||||
protected int k = 0; // history length k.
|
||||
/**
|
||||
* History length for the embedding
|
||||
*/
|
||||
protected int k = 0;
|
||||
/**
|
||||
* Do not create storage
|
||||
* for observations of the embedded past
|
||||
*/
|
||||
protected boolean noObservationStorage = false;
|
||||
/**
|
||||
* Counts of (next,embedded_past) tuples
|
||||
*/
|
||||
protected int[][] nextPastCount = null; // Count for (i[t+1], i[t]) tuples
|
||||
/**
|
||||
* Counts of (embedded_past) tuples
|
||||
*/
|
||||
protected int[] pastCount = null; // Count for i[t]
|
||||
/**
|
||||
* Counts of (next) observations
|
||||
*/
|
||||
protected int[] nextCount = null; // count for i[t+1]
|
||||
protected int[] maxShiftedValue = null; // states * (base^(k-1))
|
||||
/**
|
||||
* Cached value maxShiftedValue[i] is i * (base^(k-1))
|
||||
*/
|
||||
protected int[] maxShiftedValue = null; //
|
||||
/**
|
||||
* Cached value of base^k
|
||||
*/
|
||||
protected int base_power_k = 0;
|
||||
|
||||
/**
|
||||
* @param base
|
||||
* Construct an instance
|
||||
*
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedding length
|
||||
*/
|
||||
public ContextOfPastMeasureCalculator(int base, int history) {
|
||||
this(base, history, false);
|
||||
|
|
@ -64,9 +81,12 @@ public abstract class ContextOfPastMeasureCalculator extends
|
|||
* In general, only needs to be explicitly called if child classes
|
||||
* do not wish to create the observation arrays.
|
||||
*
|
||||
* @param base
|
||||
* @param history
|
||||
* @param dontCreateObsStorage
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedding length
|
||||
* @param dontCreateObsStorage do not create storage
|
||||
* for observations of the embedded past (as the child
|
||||
* class is signalling that it does not need it)
|
||||
*/
|
||||
protected ContextOfPastMeasureCalculator(int base, int history, boolean dontCreateObsStorage) {
|
||||
super(base);
|
||||
|
|
@ -100,12 +120,7 @@ public abstract class ContextOfPastMeasureCalculator extends
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise() {
|
||||
super.initialise();
|
||||
|
||||
|
|
@ -117,12 +132,15 @@ public abstract class ContextOfPastMeasureCalculator extends
|
|||
}
|
||||
|
||||
/**
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* Utility function to compute the combined embedded
|
||||
* past values of x up to and including time step t
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
*
|
||||
* @param x
|
||||
* @param t
|
||||
* @return
|
||||
* @param x time-series data
|
||||
* @param t compute embedding vector up to and
|
||||
* including index t
|
||||
* @return int value representing the embedding vector
|
||||
* translated into a unique integer
|
||||
*/
|
||||
public int computePastValue(int[] x, int t) {
|
||||
int pastVal = 0;
|
||||
|
|
@ -134,37 +152,50 @@ public abstract class ContextOfPastMeasureCalculator extends
|
|||
}
|
||||
|
||||
/**
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* Utility function to compute the combined embedded
|
||||
* past values of x up to and including time step t
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
* where x is a column in data
|
||||
*
|
||||
* @param x
|
||||
* @param agentNumber
|
||||
* @param t
|
||||
* @return
|
||||
* @param data multivariate time-series data
|
||||
* (first index is time, second is variable number)
|
||||
* @param columnNumber which column to embed
|
||||
* @param t compute embedding vector up to and
|
||||
* including index t
|
||||
* @return int value representing the embedding vector
|
||||
* translated into a unique integer
|
||||
*/
|
||||
public int computePastValue(int[][] x, int agentNumber, int t) {
|
||||
public int computePastValue(int[][] data, int columnNumber, int t) {
|
||||
int pastVal = 0;
|
||||
for (int p = 0; p < k; p++) {
|
||||
pastVal *= base;
|
||||
pastVal += x[t - k + 1 + p][agentNumber];
|
||||
pastVal += data[t - k + 1 + p][columnNumber];
|
||||
}
|
||||
return pastVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to compute the combined past values of x up to and including time step t
|
||||
* Utility function to compute the combined embedded
|
||||
* past values of x up to and including time step t
|
||||
* (i.e. (x_{t-k+1}, ... ,x_{t-1},x_{t}))
|
||||
* where x is a time-series for a given row and
|
||||
* column in data
|
||||
*
|
||||
* @param x
|
||||
* @param agentNumber
|
||||
* @param t
|
||||
* @return
|
||||
* @param data multivariate time-series data
|
||||
* (first index is time, second is row number for the variable
|
||||
* and third is column number for the variable)
|
||||
* @param rowNumber row number of the variable to embed
|
||||
* @param columnNumber column number of the variable to embed
|
||||
* @param t compute embedding vector up to and
|
||||
* including index t
|
||||
* @return int value representing the embedding vector
|
||||
* translated into a unique integer
|
||||
*/
|
||||
public int computePastValue(int[][][] x, int agentRow, int agentColumn, int t) {
|
||||
public int computePastValue(int[][][] data, int rowNumber, int columnNumber, int t) {
|
||||
int pastVal = 0;
|
||||
for (int p = 0; p < k; p++) {
|
||||
pastVal *= base;
|
||||
pastVal += x[t - k + 1 + p][agentRow][agentColumn];
|
||||
pastVal += data[t - k + 1 + p][rowNumber][columnNumber];
|
||||
}
|
||||
return pastVal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,30 +21,39 @@ package infodynamics.measures.discrete;
|
|||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* <p>Univariate entropy calculator</p>
|
||||
* <p>Entropy calculator for univariate discrete (int[]) data.</p>
|
||||
*
|
||||
* <p>Usage:
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Continuous accumulation of observations. Call:
|
||||
* <ol>
|
||||
* <li>{@link #initialise()};</li>
|
||||
* <li>then supply the observations using any of the addObservations()
|
||||
* methods (several times over), e.g. {@link #addObservations(int[][])};</li>
|
||||
* <li>then when all observations have been added, call any of the
|
||||
* compute methods (several times over), e.g.:
|
||||
* {@link #computeLocalFromPreviousObservations(int[][])}</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* <li>Standalone mode. Call:
|
||||
* <ol>
|
||||
* <li>one of the standalone methods which supply observations
|
||||
* and compute at once, e.g. {@link #computeAverageLocal(int[][])}.</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* </ol></p>
|
||||
* <li>Construct the calculator: {@link #EntropyCalculator(int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average entropy: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local entropy values, such as {@link #computeLocal(int[])};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[])},
|
||||
* {@link #computeAverageLocal(int[])} etc.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. M. Cover and J. A. Thomas, 'Elements of Information
|
||||
Theory' (John Wiley & Sons, New York, 1991).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class EntropyCalculator extends InfoMeasureCalculator
|
||||
implements SingleAgentMeasure
|
||||
|
|
@ -56,10 +65,12 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
* User was formerly forced to create new instances through this factory method.
|
||||
* Retained for backwards compatibility.
|
||||
*
|
||||
* @param base
|
||||
* @param blocksize
|
||||
*
|
||||
* @return
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param blocksize number of consecutive joint values to include
|
||||
* in the calculation.
|
||||
* @deprecated
|
||||
* @return a new EntropyCalculator
|
||||
*/
|
||||
public static EntropyCalculator newInstance(int base, int blocksize) {
|
||||
if (blocksize > 1) {
|
||||
|
|
@ -73,8 +84,10 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Contruct a new instance
|
||||
*
|
||||
* @param base
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
*/
|
||||
public EntropyCalculator(int base) {
|
||||
|
||||
|
|
@ -84,22 +97,13 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
stateCount = new int[base];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
MatrixUtils.fill(stateCount, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
*
|
||||
* @param states 1st index is time
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[]) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -112,13 +116,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][]) {
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -134,13 +132,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][]) {
|
||||
int timeSteps = states.length;
|
||||
if (timeSteps == 0) {
|
||||
|
|
@ -165,15 +157,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param agentNumber
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][], int agentNumber) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -186,16 +170,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param agentIndex1
|
||||
* @param agentIndex2
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
int timeSteps = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -209,8 +184,9 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the current count for the given value
|
||||
*
|
||||
* @param stateVal
|
||||
* @param stateVal given value
|
||||
* @return count of observations of the given state
|
||||
*/
|
||||
public int getStateCount(int stateVal) {
|
||||
|
|
@ -218,20 +194,16 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the current probability for the given value
|
||||
*
|
||||
* @param stateVal
|
||||
* @param stateVal given value
|
||||
* @return probability of the given state
|
||||
*/
|
||||
public double getStateProbability(int stateVal) {
|
||||
return (double) stateCount[stateVal] / (double) observations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average entropy from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return the average entropy
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double ent = 0.0;
|
||||
double entCont = 0.0;
|
||||
|
|
@ -260,14 +232,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
return ent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
*
|
||||
* @param states index is time
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[]){
|
||||
int rows = states.length;
|
||||
|
||||
|
|
@ -292,15 +257,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][] computeLocalFromPreviousObservations(int states[][]){
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -328,15 +285,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][][] computeLocalFromPreviousObservations(int states[][][]){
|
||||
int timeSteps = states.length;
|
||||
int agentRows, agentColumns;
|
||||
|
|
@ -377,16 +326,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states
|
||||
* @param agentNumber
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int agentNumber){
|
||||
int rows = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
@ -412,17 +352,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @param agentIndex1
|
||||
* @param agentIndex2
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][], int agentIndex1, int agentIndex2){
|
||||
int timeSteps = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
@ -449,16 +379,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure across a 1D temporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 1D temporal array of local values.
|
||||
* First history rows are zeros
|
||||
*
|
||||
* @param states - 1D array of states
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final double[] computeLocal(int states[]) {
|
||||
|
||||
initialise();
|
||||
|
|
@ -466,16 +387,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final double[][] computeLocal(int states[][]) {
|
||||
|
||||
initialise();
|
||||
|
|
@ -483,16 +395,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure across a 3D spatiotemporal
|
||||
* array of the states of 2D homogeneous agents
|
||||
* Return a 3D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final double[][][] computeLocal(int states[][][]) {
|
||||
|
||||
initialise();
|
||||
|
|
@ -500,15 +403,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure across a 1D temporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
*
|
||||
* @param states - 1D array of states
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final double computeAverageLocal(int states[]) {
|
||||
|
||||
initialise();
|
||||
|
|
@ -516,16 +411,7 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final double computeAverageLocal(int states[][]) {
|
||||
|
||||
initialise();
|
||||
|
|
@ -533,92 +419,37 @@ public class EntropyCalculator extends InfoMeasureCalculator
|
|||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure across a 3D spatiotemporal
|
||||
* array of the states of 2D homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public final double computeAverageLocal(int states[][][]) {
|
||||
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure for one agent in a 2D spatiotemporal
|
||||
* array of the states of agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method should be used for heterogeneous agents
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param col - column number of the agent in the states array
|
||||
* @return
|
||||
*/
|
||||
public final double[] computeLocalAtAgent(int states[][], int col) {
|
||||
|
||||
@Override
|
||||
public final double[] computeLocal(int states[][], int col) {
|
||||
initialise();
|
||||
addObservations(states, col);
|
||||
return computeLocalFromPreviousObservations(states, col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure for one agent in a 2D spatiotemporal
|
||||
* array of the states of agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method should be used for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @param agentIndex1
|
||||
* @param agentIndex2
|
||||
* @return
|
||||
*/
|
||||
public final double[] computeLocalAtAgent(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
|
||||
@Override
|
||||
public final double[] computeLocal(int states[][][],
|
||||
int agentIndex1, int agentIndex2) {
|
||||
initialise();
|
||||
addObservations(states, agentIndex1, agentIndex2);
|
||||
return computeLocalFromPreviousObservations(states, agentIndex1, agentIndex2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure
|
||||
* for a single agent
|
||||
* Returns the average
|
||||
* This method suitable for heterogeneous agents
|
||||
* @param states - 2D array of states
|
||||
* @param col - column number of the agent in the states array
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final double computeAverageLocalAtAgent(int states[][], int col) {
|
||||
@Override
|
||||
public final double computeAverageLocal(int states[][], int col) {
|
||||
initialise();
|
||||
addObservations(states, col);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure
|
||||
* for a single agent
|
||||
* Returns the average
|
||||
* This method suitable for heterogeneous agents
|
||||
* @param states - 2D array of states
|
||||
* @param agentIndex1
|
||||
* @param agentIndex2
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final double computeAverageLocalAtAgent(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
@Override
|
||||
public final double computeAverageLocal(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
initialise();
|
||||
addObservations(states, agentIndex1, agentIndex2);
|
||||
return computeAverageLocalOfObservations();
|
||||
|
|
|
|||
|
|
@ -19,18 +19,48 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
/**
|
||||
* Compute average and local entropy rates
|
||||
*
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localActiveInformation()
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* <p>Entropy rate calculator for univariate discrete (int[]) data
|
||||
* (ie computes entropy over blocks of consecutive states in time).
|
||||
* Implements entropy rate as entropy of next state
|
||||
* conditional on the embedded past (as per the alternative
|
||||
* definition used by Crutchfield and Feldman, see below)
|
||||
* rather than the limiting rate of block entropy over block size.</p>
|
||||
*
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator: {@link #EntropyRateCalculator(int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average entropy: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local entropy values, such as {@link #computeLocal(int[])};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[])},
|
||||
* {@link #computeAverageLocal(int[])} etc.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. M. Cover and J. A. Thomas, 'Elements of Information
|
||||
Theory' (John Wiley & Sons, New York, 1991).</li>
|
||||
* <li>J. P. Crutchfield, D. P. Feldman,
|
||||
* <a href="http://dx.doi.org/10.1063/1.1530990">
|
||||
* "Regularities Unseen, Randomness Observed: Levels of Entropy Convergence"</a>,
|
||||
* Chaos, Vol. 13, No. 1. (2003), pp. 25-54.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalculator {
|
||||
|
||||
|
|
@ -40,26 +70,54 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
*
|
||||
* @param base
|
||||
* @param history
|
||||
*
|
||||
* @deprecated
|
||||
* @return
|
||||
*/
|
||||
public static EntropyRateCalculator newInstance(int base, int history) {
|
||||
return new EntropyRateCalculator(base, history);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance
|
||||
*
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedded history length of the destination to condition on -
|
||||
* this is k in Schreiber's notation.
|
||||
*/
|
||||
public EntropyRateCalculator(int base, int history) {
|
||||
|
||||
super(base, history);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int[] states) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
observations += (rows - k);
|
||||
|
||||
// Initialise and store the current previous value for each column
|
||||
int prevVal = 0;
|
||||
for (int p = 0; p < k; p++) {
|
||||
prevVal *= base;
|
||||
prevVal += states[p];
|
||||
}
|
||||
|
||||
// 1. Count the tuples observed
|
||||
int nextVal;
|
||||
for (int r = k; r < rows; r++) {
|
||||
// Add to the count for this particular transition:
|
||||
// (cell's assigned as above)
|
||||
nextVal = states[r];
|
||||
nextPastCount[nextVal][prevVal]++;
|
||||
pastCount[prevVal]++;
|
||||
// Update the previous value:
|
||||
prevVal -= maxShiftedValue[states[r-k]];
|
||||
prevVal *= base;
|
||||
prevVal += states[r];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addObservations(int states[][]) {
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -93,13 +151,7 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][]) {
|
||||
int timeSteps = states.length;
|
||||
if (timeSteps == 0) {
|
||||
|
|
@ -144,14 +196,7 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][], int col) {
|
||||
int rows = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -180,14 +225,7 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][][], int agentIndex1, int agentIndex2) {
|
||||
int timeSteps = states.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -216,12 +254,7 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local active information storage from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double entRate = 0.0;
|
||||
double entRateCont = 0.0;
|
||||
|
|
@ -257,15 +290,48 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
return entRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy rate for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int[] states) {
|
||||
int rows = states.length;
|
||||
|
||||
// Allocate for all rows even though we'll leave the first ones as zeros
|
||||
double[] localEntRate = new double[rows];
|
||||
average = 0;
|
||||
max = 0;
|
||||
min = 0;
|
||||
|
||||
// Initialise and store the current previous value for each column
|
||||
int prevVal = 0;
|
||||
for (int p = 0; p < k; p++) {
|
||||
prevVal *= base;
|
||||
prevVal += states[p];
|
||||
}
|
||||
|
||||
int nextVal;
|
||||
double logTerm = 0.0;
|
||||
for (int r = k; r < rows; r++) {
|
||||
nextVal = states[r];
|
||||
logTerm = ( (double) nextPastCount[nextVal][prevVal] ) /
|
||||
( (double) pastCount[prevVal] );
|
||||
// Entropy rate takes the negative log:
|
||||
localEntRate[r] = - Math.log(logTerm) / log_2;
|
||||
average += localEntRate[r];
|
||||
if (localEntRate[r] > max) {
|
||||
max = localEntRate[r];
|
||||
} else if (localEntRate[r] < min) {
|
||||
min = localEntRate[r];
|
||||
}
|
||||
// Update the previous value:
|
||||
prevVal -= maxShiftedValue[states[r-k]];
|
||||
prevVal *= base;
|
||||
prevVal += states[r];
|
||||
}
|
||||
average = average/(double) (rows - k);
|
||||
|
||||
return localEntRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[][] computeLocalFromPreviousObservations(int states[][]){
|
||||
int rows = states.length;
|
||||
int columns = states[0].length;
|
||||
|
|
@ -308,19 +374,10 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
}
|
||||
average = average/(double) (columns * (rows - k));
|
||||
|
||||
return localEntRate;
|
||||
|
||||
return localEntRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy rate for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[][][] computeLocalFromPreviousObservations(int states[][][]){
|
||||
int timeSteps = states.length;
|
||||
int agentRows = states[0].length;
|
||||
|
|
@ -370,18 +427,9 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
average = average/(double) (agentRows * agentColumns * (timeSteps - k));
|
||||
|
||||
return localEntRate;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy rate for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int col){
|
||||
int rows = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
@ -424,15 +472,7 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes local entropy rate for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][], int agentIndex1, int agentIndex2){
|
||||
int timeSteps = states.length;
|
||||
//int columns = states[0].length;
|
||||
|
|
@ -473,5 +513,5 @@ public class EntropyRateCalculator extends SingleAgentMeasureInContextOfPastCalc
|
|||
|
||||
return localEntRate;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,57 +19,89 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
/**
|
||||
* <p>Info theoretic measure calculator base class, providing common functionality
|
||||
* <p>Base class for our information-theoretic calculators
|
||||
* on discrete (int[]) data,
|
||||
* providing common functionality
|
||||
* for user-level measure classes.</p>
|
||||
*
|
||||
* <p>Usage of child classes is intended to follow this general pattern:
|
||||
* <p>
|
||||
* Usage of the child classes extending this class is intended to follow this paradigm:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>Construct;</li>
|
||||
* <li>{@link #initialise()};</li>
|
||||
* <li>Then, either of the following:
|
||||
* <ol>
|
||||
* <li>Continuous accumulation of observations before computing, via:
|
||||
* <ol>
|
||||
* <li>calling "addObservations()" methods of children
|
||||
* several times over;</li>
|
||||
* <li>Compute required quantities, using
|
||||
* {@link #computeAverageLocalOfObservations()} or
|
||||
* "computeLocalUsinPreviousObservations()".</li>
|
||||
* </ol></li>
|
||||
* <li>Standalone computation from a single set of observations; call:
|
||||
* "computeLocal()" or "computeAverageLocal()".</li>
|
||||
* </ol>
|
||||
* </ol></p>
|
||||
* <li>Construct the calculator;</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 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>Note: various functions referred to above (e.g. "addObservations()")
|
||||
* are not specified here, so that this class can be a superclass
|
||||
* for both univariate, pairwise and multivariate methods.</p>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
* joseph.lizier at gmail.com
|
||||
* http://lizier.me/joseph/
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public abstract class InfoMeasureCalculator {
|
||||
|
||||
/**
|
||||
* Last computed average of the measure
|
||||
*/
|
||||
protected double average = 0.0;
|
||||
/**
|
||||
* Last computed max local value of the measure
|
||||
*/
|
||||
protected double max = 0.0;
|
||||
/**
|
||||
* Last computed min local value of the measure
|
||||
*/
|
||||
protected double min = 0.0;
|
||||
/**
|
||||
* Last computed standard deviation of local values of the measure
|
||||
*/
|
||||
protected double std = 0.0;
|
||||
/**
|
||||
* Number of observations supplied for the PDFs
|
||||
*/
|
||||
protected int observations = 0;
|
||||
/**
|
||||
* Number of available quantised states for each variable
|
||||
* (ie binary is base-2).
|
||||
*/
|
||||
protected int base = 0; // number of individual states. Need initialised to 0 for changedSizes
|
||||
|
||||
/**
|
||||
* Cached value of ln(base)
|
||||
*/
|
||||
protected double log_base = 0;
|
||||
/**
|
||||
* Cached value of ln(2)
|
||||
*/
|
||||
protected double log_2 = Math.log(2.0);
|
||||
/**
|
||||
* Cache of whether the base is a power of 2
|
||||
*/
|
||||
protected boolean power_of_2_base = false;
|
||||
/**
|
||||
* Cached value of log_2(base)
|
||||
*/
|
||||
protected int log_2_base = 0;
|
||||
|
||||
/**
|
||||
* Whether we're in debug mode
|
||||
*/
|
||||
protected boolean debug = false;
|
||||
|
||||
/**
|
||||
* Construct an instance
|
||||
*
|
||||
* @param blocksize
|
||||
* @param base
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
*/
|
||||
protected InfoMeasureCalculator(int base) {
|
||||
|
||||
|
|
@ -88,9 +120,8 @@ public abstract class InfoMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
* Initialise the calculator for re-use with new observations.
|
||||
* (Child classes should clear the existing PDFs)
|
||||
*/
|
||||
public void initialise(){
|
||||
average = 0.0;
|
||||
|
|
@ -100,38 +131,66 @@ public abstract class InfoMeasureCalculator {
|
|||
observations = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 final double getLastAverage() {
|
||||
return average;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last computed max local value of the measure.
|
||||
* Not declaring this final so that separable calculator
|
||||
* can throw an exception on it since it does not support it
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getLastMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last computed min local value of the measure.
|
||||
* Not declaring this final so that separable calculator
|
||||
* can throw an exception on it since it does not support it
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getLastMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last computed standard deviation of
|
||||
* local values of the measure.
|
||||
*/
|
||||
public final double getLastStd() {
|
||||
return std;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 final int getNumObservations() {
|
||||
return observations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a given integer is a power of 2
|
||||
*
|
||||
* @param num an integer
|
||||
* @return whether the integer is a power of 2
|
||||
*/
|
||||
public final static boolean isPowerOf2(int num) {
|
||||
int bits = 0;
|
||||
int shiftedValue = num;
|
||||
|
|
@ -156,15 +215,17 @@ public abstract class InfoMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the average value of the measure from the previously supplied
|
||||
* observations
|
||||
* Compute the average value of the measure
|
||||
* from the previously-supplied samples.
|
||||
*
|
||||
* @return average value
|
||||
* @return the estimate of the measure
|
||||
*/
|
||||
public abstract double computeAverageLocalOfObservations();
|
||||
|
||||
/**
|
||||
* @param debug the debug status to set
|
||||
* 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) {
|
||||
this.debug = debug;
|
||||
|
|
|
|||
|
|
@ -22,16 +22,42 @@ import infodynamics.utils.MathsUtils;
|
|||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localMultiInformation()
|
||||
* <p>Multi-information or integration calculator for multivariate discrete data.
|
||||
* That is, it is applied to <code>double[][]</code> data, where the first index
|
||||
* is observation number or time, and the second is variable number.
|
||||
* See Tononi et al. below for the definition of multi-information/integration.</p>
|
||||
* </p>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator:
|
||||
* {@link #MultiInformationCalculator(int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[][], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being (at this stage):
|
||||
* <ul>
|
||||
* <li>the average MI: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>"G. Tononi, O. Sporns, G. M. Edelman,
|
||||
* <a href="http://dx.doi.org/10.1073/pnas.91.11.5033">"A measure for
|
||||
* brain complexity:
|
||||
* relating functional segregation and integration in the nervous system"</a>
|
||||
* Proceedings of the National Academy of Sciences, Vol. 91, No. 11.
|
||||
* (1994), pp. 5033-5037.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class MultiInformationCalculator extends InfoMeasureCalculator {
|
||||
|
||||
|
|
@ -43,8 +69,12 @@ public class MultiInformationCalculator extends InfoMeasureCalculator {
|
|||
private boolean checkedFirst = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Construct an instance
|
||||
*
|
||||
* @base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @numVars numbers of joint variables that multi-info
|
||||
* will be computed over.
|
||||
*/
|
||||
public MultiInformationCalculator(int base, int numVars) {
|
||||
super(base);
|
||||
|
|
@ -54,22 +84,24 @@ public class MultiInformationCalculator extends InfoMeasureCalculator {
|
|||
marginalCounts = new int[numVars][base];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
MatrixUtils.fill(jointCount, 0);
|
||||
MatrixUtils.fill(marginalCounts, 0);
|
||||
}
|
||||
|
||||
// TODO Define just a simple addObservations for
|
||||
// int[][] states where there are just numVars variables
|
||||
|
||||
/**
|
||||
* Add observations of the variables based at every point, with the set defined by
|
||||
* the group offsets array
|
||||
* Given one time sample of a homogeneous array of variables (states),
|
||||
* add the observations of all sets of numVars of these, defined
|
||||
* by the offsets in groupOffsets from every point in the array.
|
||||
*
|
||||
* @param states
|
||||
* @param groupOffsets
|
||||
* @param states current values of an array of variables
|
||||
* @param groupOffsets offsets for the numVars set from a given
|
||||
* data point
|
||||
*/
|
||||
public void addObservations(int[] states, int[] groupOffsets) {
|
||||
for (int c = 0; c < states.length; c++) {
|
||||
|
|
@ -87,11 +119,15 @@ public class MultiInformationCalculator extends InfoMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations of the variables based at every point, with the set defined by
|
||||
* the group offsets array
|
||||
* Given one time sample of a homogeneous array of variables (states),
|
||||
* add the observations of one set of numVars of these, defined
|
||||
* by the offsets in groupOffsets from destinationIndex.
|
||||
*
|
||||
* @param states
|
||||
* @param groupOffsets
|
||||
* @param states current values of an array of variables
|
||||
* @param destinationIndex which variable to center
|
||||
* our offsets from and take the sample,
|
||||
* @param groupOffsets offsets for the numVars set from a given
|
||||
* data point
|
||||
*/
|
||||
public void addObservations(int[] states, int destinationIndex, int[] groupOffsets) {
|
||||
// Add the marginal observations in, and compute the joint state value
|
||||
|
|
@ -107,11 +143,15 @@ public class MultiInformationCalculator extends InfoMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations of the variables based at every point, with the set defined by
|
||||
* the group offsets array
|
||||
* Given multiple time samples of a homogeneous array of variables (states),
|
||||
* add the observations of all sets of numVars of these, defined
|
||||
* by the offsets in groupOffsets from every point in the array.
|
||||
* Do this for every time point
|
||||
*
|
||||
* @param states
|
||||
* @param groupOffsets
|
||||
* @param states 2D array of values of an array of variables
|
||||
* at many observations (first index is time, second is variable index)
|
||||
* @param groupOffsets offsets for the numVars set from a given
|
||||
* data point
|
||||
*/
|
||||
public void addObservations(int[][] states, int[] groupOffsets) {
|
||||
for (int t = 0; t < states.length; t++) {
|
||||
|
|
@ -130,12 +170,7 @@ public class MultiInformationCalculator extends InfoMeasureCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local multi information storage from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
|
||||
int[] jointTuple = new int[numVars];
|
||||
|
|
@ -146,7 +181,7 @@ public class MultiInformationCalculator extends InfoMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the contribution to the MI for all tuples starting with tuple[0..(fromIndex-1)].
|
||||
* Private utility to compute the contribution to the MI for all tuples starting with tuple[0..(fromIndex-1)].
|
||||
*
|
||||
* @param tuple
|
||||
* @param fromIndex
|
||||
|
|
|
|||
|
|
@ -25,18 +25,43 @@ import infodynamics.utils.MatrixUtils;
|
|||
import infodynamics.utils.EmpiricalMeasurementDistribution;
|
||||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localMutualInformation()
|
||||
* <p>Mutual information (MI) calculator for univariate discrete (int[]) data.</p>
|
||||
*
|
||||
* @author Joseph Lizier, joseph.lizier at gmail.com
|
||||
*
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator: {@link #MutualInformationCalculator(int)}
|
||||
* or {@link #MutualInformationCalculator(int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average MI: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local MI values, such as
|
||||
* {@link #computeLocalFromPreviousObservations(int[], int[])};</li>
|
||||
* <li>comparison to null distribution, such as
|
||||
* {@link #computeSignificance()};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[][], int, int)}.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. M. Cover and J. A. Thomas, 'Elements of Information
|
||||
Theory' (John Wiley & Sons, New York, 1991).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class MutualInformationCalculator extends InfoMeasureCalculator
|
||||
implements ChannelCalculator, AnalyticNullDistributionComputer {
|
||||
|
|
@ -50,8 +75,10 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
|
||||
/**
|
||||
* Construct a new MI calculator with default time difference of 0
|
||||
* between the variables
|
||||
*
|
||||
* @param base number of symbols for each variable
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @throws Exception
|
||||
*/
|
||||
public MutualInformationCalculator(int base) throws Exception {
|
||||
|
|
@ -61,7 +88,8 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
/**
|
||||
* Create a new mutual information calculator
|
||||
*
|
||||
* @param base number of symbols for each variable
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param timeDiff number of time steps across which to compute
|
||||
* MI for given time series
|
||||
* @throws Exception when timeDiff < 0
|
||||
|
|
@ -77,10 +105,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
jCount = new int[base];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
miComputed = false;
|
||||
|
|
@ -90,10 +115,13 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add more observations in to our estimates of the pdfs
|
||||
* Pairs are between the arrays var1 and var2, separated in time by timeDiff (i is first)
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Pairs for MI are between the arrays var1 and var2, separated in time by timeDiff
|
||||
* (var1 is first).
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int[] var1, int[] var2) {
|
||||
int timeSteps = var1.length;
|
||||
// int columns = states[0].length;
|
||||
|
|
@ -113,10 +141,12 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add more observations in to our estimates of the pdfs
|
||||
* Pairs are between columns iCol and jCol, separated in time by timeDiff (i is first)
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Pairs for MI are between columns iCol and jCol, separated in time by timeDiff (i is first).
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int states[][], int iCol, int jCol) {
|
||||
int rows = states.length;
|
||||
// int columns = states[0].length;
|
||||
|
|
@ -135,12 +165,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local mutual information storage from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double mi = 0.0;
|
||||
double miCont = 0.0;
|
||||
|
|
@ -189,12 +214,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
return mi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average from the given observations
|
||||
*
|
||||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
RandomGenerator rg = new RandomGenerator();
|
||||
// (Not necessary to check for distinct random perturbations)
|
||||
|
|
@ -203,10 +223,38 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average from the given observations
|
||||
* Generate a bootstrapped distribution of what the MI would look like,
|
||||
* under a null hypothesis that the source values of our
|
||||
* samples had no relation to the destination values.
|
||||
*
|
||||
* @param newOrderings the reorderings to use
|
||||
* @return
|
||||
* <p>See Section II.E "Statistical significance testing" of
|
||||
* the JIDT paper below for a description of how this is done for
|
||||
* a mutual information. Basically, the marginal PDFs
|
||||
* of each marginal
|
||||
* are preserved, while their joint PDF is destroyed, and the
|
||||
* distribution of MI under these conditions is generated.</p>
|
||||
*
|
||||
* <p>Note that if several disjoint time-series have been added
|
||||
* as observations using {@link #addObservations(double[])} etc.,
|
||||
* then these separate "trials" will be mixed up in the generation
|
||||
* of surrogates here.</p>
|
||||
*
|
||||
* <p>This method (in contrast to {@link #computeSignificance(int)})
|
||||
* allows the user to specify how to construct the surrogates,
|
||||
* such that repeatable results may be obtained.</p>
|
||||
*
|
||||
* @param newOrderings a specification of how to shuffle the next values
|
||||
* to create the surrogates to generate the distribution with. The first
|
||||
* index is the permutation number (i.e. newOrderings.length is the number
|
||||
* of surrogate samples we use to bootstrap to generate the distribution here.)
|
||||
* Each array newOrderings[i] should be an array of length N (where
|
||||
* would be the value returned by {@link #getNumObservations()}),
|
||||
* containing a permutation of the values in 0..(N-1).
|
||||
* @return the distribution of MI scores under this null hypothesis.
|
||||
* @see "J.T. Lizier, 'JIDT: An information-theoretic
|
||||
* toolkit for studying the dynamics of complex systems', 2014."
|
||||
* @throws Exception where the length of each permutation in newOrderings
|
||||
* is not equal to the number N samples that were previously supplied.
|
||||
*/
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings) {
|
||||
double actualMI = computeAverageLocalOfObservations();
|
||||
|
|
@ -264,29 +312,7 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
return measDistribution;
|
||||
}
|
||||
|
||||
/**
|
||||
* <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
|
||||
* discrete distributions follows a chi-square distribution with
|
||||
* degrees of freedom equal to the product of the number of discrete values
|
||||
* minus one, for each variable.</p>
|
||||
*
|
||||
* @return ChiSquareMeasurementDistribution object
|
||||
* 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}
|
||||
*/
|
||||
@Override
|
||||
public AnalyticMeasurementDistribution computeSignificance() {
|
||||
if (!miComputed) {
|
||||
computeAverageLocalOfObservations();
|
||||
|
|
@ -331,7 +357,6 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
* @return array of local mutual information values for each
|
||||
* observation of (var1, var2). Note - if timeDiff > 0, then the
|
||||
* return length will be var1.length - timeDiff.
|
||||
* @throws Exception
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int[] var1, int[] var2) throws Exception{
|
||||
|
||||
|
|
@ -371,8 +396,13 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
* for the given states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
*
|
||||
* @param states
|
||||
* @return
|
||||
* @param states 2D time series of observations (first index time,
|
||||
* second is variable index)
|
||||
* @param iCol column number for first variable
|
||||
* @param jCol column number for second variable
|
||||
* @return array of local mutual information values for each
|
||||
* observation of (var1, var2). Note - if timeDiff > 0, then the
|
||||
* return length will be var1.length - timeDiff.
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int iCol, int jCol){
|
||||
int rows = states.length;
|
||||
|
|
@ -415,10 +445,15 @@ public class MutualInformationCalculator extends InfoMeasureCalculator
|
|||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @return
|
||||
* @param states 2D time series of observations (first index time,
|
||||
* second is variable index)
|
||||
* @param iCol column number for first variable
|
||||
* @param jCol column number for second variable
|
||||
* @return array of local mutual information values for each
|
||||
* observation of (var1, var2). Note - if timeDiff > 0, then the
|
||||
* return length will be var1.length - timeDiff.
|
||||
*/
|
||||
public double[] localMutualInformation(int states[][], int iCol, int jCol) {
|
||||
public double[] computeLocal(int states[][], int iCol, int jCol) {
|
||||
initialise();
|
||||
addObservations(states, iCol, jCol);
|
||||
return computeLocalFromPreviousObservations(states, iCol, jCol);
|
||||
|
|
|
|||
|
|
@ -22,37 +22,64 @@ import infodynamics.utils.MathsUtils;
|
|||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* <p>Implements the Predictive information (see Bialek et al. below)
|
||||
* form of the Excess Entropy (see Crutchfield et al. below),
|
||||
* i.e. the mutual information I(x_{n+1}^{(k+)};x_{n}^{(k)}) between
|
||||
* k-length blocks in the past up to time n, (x_{n}^{(k)}), and in the future
|
||||
* from time n+1, x_{n+1}^{(k+)}</p>
|
||||
* <p> Predictive information calculator for univariate discrete (int[]) data.
|
||||
* See definition of Predictive information (PI) by Bialek et al. below,
|
||||
* also is a form of the Excess Entropy (see Crutchfield and Feldman below),
|
||||
* Basically, PI is the mutual information between the past <i>state</i>
|
||||
* of a time-series process <i>X</i> and its future <i>state</i>.
|
||||
* The past <i>state</i> at time <code>n</code>
|
||||
* is represented by an embedding vector of <code>k</code> values from <code>X_n</code> backwards,
|
||||
* each separated by <code>\tau</code> steps, giving
|
||||
* <code><b>X^k_n</b> = [ X_{n-(k-1)\tau}, ... , X_{n-\tau}, X_n]</code>.
|
||||
* We call <code>k</code> the embedding dimension, and <code>\tau</code>
|
||||
* the embedding delay (only delay = 1 is implemented at the moment).
|
||||
* The future <i>state</i> at time <code>n</code>
|
||||
* is defined similarly into the future:
|
||||
* each separated by <code>\tau</code> steps, giving
|
||||
* <code><b>X^k+_n</b> = [ X_{n+1}, X_{n+\tau}, X_{n+(k-1)\tau}]</code>.
|
||||
* PI is then the mutual information between <b>X^k_n</b> and <b>X^k+_n</b>.</p>
|
||||
*
|
||||
* <p>Usage:
|
||||
* <p>Usage of the class is intended to follow this paradigm:</p>
|
||||
* <ol>
|
||||
* <li>Continuous accumulation of observations - call:
|
||||
* <ol>
|
||||
* <li>initialise()</li>
|
||||
* <li>addObservations() several times over</li>
|
||||
* <li>computeLocalFromPreviousObservations()</li>
|
||||
* </ol></li>
|
||||
* <li>Standalone - call:
|
||||
* <ol>
|
||||
* <li>localActiveInformation()</li>
|
||||
* </ol></li>
|
||||
* </ol>
|
||||
* <li>Construct the calculator: {@link #PredictiveInformationCalculator(int, int)};</li>
|
||||
* <li>Initialise the calculator using {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* sets of {@link #addObservations(int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average entropy: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>local entropy values, such as {@link #computeLocal(int[])};</li>
|
||||
* <li>and variants of these.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[])},
|
||||
* {@link #computeAverageLocal(int[])} etc.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @author Joseph Lizier joseph.lizier at gmail.com
|
||||
* <p>TODO Inherit from {@link SingleAgentMeasureInContextOfPastCalculator}
|
||||
* as {@link ActiveInformationCalculator} does; Tidy up the Javadocs for
|
||||
* the methods, which are somewhat preliminary</p>
|
||||
*
|
||||
* @see <a href="http://dx.doi.org/10.1016/S0378-4371(01)00444-7">
|
||||
* Bialek, W., Nemenman, I., and Tishby, N. (2001)
|
||||
* Complexity through nonextensivity. Physica A, 302, 89-99.</a>
|
||||
* @see <a href="http://dx.doi.org/10.1063/1.1530990">
|
||||
* Crutchfield, J. P. and Feldman, D. P. (2003) Regularities
|
||||
* unseen, randomness observed: Levels of entropy convergence.
|
||||
* Chaos, 13, 25-54.</a>
|
||||
*
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>Bialek, W., Nemenman, I., and Tishby, N.,
|
||||
* <a href="http://dx.doi.org/10.1016/S0378-4371(01)00444-7">
|
||||
* "Complexity through nonextensivity"</a>,
|
||||
* Physica A, 302, 89-99. (2001).</li>
|
||||
* <li>J. P. Crutchfield, D. P. Feldman,
|
||||
* <a href="http://dx.doi.org/10.1063/1.1530990">
|
||||
* "Regularities Unseen, Randomness Observed: Levels of Entropy Convergence"</a>,
|
||||
* Chaos, Vol. 13, No. 1. (2003), pp. 25-54.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class PredictiveInformationCalculator {
|
||||
|
||||
|
|
@ -76,13 +103,21 @@ public class PredictiveInformationCalculator {
|
|||
*
|
||||
* @param numDiscreteValues Number of discrete values (e.g. 2 for binary states)
|
||||
* @param blockLength
|
||||
*
|
||||
* @deprecated
|
||||
* @return
|
||||
*/
|
||||
public static PredictiveInformationCalculator newInstance(int numDiscreteValues, int blockLength) {
|
||||
return new PredictiveInformationCalculator(numDiscreteValues, blockLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance
|
||||
*
|
||||
* @param numDiscreteValues number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param blockLength embedded history length of the past and future to use -
|
||||
* this is k in Schreiber's notation.
|
||||
*/
|
||||
public PredictiveInformationCalculator(int numDiscreteValues, int blockLength) {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -25,23 +25,53 @@ import infodynamics.utils.MatrixUtils;
|
|||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Implements separable information (see Lizier et al, Chaos 2010)
|
||||
* Separable information = sum of active information and apparent transfer entropy from every
|
||||
* Implements <b>separable information</b> (see Lizier et al, 2010, below).
|
||||
*
|
||||
* Separable information is the sum of active information and apparent transfer entropy from every
|
||||
* causal information contributor.
|
||||
* The causal information contributors (either their offsets or their absolute column numbers)
|
||||
* should be supplied in the same order in every method call, otherwise the answer supplied will
|
||||
* be incorrect.
|
||||
*
|
||||
* Usage:
|
||||
* 1. Continuous accumulation of observations:
|
||||
* Call: a. initialise()
|
||||
* b. addObservations() several times over
|
||||
* c. computeLocalFromPreviousObservations()
|
||||
* 2. Standalone:
|
||||
* Call: localActiveInformation()
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
* <p>
|
||||
* Usage of the child classes implementing this interface is intended to follow this paradigm:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator via
|
||||
* {@link #SeparableInfoCalculator(int, int, int)};</li>
|
||||
* <li>Initialise the calculator using
|
||||
* {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* the set of {@link #addObservations(int[][], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average TE: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>the local TE values for these samples: {@link #computeLocalOfPreviousObservations()}</li>
|
||||
* <li>local TE values for a specific set of samples: e.g.
|
||||
* {@link #computeLocalFromPreviousObservations(int[][], int[])} etc.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[][], int[])} or
|
||||
* {@link #computeAverageLocal(int[][], int[])}.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>The causal information contributors (either their offsets or their absolute column numbers)
|
||||
* should be supplied in the same order in every method call, otherwise the answer supplied will
|
||||
* be incorrect.</p>
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>J. T. Lizier, M. Prokopenko and A. Zomaya,
|
||||
* <a href=http://dx.doi.org/10.1063/1.3486801">
|
||||
* "Information modification and particle collisions in distributed computation"</a>
|
||||
* Chaos 20, 3, 037109 (2010).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
||||
|
||||
|
|
@ -94,7 +124,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
//TODO make this class compatible with k==0
|
||||
// (low priority, not truly necessary)
|
||||
throw new RuntimeException("This class does not currently " +
|
||||
"function with k < 1 (see CompleteTransferEntropyCalculator " +
|
||||
"function with k < 1 (see ConditionalTransferEntropyCalculator " +
|
||||
"for how to implement this)");
|
||||
}
|
||||
|
||||
|
|
@ -109,11 +139,35 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance
|
||||
*
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedded history length of the destination to condition on -
|
||||
* this is k in Schreiber's notation.
|
||||
* @param numOtherInfoContributors number of information contributors
|
||||
* (other than the past of the destination
|
||||
* or the source) to condition on.
|
||||
*/
|
||||
public SeparableInfoCalculator
|
||||
(int base, int history, int numInfoContributors) {
|
||||
this(base, history, numInfoContributors, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method to implement the public constructor
|
||||
*
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedded history length of the destination to condition on -
|
||||
* this is k in Schreiber's notation.
|
||||
* @param numOtherInfoContributors number of information contributors
|
||||
* (other than the past of the destination
|
||||
* or the source) to condition on.
|
||||
* @param dontCreateObsStorage indicates that storage for
|
||||
* observations should not be created.
|
||||
*/
|
||||
protected SeparableInfoCalculator
|
||||
(int base, int history, int numInfoContributors, boolean dontCreateObsStorage) {
|
||||
|
||||
|
|
@ -131,12 +185,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
|
||||
|
|
@ -159,7 +208,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* agents will contribute to single pdfs, and all are assumed
|
||||
* to have other info contributors at same offsets.
|
||||
*
|
||||
* @param states states 1st index is time, 2nd index is agent number
|
||||
* @param states multivariate time series, 1st index is time, 2nd index is agent number
|
||||
* @param offsetOfDestFromSources offsets of the destination *from* causal information contributors.
|
||||
* (i.e. an offset of 1 means the destination is one index larger, or one to the right,
|
||||
* than the source).
|
||||
|
|
@ -238,7 +287,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* agents will contribute to single pdfs, and all are assumed
|
||||
* to have other info contributors at same offsets.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param states multivariate time series 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param offsetOfDestFromSources 2D offsets of the destination *from* causal information contributors.
|
||||
* (i.e. an offset of 1 means the destination is one index larger, or one to the right,
|
||||
* than the source).
|
||||
|
|
@ -334,12 +383,12 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single source-destination pair of the multi-agent system
|
||||
* Add observations for a single destination of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states the space-time observations to compute over
|
||||
* @param states multivariate time series, 1st index is time, 2nd index is agent number
|
||||
* @param destCol the destination index
|
||||
* @param sourcesAbsolute array of the source indices
|
||||
*/
|
||||
|
|
@ -394,12 +443,13 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single source-destination pair of the multi-agent system
|
||||
* Add observations for a single destination pair of the
|
||||
* multivariate time series
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param states multivariate time series: 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param destAgentRow the destination index
|
||||
* @param destAgentColumn the destination index
|
||||
* @param sourcesAbsolute array of the source indices
|
||||
|
|
@ -455,12 +505,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local separable information from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public synchronized double computeAverageLocalOfObservations() {
|
||||
max = 0;
|
||||
min = 0;
|
||||
|
|
@ -469,7 +514,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
avPositiveLocal = 0.0;
|
||||
avNegativeLocal = 0.0;
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
}
|
||||
|
||||
// Create space for the joint source values to run through:
|
||||
|
|
@ -479,7 +524,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
// Close off the individual observations
|
||||
try {
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
|
|
@ -489,8 +534,11 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
std = Math.sqrt(meanSqLocals - average * average);
|
||||
return average;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the average, max, min and meanSq of locals for the separable information
|
||||
* Private utility function.
|
||||
*
|
||||
* <p>Updates the average, max, min and meanSq of locals for the separable information
|
||||
* for the given source values in sourceValues up to the index indexToModify over
|
||||
* all possible source values after the index indexToModify onwards. Uses recursion
|
||||
* on increasing indexToModify.
|
||||
|
|
@ -588,13 +636,16 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only
|
||||
* since it assumes the source offsets are the same
|
||||
* for all destinations (and all are added to the PDFs)
|
||||
*
|
||||
* @param states 1st index is time, 2nd is agent index
|
||||
* @param states multivariate time series 1st index is time, 2nd is agent index
|
||||
* @param offsetOfDestFromSources offsets of the destination *from* causal information contributors.
|
||||
* (i.e. an offset of 1 means the destination is one index larger, or one to the right,
|
||||
* than the source).
|
||||
* sourcesOffsets is permitted to include 0, it will be ignored.
|
||||
* @return
|
||||
* @return multivariate time series of local separable information,
|
||||
* indexed as per states.
|
||||
*/
|
||||
public double[][] computeLocalFromPreviousObservations
|
||||
(int states[][], int offsetOfDestFromSources[]){
|
||||
|
|
@ -640,7 +691,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
// Make a vector of the active and TE values for the coherence computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
}
|
||||
double[] localActAndTes = new double[numSources + 1];
|
||||
|
||||
|
|
@ -708,7 +759,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
// Close off the individual observations
|
||||
try {
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
|
|
@ -724,13 +775,16 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only
|
||||
* since it assumes offsets are same for all destinations
|
||||
* and includes them all in the calculation
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param states multivariate time series 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param offsetOfDestFromSources offsets of the destination *from* causal information contributors.
|
||||
* (i.e. an offset of 1 means the destination is one index larger, or one to the right,
|
||||
* than the source).
|
||||
* sourcesOffsets is permitted to include 0, it will be ignored.
|
||||
* @return
|
||||
* @return multivariate time series of local separable information
|
||||
* values, indexed as per states.
|
||||
*/
|
||||
public double[][][] computeLocalFromPreviousObservations
|
||||
(int states[][][], int offsetOfDestFromSources[][]){
|
||||
|
|
@ -784,7 +838,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
// Make a vector of the active and TE values for the coherence computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
}
|
||||
double[] localActAndTes = new double[numSources + 1];
|
||||
|
||||
|
|
@ -865,7 +919,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
// Close off the individual observations
|
||||
try {
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
|
|
@ -878,14 +932,16 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Computes local separable information for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* destination in the multivariate time series,
|
||||
* using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param states multivariate time series 1st index is time, 2nd index is agent number
|
||||
* @param destCol index for the destination agent
|
||||
* @param sourcesAbsolute indices for the source agents
|
||||
* @return
|
||||
* @return multivariate time series of local separable information
|
||||
* values for the given destination variable
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations
|
||||
(int states[][], int destCol, int[] sourcesAbsolute){
|
||||
|
|
@ -925,7 +981,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
// Make a vector of the active and TE values for the coherence computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
}
|
||||
double[] localActAndTes = new double[numSources + 1];
|
||||
|
||||
|
|
@ -985,7 +1041,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
// Close off the individual observations
|
||||
try {
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
|
|
@ -998,15 +1054,18 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Computes local separable information for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* destination variable in a multivariate time series,
|
||||
* using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param states multivariate time series: 1st index is time,
|
||||
* 2nd and 3rd index give the 2D agent number
|
||||
* @param destAgentRow the destination index
|
||||
* @param destAgentColumn the destination index
|
||||
* @param sourcesAbsolute array of the source indices
|
||||
* @return
|
||||
* @return multivariate time series of local separable information
|
||||
* values for the given destination
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations
|
||||
(int states[][][], int destAgentRow, int destAgentColumn, int[][] sourcesAbsolute){
|
||||
|
|
@ -1046,7 +1105,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
// Make a vector of the active and TE values for the coherence computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
}
|
||||
double[] localActAndTes = new double[numSources + 1];
|
||||
|
||||
|
|
@ -1107,7 +1166,7 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
// Close off the individual observations
|
||||
try {
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
|
|
@ -1120,18 +1179,22 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local separable info across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* compute local separable info across a 2D multivariate time series
|
||||
* of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal multivariate time series of local values.
|
||||
* First history rows are zeros.
|
||||
* This method to be called for homogeneous agents only
|
||||
* since it assumes all destinations have the same source offsets
|
||||
* and includes them all in the calculation.
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param states multivariate time series: first index is time,
|
||||
* second is variable index.
|
||||
* @param offsetOfDestFromSources offsets of the destination *from* causal information contributors.
|
||||
* (i.e. an offset of 1 means the destination is one index larger, or one to the right,
|
||||
* than the source).
|
||||
* sourcesOffsets is permitted to include 0, it will be ignored.
|
||||
* @return
|
||||
* @return multivariate time series of local separable information,
|
||||
* indexed as per states.
|
||||
*/
|
||||
public double[][] computeLocal(int states[][], int[] offsetOfDestFromSources) {
|
||||
|
||||
|
|
@ -1143,18 +1206,21 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local separable info across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* compute local separable info across a 3D multivariate time series
|
||||
* of the states of homogeneous agents.
|
||||
* Return a 3D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* First history rows are zeros.
|
||||
* This method to be called for homogeneous agents only
|
||||
* since it assumes all destinations have the same source offsets
|
||||
* and includes them all in the calculation.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param states multivariate time series: 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param offsetOfDestFromSources offsets of the destination *from* causal information contributors.
|
||||
* (i.e. an offset of 1 means the destination is one index larger, or one to the right,
|
||||
* than the source).
|
||||
* sourcesOffsets is permitted to include 0, it will be ignored.
|
||||
* @return
|
||||
* @return multivariate time series of local separable information,
|
||||
* indexed as per states.
|
||||
*/
|
||||
public double[][][] computeLocal(int states[][][], int[][] offsetOfDestFromSources) {
|
||||
|
||||
|
|
@ -1166,14 +1232,19 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* compute average separable information across a 2D multivariate time series
|
||||
* of the states of homogeneous agents.
|
||||
* Return the average.
|
||||
* This method to be called for homogeneous agents only
|
||||
* since it assumes all destinations have the same source offsets
|
||||
* and includes them all in the calculation.
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param sourceOffsets - column offsets for causal info contributors
|
||||
* @return
|
||||
* @param states multivariate time series: first index is time,
|
||||
* second is variable number
|
||||
* @param sourceOffsets column offsets for causal info contributors
|
||||
* from each destination
|
||||
* @return average separable information for these
|
||||
* observations.
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int[] sourceOffsets) {
|
||||
|
||||
|
|
@ -1184,16 +1255,18 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* compute average separable information across a 3D multivariate time series
|
||||
* of the states of homogeneous agents.
|
||||
* Return the average separable info.
|
||||
* This method to be called for homogeneous agents only
|
||||
* since it assumes all destinations have the same source offsets
|
||||
* and includes them all in the calculation.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param states multivariate time series: 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param sourceOffsets agent offsets for causal info contributors. 1st index points to
|
||||
* an array of two elements for the row and column offsets.
|
||||
*
|
||||
* @return
|
||||
* @return average separable information for these
|
||||
* observations.
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][], int[][] sourceOffsets) {
|
||||
|
||||
|
|
@ -1204,16 +1277,19 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* compute local separable information for a specific destination
|
||||
* in a 2D multivariate time series
|
||||
* of the states.
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* First history rows are zeros.
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param destCol - column index for the destination agent
|
||||
* @param sourcesAbsolute - column indices for causal info contributors
|
||||
* @return
|
||||
* @param states multivariate time series: first index is time,
|
||||
* second is variable number
|
||||
* @param destCol column index for the destination agent to consider
|
||||
* @param sourcesAbsolute column indices for causal info contributors
|
||||
* to this destination
|
||||
* @return time series of local separable information
|
||||
*/
|
||||
public double[] computeLocal(int states[][], int destCol, int[] sourcesAbsolute) {
|
||||
|
||||
|
|
@ -1225,17 +1301,17 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 3D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method suitable for heterogeneous agents
|
||||
* compute local separable information for a specific destination
|
||||
* in a 3D multivariate time series
|
||||
* of the states.
|
||||
* First history rows are zeros.
|
||||
* This method suitable for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param states multivariate time series: 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param destAgentRow row index for the destination agent
|
||||
* @param destAgnetColumn column index for the destination agent
|
||||
* @param sourcesAbsolute absolute indices for causal info contributors to this destination
|
||||
* @return
|
||||
* @return time series of local separable information
|
||||
*/
|
||||
public double[] computeLocal(int states[][][], int destAgentRow,
|
||||
int destAgentColumn, int[][] sourcesAbsolute) {
|
||||
|
|
@ -1248,15 +1324,17 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Returns the average
|
||||
* compute average separable information for a specific destination
|
||||
* in a 2D multivariate time series
|
||||
* of the states.
|
||||
* Returns the average.
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param destCol - column index for the destination agent
|
||||
* @param sourcesAbsolute - column indices for causal info contributors
|
||||
* @return
|
||||
* @param states multivariate time series: first index is time,
|
||||
* second is variable number
|
||||
* @param destCol column index for the destination agent
|
||||
* @param sourcesAbsolute column indices for causal info contributors
|
||||
* @return average separable information for this destination
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int destCol, int[] sourcesAbsolute) {
|
||||
|
||||
|
|
@ -1267,16 +1345,17 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Returns the average
|
||||
* compute average separable information for a specific destination
|
||||
* in a 3D multivariate time series
|
||||
* of the states.
|
||||
* Returns the average.
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd indices are agent indices
|
||||
* @param states multivariate time series: 1st index is time, 2nd and 3rd are agent indices
|
||||
* @param destAgentRow row index for the destination agent
|
||||
* @param destAgnetColumn column index for the destination agent
|
||||
* @param sourcesAbsolute absolute indices for causal info contributors to this destination
|
||||
* @return
|
||||
* @return average separable information for this destination
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][], int destAgentRow,
|
||||
int destAgentColumn, int[][] sourcesAbsolute) {
|
||||
|
|
@ -1318,8 +1397,8 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Counts the information contributors to this node which
|
||||
* are not equal to the node itself (offset 0)
|
||||
*
|
||||
* @param sourcesOffsets
|
||||
* @return
|
||||
* @param sourcesOffsets information contributors
|
||||
* @return count of sourcesOffsets with any 0 entries removed from the array
|
||||
*/
|
||||
public static int countOfOffsetSources(int[] sourcesOffsets) {
|
||||
int countOfSources = 0;
|
||||
|
|
@ -1335,8 +1414,8 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Counts the information contributors to this node which
|
||||
* are not equal to the node itself (offset (0,0))
|
||||
*
|
||||
* @param sourcesOffsets
|
||||
* @return
|
||||
* @param sourcesOffsets information contributors
|
||||
* @return count of sourcesOffsets with any (0,0) entries removed from the 2D array
|
||||
*/
|
||||
public static int countOfOffsetSources(int[][] sourcesOffsets) {
|
||||
int countOfSources = 0;
|
||||
|
|
@ -1352,9 +1431,9 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Counts the information contributors to the dest which
|
||||
* are not equal to the node itself
|
||||
*
|
||||
* @param sources
|
||||
* @param dest
|
||||
* @return
|
||||
* @param sources array of source indices
|
||||
* @param dest index of dest
|
||||
* @return count of sources with any entries equal to dest removed.
|
||||
*/
|
||||
public static int countOfAbsoluteSources(int[] sources, int dest) {
|
||||
int countOfSources = 0;
|
||||
|
|
@ -1371,8 +1450,9 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* are not equal to the node itself
|
||||
*
|
||||
* @param sources array of arrays of row and column indices
|
||||
* @param dest
|
||||
* @return
|
||||
* @param destAgentRow row of dest variable
|
||||
* @param destAgentColumn column of dest variable
|
||||
* @return count of entries in sources not equal to the dest indices
|
||||
*/
|
||||
public static int countOfAbsoluteSources(int[][] sources, int destAgentRow, int destAgentColumn) {
|
||||
int countOfSources = 0;
|
||||
|
|
@ -1389,8 +1469,9 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Check that the supplied array of offsets as sources
|
||||
* is long enough compared to our expectation
|
||||
*
|
||||
* @param sourcesOffsets
|
||||
* @return
|
||||
* @param sourcesOffsets array of source offsets
|
||||
* @return whether it is as long as expected
|
||||
* @throws RuntimeException if it is not
|
||||
*/
|
||||
public boolean confirmEnoughOffsetSources(int[] sourcesOffsets) {
|
||||
if (countOfOffsetSources(sourcesOffsets) != numSources) {
|
||||
|
|
@ -1403,8 +1484,9 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Check that the supplied array of offsets as sources
|
||||
* is long enough compared to our expectation
|
||||
*
|
||||
* @param sourcesOffsets
|
||||
* @return
|
||||
* @param sourcesOffsets array of 2D source offsets
|
||||
* @return whether it is as long as expected
|
||||
* @throws RuntimeException if it is not
|
||||
*/
|
||||
public boolean confirmEnoughOffsetSources(int[][] sourcesOffsets) {
|
||||
if (countOfOffsetSources(sourcesOffsets) != numSources) {
|
||||
|
|
@ -1417,9 +1499,10 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Check that the supplied array of absolutes as sources
|
||||
* is long enough compared to our expectation
|
||||
*
|
||||
* @param sourcesAbsolute
|
||||
* @param dest
|
||||
* @return
|
||||
* @param sourcesAbsolute array of source indices
|
||||
* @param dest dest index
|
||||
* @return whether it is as long as expected
|
||||
* @throws RuntimeException if it is not
|
||||
*/
|
||||
public boolean confirmEnoughAbsoluteSources(int[] sourcesAbsolute, int dest) {
|
||||
if (countOfAbsoluteSources(sourcesAbsolute, dest) != numSources) {
|
||||
|
|
@ -1432,10 +1515,11 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* Check that the supplied array of absolutes as sources
|
||||
* is long enough compared to our expectation
|
||||
*
|
||||
* @param sourcesAbsolute
|
||||
* @param destAgentRow
|
||||
* @param destAgentColumn
|
||||
* @return
|
||||
* @param sourcesAbsolute array of 2D source indices
|
||||
* @param destAgentRow row of dest variable
|
||||
* @param destAgentColumn column of dest variable
|
||||
* @return whether it is as long as expected
|
||||
* @throws RuntimeException if it is not
|
||||
*/
|
||||
public boolean confirmEnoughAbsoluteSources(int[][] sourcesAbsolute, int destAgentRow, int destAgentColumn) {
|
||||
if (countOfAbsoluteSources(sourcesAbsolute, destAgentRow, destAgentColumn) != numSources) {
|
||||
|
|
@ -1449,8 +1533,9 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* are not equal to the node itself (offset 0).
|
||||
* Checks that there are enough sources.
|
||||
*
|
||||
* @param sourcesOffsets
|
||||
* @return
|
||||
* @param sourcesOffsets array of source offsets
|
||||
* @return sourcesOffsets with these entries removed
|
||||
* from the array
|
||||
*/
|
||||
public int[] cleanOffsetOfDestFromSources(int[] sourcesOffsets) {
|
||||
int[] cleaned = new int[numSources];
|
||||
|
|
@ -1481,7 +1566,8 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
*
|
||||
* @param sourcesOffsets 2D source offsets. 1st dimension is source index, 2nd index is for
|
||||
* 1st or 2nd index of source indice pair
|
||||
* @return
|
||||
* @return sourcesOffsets with these entries removed
|
||||
* from the array
|
||||
*/
|
||||
public int[][] cleanOffsetOfDestFromSources(int[][] sourcesOffsets) {
|
||||
int[][] cleaned = new int[numSources][2];
|
||||
|
|
@ -1512,9 +1598,10 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* are not equal to the node itself (offset 0).
|
||||
* Checks that there are enough other information contributors.
|
||||
*
|
||||
* @param sources
|
||||
* @param dest
|
||||
* @return
|
||||
* @param sources array of source indices
|
||||
* @param dest dest index
|
||||
* @return sources with these entries removed
|
||||
* from the array
|
||||
*/
|
||||
public int[] cleanAbsoluteSources(int[] sources, int dest) {
|
||||
int[] cleaned = new int[numSources];
|
||||
|
|
@ -1544,9 +1631,10 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
* are not equal to the node itself (offset 0).
|
||||
* Checks that there are enough other information contributors.
|
||||
*
|
||||
* @param sources
|
||||
* @param dest
|
||||
* @return
|
||||
* @param sources 2D array of source indices
|
||||
* @param dest dest index
|
||||
* @return sources with these entries removed
|
||||
* from the array
|
||||
*/
|
||||
public int[][] cleanAbsoluteSources(int[][] sources, int destAgentRow, int destAgentColumn) {
|
||||
int[][] cleaned = new int[numSources][2];
|
||||
|
|
@ -1573,13 +1661,31 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
return cleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we use periodic boundary conditions when considering
|
||||
* spatiotemporal data for homogeneous variables
|
||||
*
|
||||
* @return if this is the case
|
||||
*/
|
||||
public boolean isPeriodicBoundaryConditions() {
|
||||
return periodicBoundaryConditions;
|
||||
}
|
||||
/**
|
||||
* Set whether to use periodic boundary conditions
|
||||
*
|
||||
* @param periodicBoundaryConditions as above
|
||||
*/
|
||||
public void setPeriodicBoundaryConditions(boolean periodicBoundaryConditions) {
|
||||
this.periodicBoundaryConditions = periodicBoundaryConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the calculator should gather observations to
|
||||
* compute a multi-info between the local TEs and
|
||||
* AIS values.
|
||||
* See Lizier et al, 2012 "Coherent information structure in complex computation"
|
||||
*
|
||||
*/
|
||||
public boolean isComputeMultiInfoCoherence() {
|
||||
return computeMultiInfoCoherence;
|
||||
}
|
||||
|
|
@ -1627,11 +1733,14 @@ public class SeparableInfoCalculator extends ContextOfPastMeasureCalculator {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Allows reclaiming of some vital memory
|
||||
/**
|
||||
* Allows reclaiming of some vital memory
|
||||
*/
|
||||
public void resetMultiInfoCoherenceCalculator() {
|
||||
miCalc.initialise(numSources + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebug(boolean debug) {
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.setDebug(debug);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,26 @@ package infodynamics.measures.discrete;
|
|||
|
||||
import infodynamics.utils.MatrixUtils;
|
||||
|
||||
/**
|
||||
* Implements <b>separable information</b> (see Lizier et al, 2010, below),
|
||||
* by using separate Transfer Entropy and Active information storage
|
||||
* calculators.
|
||||
*
|
||||
* Javadocs are preliminary here (TODO), please see
|
||||
* {@link SeparableInfoCalculator} for user-level documentation
|
||||
* regarding the methods.
|
||||
*
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>J. T. Lizier, M. Prokopenko and A. Zomaya,
|
||||
* <a href=http://dx.doi.org/10.1063/1.3486801">
|
||||
* "Information modification and particle collisions in distributed computation"</a>
|
||||
* Chaos 20, 3, 037109 (2010).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
||||
|
||||
ActiveInformationCalculator aiCalc;
|
||||
|
|
@ -533,7 +553,7 @@ public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
|||
|
||||
// Now compute the coherence of computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
double[] miTuple = new double[numSources + 1];
|
||||
for (int t = k; t < timeSteps; t++) {
|
||||
// Construct the multi-info tuple
|
||||
|
|
@ -544,7 +564,7 @@ public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
|||
miCalc.addObservation(miTuple);
|
||||
}
|
||||
try {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
// which simply will not happen. Just in case it does, we'll throw a runtime exception
|
||||
|
|
@ -612,7 +632,7 @@ public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
|||
|
||||
// Now compute the coherence of computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
double[] miTuple = new double[numSources + 1];
|
||||
for (int t = k; t < timeSteps; t++) {
|
||||
for (int r = periodicBoundaryConditions ? 0 : nonPeriodicStartAgent;
|
||||
|
|
@ -627,7 +647,7 @@ public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
|||
}
|
||||
}
|
||||
try {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
// which simply will not happen. Just in case it does, we'll throw a runtime exception
|
||||
|
|
@ -720,7 +740,7 @@ public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
|||
|
||||
// Now compute the coherence of computation
|
||||
if (computeMultiInfoCoherence) {
|
||||
miCalc.startIndividualObservations();
|
||||
miCalc.startAddObservations();
|
||||
double[] miTuple = new double[numSources + 1];
|
||||
for (int t = k; t < timeSteps; t++) {
|
||||
for (int r = periodicBoundaryConditions ? 0 : nonPeriodicStartRow;
|
||||
|
|
@ -739,7 +759,7 @@ public class SeparableInfoCalculatorByAddition extends SeparableInfoCalculator {
|
|||
}
|
||||
}
|
||||
try {
|
||||
miCalc.endIndividualObservations();
|
||||
miCalc.finaliseAddObservations();
|
||||
} catch (Exception e) {
|
||||
// an exception would only be thrown if we changed the number of causal contributors here
|
||||
// which simply will not happen. Just in case it does, we'll throw a runtime exception
|
||||
|
|
|
|||
|
|
@ -19,35 +19,54 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
/**
|
||||
* Interface to define adding observations and calculating
|
||||
* local and average values of info theoretic measures
|
||||
* for single agent metrics (e.g. entropy, active information).
|
||||
* Would ideally be an abstract class to be inherited from, but
|
||||
* it's more important for us to have inheritance from
|
||||
* Interface for calculators of information-theoretic measures
|
||||
* for single variables (e.g. entropy, active information storage).
|
||||
* The interface defines common operations such as
|
||||
* adding observations and calculating
|
||||
* local and average values, etc.
|
||||
*
|
||||
* <p>Usage is as per {@link InfoMeasureCalculator}, with
|
||||
* many methods for supplying observations and making
|
||||
* calculations defined here.</p>
|
||||
*
|
||||
* <p>It would ideally be an abstract class to be inherited from, but
|
||||
* it's more important for some of our calculators to have inheritance from
|
||||
* ContextOfPastCalculator, and since java doesn't allow multiple
|
||||
* inheritance, one of them has to miss out.
|
||||
* To get around this, we combine the two in
|
||||
* {@link SingleAgentMeasureInContextOfPastCalculator}.
|
||||
* </p>
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public interface SingleAgentMeasure {
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param states series of samples
|
||||
*/
|
||||
public void addObservations(int states[]);
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to the PDFs.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
*/
|
||||
public void addObservations(int states[][]);
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* Add observations for a single variable of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* This call should be made as opposed to {@link #addObservations(int[][])}
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param col index of agent
|
||||
*/
|
||||
public void addObservations(int states[][], int col);
|
||||
|
|
@ -57,55 +76,77 @@ public interface SingleAgentMeasure {
|
|||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
*/
|
||||
public void addObservations(int states[][][]);
|
||||
|
||||
/**
|
||||
* Add observations for a single agent of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* This call should be made as opposed to {@link #addObservations(int[][][])}
|
||||
* for computing active info for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @param index1 first index of agent
|
||||
* @param index2 index of agent in 2nd dimension
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param index1 row index index the variable
|
||||
* @param index2 column index of the variable
|
||||
*/
|
||||
public void addObservations(int states[][][], int index1, int index2);
|
||||
|
||||
/**
|
||||
* Returns the average information theoretic measure from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* Compute the average value of the measure
|
||||
* from the previously-supplied samples.
|
||||
*
|
||||
* Must set average, min and max
|
||||
*
|
||||
* @return
|
||||
* @return the estimate of the measure
|
||||
*/
|
||||
public double computeAverageLocalOfObservations();
|
||||
|
||||
/**
|
||||
* Computes local information theoretic measure for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
* sent in via the addObservations method.
|
||||
*
|
||||
* Must set average, min and max
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
* @param states time series of samples
|
||||
* @return time-series of local values (indexed as per states)
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[]);
|
||||
|
||||
/**
|
||||
* Computes local information theoretic measure for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only,
|
||||
* since the local values will be computed for all variables.
|
||||
*
|
||||
* Must set average, min and max
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @return 2D time-series of local values (indexed as per states)
|
||||
*/
|
||||
public double[][] computeLocalFromPreviousObservations(int states[][]);
|
||||
|
||||
/**
|
||||
* Computes local information theoretic measure for the given
|
||||
* variable in the 2D time-series
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
* sent in via the addObservations method.
|
||||
* This method is suitable for heterogeneous agents, since
|
||||
* the specific variable is identified.
|
||||
*
|
||||
* Must set average, min and max
|
||||
* Must set average, min and max.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param col index of the given variable
|
||||
* @return time-series of local values for the variable
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int col);
|
||||
|
||||
|
|
@ -113,91 +154,184 @@ public interface SingleAgentMeasure {
|
|||
* Computes local information theoretic measure for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method to be used for homogeneous agents only
|
||||
* This method to be used for homogeneous agents only,
|
||||
* since the local values will be computed for all variables.
|
||||
*
|
||||
* Must set average, min and max
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @return 3D time-series of local values (indexed as per states)
|
||||
*/
|
||||
public double[][][] computeLocalFromPreviousObservations(int states[][][]);
|
||||
|
||||
/**
|
||||
* Computes local information theoretic measure for the given
|
||||
* Computes the local information theoretic measure for the given
|
||||
* variable in the 3D time-series
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method
|
||||
* This method is suitable for heterogeneous agents
|
||||
* This method is suitable for heterogeneous agents, since
|
||||
* the specific variable is identified.
|
||||
*
|
||||
* Must set average, min and max
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param index1 row index of the given variable
|
||||
* @param index2 column index of the given variable
|
||||
* @return time-series of local values for the variable
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][], int index1, int index2);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* compute the local information-theoretic measure across a
|
||||
* time-series of states.
|
||||
* Return a time-series array of local values.
|
||||
* First history rows are zeros when the measure must build up
|
||||
* embedded history of the variable.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
* @param states time series of samples
|
||||
* @return time-series of local values (indexed as per states)
|
||||
*/
|
||||
public double[] computeLocal(int states[]);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute the local information-theoretic measure across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents,
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros when the measure must build up
|
||||
* embedded history of the variable.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @return 2D time-series of local values (indexed as per states)
|
||||
*/
|
||||
public double[][] computeLocal(int states[][]);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure across a 2D spatiotemporal
|
||||
* compute the local information theoretic measure across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* Return a 3D spatiotemporal array of local values.
|
||||
* First history rows are zeros when the measure must build up
|
||||
* embedded history of the variable.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index are agent number
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @return 3D time-series of local values (indexed as per states)
|
||||
*/
|
||||
public double[][][] computeLocal(int states[][][]);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
* compute the average information theoretic measure across a time-series
|
||||
* of states.
|
||||
* Return the average.
|
||||
*
|
||||
* @param states -1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
* @param states time series of samples
|
||||
* @return average of the information-theoretic measure.
|
||||
*/
|
||||
public double computeAverageLocal(int states[]);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute the average information theoretic measure across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents.
|
||||
* Return the average.
|
||||
* This method to be called for homogeneous agents only,
|
||||
* since all variables are used in the PDFs.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @return average of the information-theoretic measure.
|
||||
*/
|
||||
public double computeAverageLocal(int states[][]);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure for one agent in a 2D spatiotemporal
|
||||
* array of the states of agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method should be used for heterogeneous agents
|
||||
* compute the average information theoretic measure across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents.
|
||||
* Return the average.
|
||||
* This method to be called for homogeneous agents only,
|
||||
* since all variables are used in the PDFs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param col - column number of the agent in the states array
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @return average of the information-theoretic measure.
|
||||
*/
|
||||
public double[] computeLocalAtAgent(int states[][], int col);
|
||||
public double computeAverageLocal(int states[][][]);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local information theoretic measure
|
||||
* for a single agent
|
||||
* Returns the average
|
||||
* This method suitable for heterogeneous agents
|
||||
* @param blocksize - Size of blocks to compute entropy over
|
||||
* @param base - base of the states
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param col - column number of the agent in the states array
|
||||
* compute local information theoretic measure for one variable
|
||||
* in a 2D spatiotemporal
|
||||
* multivariate array.
|
||||
* Return a time-series array of local values.
|
||||
* First history rows are zeros when the measure must build up
|
||||
* embedded history of the variable.
|
||||
* This method should be used for heterogeneous agents
|
||||
*
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param col index of the given variable
|
||||
* @return time-series of local values of the measure for
|
||||
* the given variable
|
||||
*/
|
||||
public double computeAverageLocalAtAgent(int states[][], int col);
|
||||
public double[] computeLocal(int states[][], int col);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local information theoretic measure for one variable
|
||||
* in a 3D spatiotemporal
|
||||
* multivariate array.
|
||||
* Return a time-series array of local values.
|
||||
* First history rows are zeros when the measure must build up
|
||||
* embedded history of the variable.
|
||||
* This method should be used for heterogeneous agents
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param index1 row index of the given variable
|
||||
* @param index2 column index of the given variable
|
||||
* @return time-series of local values of the measure for
|
||||
* the given variable
|
||||
*/
|
||||
public double[] computeLocal(int states[][][], int index1, int index2);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute the average information theoretic measure
|
||||
* for a single agent in a multivariate time series.
|
||||
* Returns the average.
|
||||
* This method suitable for heterogeneous agents.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param col index of the given variable
|
||||
* @return average of the measure for the given variable.
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int col);
|
||||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute the average information theoretic measure
|
||||
* for a single agent in a multivariate time series.
|
||||
* Returns the average.
|
||||
* This method suitable for heterogeneous agents.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param index1 row index of the given variable
|
||||
* @param index2 column index of the given variable
|
||||
* @return average of the measure for the given variable.
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][], int index1, int index2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,59 +19,111 @@
|
|||
package infodynamics.measures.discrete;
|
||||
|
||||
/**
|
||||
* Combines functionality for single agents with functionality
|
||||
* required in the context of the past.
|
||||
* A base class for calculators computing measures for
|
||||
* a single variable which
|
||||
* require knowledge of the embedded past state of a univariate
|
||||
* discrete (ie int[]) variable.
|
||||
*
|
||||
* @author Joseph Lizier
|
||||
*
|
||||
* <p>This combines functionality for single agents from
|
||||
* {@link SingleAgentMeasure} with functionality
|
||||
* required in the context of the past provided by
|
||||
* {@link ContextOfPastMeasureCalculator}.</p>
|
||||
*
|
||||
* <p>Usage is as defined in {@link InfoMeasureCalculator}, with
|
||||
* extra methods for supplying observations and making
|
||||
* calculations defined in {@link SingleAgentMeasure}</p>.
|
||||
*
|
||||
* <p>Users should not need to deal with this class directly;
|
||||
* it is simply used to gather common functionality for several
|
||||
* child classes.
|
||||
* </p>
|
||||
*
|
||||
* TODO Make the Active info storage and entropy calculators inherit from this
|
||||
*
|
||||
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>)
|
||||
*/
|
||||
public abstract class SingleAgentMeasureInContextOfPastCalculator extends
|
||||
ContextOfPastMeasureCalculator implements SingleAgentMeasure {
|
||||
|
||||
/**
|
||||
* Construct the calculator
|
||||
*
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param history embedding length
|
||||
*/
|
||||
public SingleAgentMeasureInContextOfPastCalculator(int base, int history) {
|
||||
super(base, history);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double[] computeLocal(int[] states) {
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double[][] computeLocal(int[][] states) {
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double[][][] computeLocal(int[][][] states) {
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeLocalFromPreviousObservations(states);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double computeAverageLocal(int[] states) {
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double computeAverageLocal(int[][] states) {
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double computeAverageLocal(int[][][] states) {
|
||||
initialise();
|
||||
addObservations(states);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
public final double[] computeLocalAtAgent(int[][] states, int col) {
|
||||
@Override
|
||||
public final double[] computeLocal(int[][] states, int col) {
|
||||
initialise();
|
||||
addObservations(states, col);
|
||||
return computeLocalFromPreviousObservations(states, col);
|
||||
}
|
||||
|
||||
public final double[] computeLocalAtAgent(int[][][] states, int index1, int index2) {
|
||||
@Override
|
||||
public final double[] computeLocal(int[][][] states, int index1, int index2) {
|
||||
initialise();
|
||||
addObservations(states, index1, index2);
|
||||
return computeLocalFromPreviousObservations(states, index1, index2);
|
||||
}
|
||||
|
||||
public final double computeAverageLocalAtAgent(int[][] states, int col) {
|
||||
@Override
|
||||
public final double computeAverageLocal(int[][] states, int col) {
|
||||
initialise();
|
||||
addObservations(states, col);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final double computeAverageLocal(int[][][] states, int index1, int index2) {
|
||||
initialise();
|
||||
addObservations(states, index1, index2);
|
||||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,60 +27,76 @@ import infodynamics.utils.EmpiricalMeasurementDistribution;
|
|||
import infodynamics.utils.RandomGenerator;
|
||||
|
||||
/**
|
||||
* <p>Implements transfer entropy (see Schreiber, PRL, 2000)
|
||||
* and local transfer entropy (see Lizier et al, PRE, 2008).
|
||||
* We use the term <i>apparent</i> transfer entropy to mean that
|
||||
* we compute the transfer that appears to come from a single
|
||||
* source variable, without examining any other potential sources
|
||||
* (see Lizier et al, PRE, 2008). This is also known as <i>pairwise</i>
|
||||
* transfer entropy.</p>
|
||||
*
|
||||
* <p>Specifically, this implements the transfer entropy for
|
||||
* <i>discrete</i>-valued variables.</p>
|
||||
*
|
||||
* <p>Usage:
|
||||
* <ol>
|
||||
* <li>Construct: {@link #TransferEntropyCalculator(int, int)}</li>
|
||||
* <li>Initialise: {@link #initialise()}</li>
|
||||
* <li>Either:
|
||||
* <ol>
|
||||
* <li>Continuous accumulation of observations then measurement; call:
|
||||
* <ol>
|
||||
* <li>{@link #addObservations(int[], int[])} or related calls
|
||||
* several times over - <b>note:</b> each method call adding
|
||||
* observations can be viewed as updating the PDFs; they do not
|
||||
* append the separate time series (this would be incorrect behaviour
|
||||
* for the transfer entropy, since the start of one time series
|
||||
* is not necessarily related to the end of the other).</li>
|
||||
* <li>The compute relevant quantities, e.g.
|
||||
* {@link #computeLocalFromPreviousObservations(int[], int[])} or
|
||||
* {@link #computeAverageLocalOfObservations()}</li>
|
||||
* </ol>
|
||||
* <li>or Standalone computation from a single set of observations;
|
||||
* call e.g.: {@link #computeLocal(int[], int[])} or
|
||||
* {@link #computeAverageLocal(int[][], int)}.>/li>
|
||||
* </ol>
|
||||
* </ol>
|
||||
* <p>Implements <b>transfer entropy</b>
|
||||
* for univariate discrete time-series data.
|
||||
* That is, it is applied to <code>int[]</code> data, indexed
|
||||
* by time.
|
||||
* See Schreiber below for the definition of transfer entropy,
|
||||
* and Lizier et al. for the definition of local transfer entropy.
|
||||
* Specifically, this class implements the pairwise or <i>apparent</i>
|
||||
* transfer entropy; i.e. we compute the transfer that appears to
|
||||
* come from a single source variable, without examining any other
|
||||
* potential sources
|
||||
* (see Lizier et al, PRE, 2008).</p>
|
||||
*
|
||||
* <p>
|
||||
* Usage of the child classes implementing this interface is intended to follow this paradigm:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>Construct the calculator via {@link #TransferEntropyCalculator(int, int)}
|
||||
* or {@link #TransferEntropyCalculator(int, int, int)};</li>
|
||||
* <li>Initialise the calculator using
|
||||
* {@link #initialise()};</li>
|
||||
* <li>Provide the observations/samples for the calculator
|
||||
* to set up the PDFs, using one or more calls to
|
||||
* the set of {@link #addObservations(int[], int[])} methods, then</li>
|
||||
* <li>Compute the required quantities, being one or more of:
|
||||
* <ul>
|
||||
* <li>the average TE: {@link #computeAverageLocalOfObservations()};</li>
|
||||
* <li>the local TE values for these samples: {@link #computeLocalOfPreviousObservations()}</li>
|
||||
* <li>local TE values for a specific set of samples: e.g.
|
||||
* {@link #computeLocalFromPreviousObservations(int[], int[])} etc.</li>
|
||||
* <li>the distribution of TE values under the null hypothesis
|
||||
* of no relationship between source and
|
||||
* destination values: {@link #computeSignificance(int)} or
|
||||
* {@link #computeSignificance(int[][])}.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>As an alternative to steps 3 and 4, the user may undertake
|
||||
* standalone computation from a single set of observations, via
|
||||
* e.g.: {@link #computeLocal(int[], int[])} or
|
||||
* {@link #computeAverageLocal(int[][], int)}.</li>
|
||||
* <li>
|
||||
* Return to step 2 to re-use the calculator on a new data set.
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* TODO Add arbitrary source-dest delay
|
||||
*
|
||||
* @see "Schreiber, Physical Review Letters 85 (2) pp.461-464, 2000;
|
||||
* <a href='http://dx.doi.org/10.1103/PhysRevLett.85.461'>download</a>
|
||||
* (for definition of transfer entropy)"
|
||||
* @see "Lizier, Prokopenko and Zomaya, Physical Review E 77, 026110, 2008;
|
||||
* <a href='http://dx.doi.org/10.1103/PhysRevE.77.026110'>download</a>
|
||||
* (for definition of <i>local</i> transfer entropy and qualification
|
||||
* of naming it as <i>apparent</i> transfer entropy)"
|
||||
* <p><b>References:</b><br/>
|
||||
* <ul>
|
||||
* <li>T. Schreiber, <a href="http://dx.doi.org/10.1103/PhysRevLett.85.461">
|
||||
* "Measuring information transfer"</a>,
|
||||
* Physical Review Letters 85 (2) pp.461-464, 2000.</li>
|
||||
* <li>J. T. Lizier, M. Prokopenko and A. Zomaya,
|
||||
* <a href="http://dx.doi.org/10.1103/PhysRevE.77.026110">
|
||||
* "Local information transfer as a spatiotemporal filter for complex systems"</a>
|
||||
* Physical Review E 77, 026110, 2008.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Joseph Lizier, <a href="joseph.lizier at gmail.com">email</a>,
|
||||
* <a href="http://lizier.me/joseph/">www</a>
|
||||
*
|
||||
*/
|
||||
public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
||||
implements ChannelCalculator, AnalyticNullDistributionComputer {
|
||||
|
||||
/**
|
||||
* Counts of (source,dest_next,dest_embedded_past) tuples
|
||||
*/
|
||||
protected int[][][] sourceNextPastCount = null; // count for (source[n],dest[n+1],dest[n]^k) tuples
|
||||
/**
|
||||
* Counts of (source,dest_embedded_past) tuples
|
||||
*/
|
||||
protected int[][] sourcePastCount = null; // count for (source[n],dest[n]^k) tuples
|
||||
/**
|
||||
* Whether to assume periodic boundary conditions for channels across
|
||||
|
|
@ -124,7 +140,8 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* @param base
|
||||
* @param destHistoryEmbedLength
|
||||
*
|
||||
* @return
|
||||
* @return a new TransferEntropyCalculator object
|
||||
* @deprecated
|
||||
*/
|
||||
public static TransferEntropyCalculator newInstance(int base, int destHistoryEmbedLength) {
|
||||
|
||||
|
|
@ -143,7 +160,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
/**
|
||||
* Create a new TE calculator for the given base and destination history embedding length.
|
||||
*
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* @param base number of symbols for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
* @param destHistoryEmbedLength embedded history length of the destination to condition on -
|
||||
* this is k in Schreiber's notation.
|
||||
|
|
@ -170,7 +187,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a new TE calculator for the given base and destination history embedding length.
|
||||
* Create a new TE calculator for the given base, destination and source history embedding lengths.
|
||||
*
|
||||
* @param base number of quantisation levels for each variable.
|
||||
* E.g. binary variables are in base-2.
|
||||
|
|
@ -207,12 +224,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
startObservationTime = Math.max(Math.max(k, sourceHistoryEmbedLength), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise calculator, preparing to take observation sets in
|
||||
* Should be called prior to any of the addObservations() methods.
|
||||
* You can reinitialise without needing to create a new object.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void initialise(){
|
||||
super.initialise();
|
||||
estimateComputed = false;
|
||||
|
|
@ -221,12 +233,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
MatrixUtils.fill(sourcePastCount, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single source-destination pair
|
||||
* to our estimates of the pdfs.
|
||||
* @param source source timte series
|
||||
* @param dest destination time series
|
||||
*/
|
||||
@Override
|
||||
public void addObservations(int[] source, int[] dest) {
|
||||
int rows = dest.length;
|
||||
// increment the count of observations:
|
||||
|
|
@ -270,9 +277,11 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
/**
|
||||
* Add observations for a single source-destination pair
|
||||
* to our estimates of the pdfs.
|
||||
* @param source source timte series
|
||||
* @param dest destination time series
|
||||
* @param valid time series of whether the signals
|
||||
*
|
||||
* @param source source time-series
|
||||
* @param dest destination time-series.
|
||||
* Must be same length as source
|
||||
* @param valid time-series of whether the signals
|
||||
* at the given time should be considered valid
|
||||
* and added to our PDFs
|
||||
*/
|
||||
|
|
@ -346,16 +355,17 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations for a single source-destination pair of the multi-agent system
|
||||
* Add observations for a single source-destination pair
|
||||
* to our estimates of the pdfs.
|
||||
* This call is for time series not part of the same 2D array.
|
||||
* Start and end time are the (inclusive) indices within which to add the observations.
|
||||
* The start time is from the earliest of the k historical values of the destination (inclusive),
|
||||
* the end time is the last destination time point to add in.
|
||||
* @param source
|
||||
* @param dest
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
*
|
||||
* @param source source time-series
|
||||
* @param dest destination time-series.
|
||||
* Must be same length as source
|
||||
* @param startTime earliest time that we may extract embedded history from
|
||||
* @param endTime last destination (next) time point to add in
|
||||
*
|
||||
*/
|
||||
public void addObservations(int[] source, int[] dest, int startTime, int endTime) {
|
||||
|
|
@ -398,13 +408,17 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* Add observations in to our estimates of the PDFs,
|
||||
* from a multivariate time-series.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
* variable pairs separated by j column will contribute to the PDFs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. src is column i-j, dest is column i: transfer is j cells to the right)
|
||||
* (i.e. source is column i-j, dest is column i: we
|
||||
* compute transfer is j cells to the right, using observations
|
||||
* across all column pairs separated by j)
|
||||
*/
|
||||
public void addObservations(int states[][], int j) {
|
||||
int timeSteps = states.length;
|
||||
|
|
@ -480,14 +494,19 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Add observations in to our estimates of the pdfs.
|
||||
* Add observations in to our estimates of the PDFs,
|
||||
* from a multivariate time-series.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* agents will contribute to single pdfs.
|
||||
* variable pairs separated by h rows and j columns
|
||||
* will contribute to the PDFs.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param h - number of rows to compute transfer entropy across
|
||||
* (i.e. source is in row i-h, dest is column i)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. src (g-h,i-j), dest (g,i): transfer is h cells down, j cells to the right)
|
||||
* (i.e. source is column i-j, dest is column i)
|
||||
*/
|
||||
public void addObservations(int states[][][], int h, int j) {
|
||||
int timeSteps = states.length;
|
||||
|
|
@ -598,12 +617,13 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
/**
|
||||
* Add observations for a single source-destination pair of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
* This call should be made as opposed to {@link #addObservations(int[][], int)}
|
||||
* for computing TE for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param sourceIndex source agent index
|
||||
* @param destIndex destination agent index
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param sourceIndex source variable index in states
|
||||
* @param destIndex destination variable index in states
|
||||
*/
|
||||
public void addObservations(int states[][], int sourceIndex, int destIndex) {
|
||||
int rows = states.length;
|
||||
|
|
@ -648,14 +668,16 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
/**
|
||||
* Add observations for a single source-destination pair of the multi-agent system
|
||||
* to our estimates of the pdfs.
|
||||
* This call should be made as opposed to addObservations(int states[][])
|
||||
* for computing active info for heterogeneous agents.
|
||||
* This call should be made as opposed to {@link #addObservations(int[][][], int, int)}
|
||||
* for computing TE for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param sourceRowIndex source agent row index
|
||||
* @param sourceColumnIndex source agent column index
|
||||
* @param destRowIndex destination agent row index
|
||||
* @param destColumnIndex destination agent column index
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param sourceRowIndex source variable row index in states
|
||||
* @param sourceColumnIndex source variable column index in states
|
||||
* @param destRowIndex destination variable row index in states
|
||||
* @param destColumnIndex destination variable column index in states
|
||||
*/
|
||||
public void addObservations(int states[][][], int sourceRowIndex, int sourceColumnIndex,
|
||||
int destRowIndex, int destColumnIndex) {
|
||||
|
|
@ -700,24 +722,27 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
*
|
||||
* Returns the count of observations of the past given state dest[n]^k.
|
||||
* The past state is indicated by a discrete integer representing the joint variable
|
||||
* Returns the count of observations of the supplied past state
|
||||
* pastVal.
|
||||
* The past state is indicated by a unique discrete integer representing the joint variable
|
||||
* of the k past states: (dest[n-k+1],dest[n-k+2],...,dest[n-1],dest[n]).
|
||||
* The integer is computed as:<br/>
|
||||
* pastVal = dest[n-k+1] * base^(k-1) + dest[n-k+2] * base^(k-2) + ... + dest[n-1] * base + dest[n]
|
||||
*
|
||||
*
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* @return count of observations of the given past state
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return count of observations of this given past state
|
||||
*/
|
||||
public int getPastCount(int pastVal) {
|
||||
return pastCount[pastVal];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the probability of the supplied past state
|
||||
* pastVal.
|
||||
* See {@link #getPastCount(int)} for how the joint value representing the past is calculated.
|
||||
*
|
||||
* @see {@link #getPastCount(int)} for how the joint value representing the past is calculated.
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k.
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return probability of the given past state
|
||||
*/
|
||||
public double getPastProbability(int pastVal) {
|
||||
|
|
@ -725,13 +750,12 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the count of observations of the past given past state and next value.
|
||||
*
|
||||
* Returns the count of observations of the past given state dest[n]^k and next state dest[n+1].
|
||||
*
|
||||
* @see {@link #getPastCount(int)} for how the joint value representing the past is calculated.
|
||||
* See {@link #getPastCount(int)} for how the joint value representing the past is calculated.
|
||||
*
|
||||
* @param destVal next state of the destination dest[n+1]
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return count of observations of the given past state and next state
|
||||
*/
|
||||
public int getNextPastCount(int destVal, int pastVal) {
|
||||
|
|
@ -739,9 +763,12 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the probability of the past given past state and next value.
|
||||
*
|
||||
* See {@link #getPastCount(int)} for how the joint value representing the past is calculated.
|
||||
*
|
||||
* @param destVal next state of the destination dest[n+1]
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return probability of the given past state and next state
|
||||
*/
|
||||
public double getNextPastProbability(int destVal, int pastVal) {
|
||||
|
|
@ -749,12 +776,12 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the count of observations of the past given state dest[n]^k and the source state source[n]^l.
|
||||
* @see {@link #getPastCount(int)} for how the joint values representing the past are calculated.
|
||||
*
|
||||
* @param sourceVal joint state of the source source[n]^l
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* See {@link #getPastCount(int)} for how the joint values representing the past states are calculated.
|
||||
*
|
||||
* @param sourceVal int representing the joint state of the source source[n]^l
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return count of observations of the given past state and the source state
|
||||
*/
|
||||
public int getSourcePastCount(int sourceVal, int pastVal) {
|
||||
|
|
@ -762,10 +789,12 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the probability of the past given state dest[n]^k and the source state source[n]^l.
|
||||
*
|
||||
* @see {@link #getPastCount(int)} for how the joint values representing the past are calculated.
|
||||
* @param sourceVal joint state of the source source[n]^l
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* See {@link #getPastCount(int)} for how the joint values representing the past states are calculated.
|
||||
*
|
||||
* @param sourceVal int representing the joint state of the source source[n]^l
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return probability of the given past state and the source state
|
||||
*/
|
||||
public double getSourcePastProbability(int sourceVal, int pastVal) {
|
||||
|
|
@ -773,14 +802,14 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the count of observations of the past given state dest[n]^k,
|
||||
* the next state of the destination dest[n+1] and the source state source[n]^l.
|
||||
* @see {@link #getPastCount(int)} for how the joint values representing the past are calculated.
|
||||
*
|
||||
* See {@link #getPastCount(int)} for how the joint values representing the past states are calculated.
|
||||
*
|
||||
* @param sourceVal state of the source source[n]
|
||||
* @param sourceVal int representing the joint state of the source source[n]^l
|
||||
* @param nextVal next state of the destination dest[n+1]
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return count of observations of the given past state, next state of destination and the source state
|
||||
*/
|
||||
public int getSourceNextPastCount(int sourceVal, int destVal, int pastVal) {
|
||||
|
|
@ -788,11 +817,14 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the probability of the past given state dest[n]^k,
|
||||
* the next state of the destination dest[n+1] and the source state source[n]^l.
|
||||
*
|
||||
* See {@link #getPastCount(int)} for how the joint values representing the past states are calculated.
|
||||
*
|
||||
* @see {@link #getPastCount(int)} for how the joint values representing the past are calculated.
|
||||
* @param sourceVal state of the source source[n]^l
|
||||
* @param sourceVal int representing the joint state of the source source[n]^l
|
||||
* @param nextVal next state of the destination dest[n+1]
|
||||
* @param pastVal joint state of the past of the destination dest[n]^k
|
||||
* @param pastVal int representing the joint state of the past of the destination dest[n]^k
|
||||
* @return probability of the given past state, next state of destination and the source state
|
||||
*/
|
||||
public double getSourceNextPastProbability(int sourceVal, int destVal, int pastVal) {
|
||||
|
|
@ -800,7 +832,6 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the count of observations of the next state dest[n+1].
|
||||
*
|
||||
* @param nextVal next state of the destination dest[n+1]
|
||||
|
|
@ -811,6 +842,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the probability of the next state dest[n+1].
|
||||
*
|
||||
* @param nextVal state of the next destination dest[n+1]
|
||||
* @return probability of the given next state
|
||||
|
|
@ -819,12 +851,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
return (double) nextCount[destVal] / (double) observations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the average local transfer entropy from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double computeAverageLocalOfObservations() {
|
||||
double te = 0.0;
|
||||
double teCont = 0.0;
|
||||
|
|
@ -883,7 +910,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* Returns the average active information storage from
|
||||
* the observed values which have been passed in previously.
|
||||
*
|
||||
* @return
|
||||
* @see ActiveInformationCalculator
|
||||
*/
|
||||
public double computeAverageActiveInfoStorageOfObservations() {
|
||||
double active = 0.0;
|
||||
|
|
@ -931,15 +958,7 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the significance of obtaining the given average TE from the given observations
|
||||
*
|
||||
* This is as per Chavez et. al., "Statistical assessment of nonlinear causality:
|
||||
* application to epileptic EEG signals", Journal of Neuroscience Methods 124 (2003) 113-128.
|
||||
*
|
||||
* @param numPermutationsToCheck number of new orderings of the source values to compare against
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck) {
|
||||
double actualTE = computeAverageLocalOfObservations();
|
||||
|
||||
|
|
@ -1030,12 +1049,14 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Computes local transfer entropy for the given values
|
||||
* @param sourceCurrent
|
||||
* @param destNext
|
||||
* @param destPast
|
||||
*
|
||||
* @see {@link #getPastCount(int)} for how the joint values representing the past are calculated.
|
||||
* @return
|
||||
*
|
||||
* See {@link #getPastCount(int)} for how the joint values representing the past are calculated.
|
||||
*
|
||||
* @param sourceCurrent int representing the joint state of the source source[n]^l
|
||||
* @param destNext next state of the destination dest[n+1]
|
||||
* @param destPast int representing the joint state of the past of the destination dest[n]^k
|
||||
*
|
||||
* @return local TE for the given observation
|
||||
*/
|
||||
public double computeLocalFromPreviousObservations(int sourceCurrent, int destNext, int destPast){
|
||||
|
||||
|
|
@ -1046,12 +1067,13 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Computes local apparent transfer entropy for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* states, using PDFs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
*
|
||||
* @return
|
||||
* @param source source time-series
|
||||
* @param dest destination time-series.
|
||||
* Must be same length as source
|
||||
* @return time-series of local TE values
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int sourceStates[], int destStates[]){
|
||||
int timeSteps = destStates.length;
|
||||
|
|
@ -1105,13 +1127,20 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Computes local transfer for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* multivariate states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @param j columns across which to compute TE
|
||||
* @return
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* variable pairs separated by j column will
|
||||
* have their local TE computed.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. source is column i-j, dest is column i: we
|
||||
* compute transfer is j cells to the right, using observations
|
||||
* across all column pairs separated by j)
|
||||
* @return multivariate time series of local TE values
|
||||
* (first index is time, second index is destination variable)
|
||||
*/
|
||||
public double[][] computeLocalFromPreviousObservations(int states[][], int j){
|
||||
int timeSteps = states.length;
|
||||
|
|
@ -1200,13 +1229,20 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* Computes local transfer for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method to be used for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* variable pairs separated by h rows and j columns
|
||||
* will have their local TE computed.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param h - number of rows to compute transfer entropy across
|
||||
* (i.e. source is in row i-h, dest is column i)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. src (g-h,i-j), dest (g,i): transfer is h cells down, j cells to the right)
|
||||
* @return
|
||||
* (i.e. source is column i-j, dest is column i)
|
||||
* @return multivariate time series of local TE values
|
||||
* (first index is time, second index is destination variable
|
||||
* row number, third is destination variable column number)
|
||||
*/
|
||||
public double[][][] computeLocalFromPreviousObservations(int states[][][], int h, int j){
|
||||
int timeSteps = states.length;
|
||||
|
|
@ -1322,12 +1358,17 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Computes local transfer for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd index is agent number
|
||||
* @return
|
||||
* single source-destination pair of the multi-agent system,
|
||||
* using pdfs built up from observations previously
|
||||
* sent in via the addObservations methods.
|
||||
* This call should be made as opposed to {@link #addObservations(int[][], int)}
|
||||
* for computing local TE for heterogeneous agents.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param sourceIndex source variable index in states
|
||||
* @param destIndex destination variable index in states
|
||||
* @return time-series of local TE values between the series
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[][], int sourceCol, int destCol){
|
||||
int rows = states.length;
|
||||
|
|
@ -1383,16 +1424,20 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Computes local transfer for the given
|
||||
* states, using pdfs built up from observations previously
|
||||
* single source-destination pair of the multi-agent system,
|
||||
* using pdfs built up from observations previously
|
||||
* sent in via the addObservations method.
|
||||
* This method is suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param sourceRowIndex source agent row index
|
||||
* @param sourceColumnIndex source agent column index
|
||||
* @param destRowIndex destination agent row index
|
||||
* @param destColumnIndex destination agent column index
|
||||
* @return
|
||||
* This call should be made as opposed to {@link #addObservations(int[][][], int, int)}
|
||||
* for computing local TE for heterogeneous agents.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param sourceRowIndex source variable row index in states
|
||||
* @param sourceColumnIndex source variable column index in states
|
||||
* @param destRowIndex destination variable row index in states
|
||||
* @param destColumnIndex destination variable column index in states
|
||||
* @return time-series of local TE values between the series
|
||||
*/
|
||||
public double[] computeLocalFromPreviousObservations(int states[][][],
|
||||
int sourceRowIndex, int sourceColumnIndex, int destRowIndex, int destColumnIndex){
|
||||
|
|
@ -1451,11 +1496,12 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* Standalone routine to
|
||||
* compute local transfer entropy between two time series
|
||||
* Return a time series of local values.
|
||||
* First history rows are zeros
|
||||
* @param sourceStates time series of source states
|
||||
* @param destStates time series of destination states
|
||||
* First max(k,l) values are zeros since TE is not defined there
|
||||
*
|
||||
* @return
|
||||
* @param sourceStates source time-series
|
||||
* @param destStates destination time-series.
|
||||
* Must be same length as sourceStates
|
||||
* @return time-series of local TE values
|
||||
*/
|
||||
public double[] computeLocal(int sourceStates[], int destStates[]) {
|
||||
|
||||
|
|
@ -1467,14 +1513,21 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* array of the states of homogeneous agents.
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method to be called for homogeneous agents only
|
||||
* First max(k,l) values are zeros since TE is not defined there.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* variable pairs separated by j column will
|
||||
* have their local TE computed.
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param j number of columns across which to compute the TE
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. source is column i-j, dest is column i: we
|
||||
* compute transfer is j cells to the right, using observations
|
||||
* across all column pairs separated by j)
|
||||
* @return multivariate time series of local TE values
|
||||
* (first index is time, second index is destination variable)
|
||||
*/
|
||||
public double[][] computeLocal(int states[][], int j) {
|
||||
|
||||
|
|
@ -1488,14 +1541,21 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* compute local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents.
|
||||
* Return a 3D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method to be called for homogeneous agents only
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* First max(k,l) values are zeros since TE is not defined there.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* variable pairs separated by h rows and j columns
|
||||
* will have their local TE computed.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param h - number of rows to compute transfer entropy across
|
||||
* (i.e. source is in row i-h, dest is column i)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. src (g-h,i-j), dest (g,i): transfer is h cells down, j cells to the right)
|
||||
* @return
|
||||
* (i.e. source is column i-j, dest is column i)
|
||||
* @return multivariate time series of local TE values
|
||||
* (first index is time, second index is destination variable
|
||||
* row number, third is destination variable column number)
|
||||
*/
|
||||
public double[][][] computeLocal(int states[][][], int h, int j) {
|
||||
|
||||
|
|
@ -1508,12 +1568,18 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
* Return the average TE.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* variable pairs separated by j column will
|
||||
* have their local TE computed.
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param j - TE across j cells to the right
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. source is column i-j, dest is column i: we
|
||||
* compute transfer is j cells to the right, using observations
|
||||
* across all column pairs separated by j)
|
||||
* @return average TE across j variables to the right
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int j) {
|
||||
|
||||
|
|
@ -1526,13 +1592,18 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return the average
|
||||
* This method to be called for homogeneous agents only
|
||||
* Return the average.
|
||||
* This call suitable only for homogeneous agents, as all
|
||||
* variable pairs separated by h rows and j columns
|
||||
* will have their PDFs combined.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param h - number of rows to compute transfer entropy across
|
||||
* (i.e. source is in row i-h, dest is column i)
|
||||
* @param j - number of columns to compute transfer entropy across
|
||||
* (i.e. src (g-h,i-j), dest (g,i): transfer is h cells down, j cells to the right)
|
||||
* (i.e. source is column i-j, dest is column i)
|
||||
* @return
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][], int h, int j) {
|
||||
|
|
@ -1544,16 +1615,15 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param sourceCol - column index for the source agent
|
||||
* @param destCol - column index for the destination agent
|
||||
* @return
|
||||
* compute local transfer entropy between specific variables in
|
||||
* a 2D spatiotemporal multivariate time-series.
|
||||
* First max(k,l) values are zeros since TE is not defined there.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param sourceCol source variable index in states
|
||||
* @param destCol destination variable index in states
|
||||
* @return time-series of local TE values between the series
|
||||
*/
|
||||
public double[] computeLocal(int states[][], int sourceCol, int destCol) {
|
||||
|
||||
|
|
@ -1564,18 +1634,18 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Return a 2D spatiotemporal array of local values.
|
||||
* First history rows are zeros
|
||||
* This method suitable for heterogeneous agents
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param sourceRowIndex source agent row index
|
||||
* @param sourceColumnIndex source agent column index
|
||||
* @param destRowIndex destination agent row index
|
||||
* @param destColumnIndex destination agent column index
|
||||
* @return
|
||||
* computes local transfer for the given
|
||||
* single source-destination pair of the 3D multi-agent system.
|
||||
* This method suitable for heterogeneous variables.
|
||||
*
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param sourceRowIndex source variable row index in states
|
||||
* @param sourceColumnIndex source variable column index in states
|
||||
* @param destRowIndex destination variable row index in states
|
||||
* @param destColumnIndex destination variable column index in states
|
||||
* @return time-series of local TE values between the series
|
||||
*/
|
||||
public double[] computeLocal(int states[][][], int sourceRowIndex, int sourceColumnIndex,
|
||||
int destRowIndex, int destColumnIndex) {
|
||||
|
|
@ -1588,15 +1658,16 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 2D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Returns the average
|
||||
* compute local transfer entropy between specific variables in
|
||||
* a 2D spatiotemporal multivariate time-series.
|
||||
* Returns the average.
|
||||
* This method suitable for heterogeneous agents.
|
||||
*
|
||||
* @param states - 2D array of states
|
||||
* @param sourceCol - column index for the source agent
|
||||
* @param destCol - column index for the destination agent
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable number)
|
||||
* @param sourceCol source variable index in states
|
||||
* @param destCol destination variable index in states
|
||||
* @return average TE for the given pair
|
||||
*/
|
||||
public double computeAverageLocal(int states[][], int sourceCol, int destCol) {
|
||||
|
||||
|
|
@ -1607,17 +1678,19 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
|
||||
/**
|
||||
* Standalone routine to
|
||||
* compute average local transfer entropy across a 3D spatiotemporal
|
||||
* array of the states of homogeneous agents
|
||||
* Returns the average
|
||||
* This method suitable for heterogeneous agents
|
||||
* compute local transfer entropy between specific variables in
|
||||
* a 3D spatiotemporal multivariate time-series.
|
||||
* Returns the average.
|
||||
* This method suitable for heterogeneous agents.
|
||||
*
|
||||
* @param states 1st index is time, 2nd and 3rd index give the 2D agent number
|
||||
* @param sourceRowIndex source agent row index
|
||||
* @param sourceColumnIndex source agent column index
|
||||
* @param destRowIndex destination agent row index
|
||||
* @param destColumnIndex destination agent column index
|
||||
* @return
|
||||
* @param states multivariate time series
|
||||
* (1st index is time, 2nd index is variable row number,
|
||||
* 3rd is variable column number)
|
||||
* @param sourceRowIndex source variable row index in states
|
||||
* @param sourceColumnIndex source variable column index in states
|
||||
* @param destRowIndex destination variable row index in states
|
||||
* @param destColumnIndex destination variable column index in states
|
||||
* @return average TE for the given pair
|
||||
*/
|
||||
public double computeAverageLocal(int states[][][], int sourceRowIndex, int sourceColumnIndex,
|
||||
int destRowIndex, int destColumnIndex) {
|
||||
|
|
@ -1627,9 +1700,21 @@ public class TransferEntropyCalculator extends ContextOfPastMeasureCalculator
|
|||
return computeAverageLocalOfObservations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we assume periodic boundary conditions in the calls
|
||||
* for homogeneous variables.
|
||||
*
|
||||
* @return as above
|
||||
*/
|
||||
public boolean isPeriodicBoundaryConditions() {
|
||||
return periodicBoundaryConditions;
|
||||
}
|
||||
/**
|
||||
* set whether we assume periodic boundary conditions in the calls
|
||||
* for homogeneous variables.
|
||||
*
|
||||
* @param periodicBoundaryConditions as above
|
||||
*/
|
||||
public void setPeriodicBoundaryConditions(boolean periodicBoundaryConditions) {
|
||||
this.periodicBoundaryConditions = periodicBoundaryConditions;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue