mirror of https://github.com/jlizier/jidt
203 lines
6.4 KiB
Java
Executable File
203 lines
6.4 KiB
Java
Executable File
/*
|
|
* Java Information Dynamics Toolkit (JIDT)
|
|
* Copyright (C) 2012, Joseph T. Lizier
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package infodynamics.measures.discrete;
|
|
|
|
import infodynamics.utils.MathsUtils;
|
|
import infodynamics.utils.MatrixUtils;
|
|
|
|
/**
|
|
* A base class for calculators computing measures which
|
|
* require knowledge of the embedded past state of a univariate
|
|
* discrete (ie int[]) variable.
|
|
*
|
|
* Usage is as per {@link InfoMeasureCalculatorDiscrete}, but with some
|
|
* extra utility functions provided for computing embedding vectors.
|
|
*
|
|
* @author Joseph Lizier (<a href="joseph.lizier at gmail.com">email</a>,
|
|
* <a href="http://lizier.me/joseph/">www</a>)
|
|
*/
|
|
public abstract class ContextOfPastMeasureCalculatorDiscrete extends
|
|
InfoMeasureCalculatorDiscrete {
|
|
|
|
/**
|
|
* 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]
|
|
/**
|
|
* Cached value maxShiftedValue[i] is i * (base^(k-1))
|
|
*/
|
|
protected int[] maxShiftedValue = null; //
|
|
/**
|
|
* Cached value of base^k
|
|
*/
|
|
protected int base_power_k = 0;
|
|
|
|
/**
|
|
* 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 ContextOfPastMeasureCalculatorDiscrete(int base, int history) {
|
|
this(base, history, false);
|
|
}
|
|
|
|
/**
|
|
* Constructor to be used by child classes only.
|
|
* In general, only needs to be explicitly called if child classes
|
|
* do not wish to create the observation arrays.
|
|
*
|
|
* @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 ContextOfPastMeasureCalculatorDiscrete(int base, int history, boolean dontCreateObsStorage) {
|
|
super(base);
|
|
|
|
k = history;
|
|
base_power_k = MathsUtils.power(base, k);
|
|
|
|
// Relax the requirement that k >= 1, so that we can
|
|
// eliminate considering the history at will ...
|
|
//if (k < 1) {
|
|
// throw new RuntimeException("History k " + history + " is not >= 1 a ContextOfPastMeasureCalculator");
|
|
//}
|
|
|
|
// Check that we can convert the history value into an integer ok:
|
|
if (k > Math.log(Integer.MAX_VALUE) / log_base) {
|
|
throw new RuntimeException("Base and history combination too large");
|
|
}
|
|
|
|
// Create constants for tracking prevValues
|
|
maxShiftedValue = new int[base];
|
|
for (int v = 0; v < base; v++) {
|
|
maxShiftedValue[v] = v * MathsUtils.power(base, k-1);
|
|
}
|
|
|
|
noObservationStorage = dontCreateObsStorage;
|
|
if (!dontCreateObsStorage) {
|
|
// Create storage for counts of observations
|
|
nextPastCount = new int[base][base_power_k];
|
|
pastCount = new int[base_power_k];
|
|
nextCount = new int[base];
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void initialise() {
|
|
super.initialise();
|
|
|
|
if (!noObservationStorage) {
|
|
MatrixUtils.fill(nextPastCount, 0);
|
|
MatrixUtils.fill(pastCount, 0);
|
|
MatrixUtils.fill(nextCount, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 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;
|
|
for (int p = 0; p < k; p++) {
|
|
pastVal *= base;
|
|
pastVal += x[t - k + 1 + p];
|
|
}
|
|
return pastVal;
|
|
}
|
|
|
|
/**
|
|
* 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 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[][] data, int columnNumber, int t) {
|
|
int pastVal = 0;
|
|
for (int p = 0; p < k; p++) {
|
|
pastVal *= base;
|
|
pastVal += data[t - k + 1 + p][columnNumber];
|
|
}
|
|
return pastVal;
|
|
}
|
|
|
|
/**
|
|
* 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 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[][][] data, int rowNumber, int columnNumber, int t) {
|
|
int pastVal = 0;
|
|
for (int p = 0; p < k; p++) {
|
|
pastVal *= base;
|
|
pastVal += data[t - k + 1 + p][rowNumber][columnNumber];
|
|
}
|
|
return pastVal;
|
|
}
|
|
}
|