mirror of https://github.com/jlizier/jidt
Patched scale for local info profiles in CA demos.
Added complete transfer entropy and separable info. Limited size of plots to 1000x1000 if they would be larger than this (would be a silly looking plot otherwise)
This commit is contained in:
parent
a75b1ebf07
commit
2b67cede61
|
|
@ -13,12 +13,19 @@
|
|||
% - cells - number of cells in the CA
|
||||
% - timeSteps - number of rows to execute the CA for (including the random initial row)
|
||||
% - measureId - which local info dynamics measure to plot - can be a string or an integer as follows:
|
||||
% - "active", 0 - active information storage (requires options.k)
|
||||
% - "active", 0 - active information storage (requires measureParams.k)
|
||||
% - "transfer", 1 - apparent transfer entropy (requires measureParams.k and j)
|
||||
% - "transfercomplete", 2 - complete transfer entropy (requires measureParams.k and j)
|
||||
% - "separable", 3 - separable information (requires measureParams.k)
|
||||
% - "all", -1 - plot all measures
|
||||
% - measureParams - a structure containing options as described for each measure above:
|
||||
% - measureParams.k - history length for information dynamics measures
|
||||
% - measureParams.j - we measure information transfer across j cells to the right per time step
|
||||
% - options - a stucture containing a range of other options, i.e.:
|
||||
% - plotOptions - structure as defined for the plotRawCa function
|
||||
% - seed - state for the random number generator used to set the initial condition of the CA (use this
|
||||
% for reproducibility of plots, or to produce profiles for several different measures of the same CA raw states).
|
||||
% We set rand("state", options.seed) if options.seed is supplied, and restore the previous seed afterwards.
|
||||
% - plotRawCa - default true
|
||||
% - saveImages - whether to save the plots or not (default false)
|
||||
% - movingFrameSpeed - to investigate a moving frame of reference (default 0) (as in Lizier & Mahoney paper)
|
||||
|
|
@ -48,7 +55,13 @@ function plotLocalInfoMeasureForCA(neighbourhood, base, rule, cells, timeSteps,
|
|||
javaaddpath('../../../infodynamics.jar');
|
||||
|
||||
% Simulate and plot the CA
|
||||
caStates = runCA(neighbourhood, base, rule, cells, timeSteps, false);
|
||||
if (isfield(options, "seed"))
|
||||
previousSeed = rand("state");
|
||||
caStates = runCA(neighbourhood, base, rule, cells, timeSteps, false, options.seed);
|
||||
rand("state", previousSeed);
|
||||
else
|
||||
caStates = runCA(neighbourhood, base, rule, cells, timeSteps, false);
|
||||
end
|
||||
if (options.plotRawCa)
|
||||
plotRawCa(caStates, options.plotOptions, options.saveImages);
|
||||
end
|
||||
|
|
@ -58,9 +71,11 @@ function plotLocalInfoMeasureForCA(neighbourhood, base, rule, cells, timeSteps,
|
|||
% convert the states to a format usable by java:
|
||||
caStatesJInts = octaveToJavaIntMatrix(caStates);
|
||||
toc
|
||||
|
||||
plottedOne = false;
|
||||
|
||||
% Make the local information dynamics measurement
|
||||
if ((ischar(measureId) && (strcmp("active", measureId) || strcmp("all", measureId))) || \
|
||||
if ((ischar(measureId) && (strcmpi("active", measureId) || strcmpi("all", measureId))) || \
|
||||
((measureId == 0) || (measureId == -1)))
|
||||
% Compute active information storage
|
||||
activeCalc = javaObject('infodynamics.measures.discrete.ActiveInformationCalculator', base, measureParams.k);
|
||||
|
|
@ -76,6 +91,81 @@ function plotLocalInfoMeasureForCA(neighbourhood, base, rule, cells, timeSteps,
|
|||
if (options.saveImages)
|
||||
print("figures/active.eps", "-color", "-deps");
|
||||
end
|
||||
plottedOne = true;
|
||||
end
|
||||
if ((ischar(measureId) && (strcmpi("transfer", measureId) || strcmpi("all", measureId))) || \
|
||||
((measureId == 1) || (measureId == -1)))
|
||||
% Compute apparent transfer entropy
|
||||
if (measureParams.j == 0)
|
||||
error("Can't compute transfer entropy from a cell to itself (setting measureParams.j == 0)");
|
||||
end
|
||||
transferCalc = javaObject('infodynamics.measures.discrete.ApparentTransferEntropyCalculator', base, measureParams.k);
|
||||
transferCalc.initialise();
|
||||
transferCalc.addObservations(caStatesJInts, measureParams.j);
|
||||
avTransfer = transferCalc.computeAverageLocalOfObservations();
|
||||
printf("Average apparent transfer entropy (j=%d) = %.4f\n", measureParams.j, avTransfer);
|
||||
javaLocalValues = transferCalc.computeLocalFromPreviousObservations(caStatesJInts, measureParams.j);
|
||||
toc
|
||||
figure(figNum)
|
||||
figNum = figNum + 1;
|
||||
plotLocalInfoValues(javaLocalValues, options.plotOptions);
|
||||
if (options.saveImages)
|
||||
print(sprintf("figures/transfer-%d.eps", measureParams.j), "-color", "-deps");
|
||||
end
|
||||
plottedOne = true;
|
||||
end
|
||||
if ((ischar(measureId) && (strcmpi("transfercomplete", measureId) || strcmpi("completetransfer", measureId) || strcmpi("all", measureId))) || \
|
||||
((measureId == 2) || (measureId == -1)))
|
||||
% Compute complete transfer entropy
|
||||
if (measureParams.j == 0)
|
||||
error("Can't compute transfer entropy from a cell to itself (setting measureParams.j == 0)");
|
||||
end
|
||||
transferCalc = javaObject('infodynamics.measures.discrete.CompleteTransferEntropyCalculator', ...
|
||||
base, measureParams.k, neighbourhood - 2);
|
||||
transferCalc.initialise();
|
||||
% The offsets of the parents (see runCA for how this is computed, especially for even neighbourhood):
|
||||
fullSetOfParents = ceil(-neighbourhood / 2) : ceil(-neighbourhood / 2) + (neighbourhood-1);
|
||||
% Offsets of all parents can be included here - even 0 and j, these will be eliminated internally:
|
||||
transferCalc.addObservations(caStatesJInts, measureParams.j, octaveToJavaIntArray(fullSetOfParents));
|
||||
avTransfer = transferCalc.computeAverageLocalOfObservations();
|
||||
printf("Average complete transfer entropy (j=%d) = %.4f\n", measureParams.j, avTransfer);
|
||||
javaLocalValues = transferCalc.computeLocalFromPreviousObservations(caStatesJInts, ...
|
||||
measureParams.j, octaveToJavaIntArray(fullSetOfParents));
|
||||
toc
|
||||
figure(figNum)
|
||||
figNum = figNum + 1;
|
||||
plotLocalInfoValues(javaLocalValues, options.plotOptions);
|
||||
if (options.saveImages)
|
||||
print(sprintf("figures/transferComp-%d.eps", measureParams.j), "-color", "-deps");
|
||||
end
|
||||
plottedOne = true;
|
||||
end
|
||||
if ((ischar(measureId) && (strcmpi("separable", measureId) || strcmpi("all", measureId))) || \
|
||||
((measureId == 3) || (measureId == -1)))
|
||||
% Compute separable information
|
||||
separableCalc = javaObject('infodynamics.measures.discrete.SeparableInfoCalculator', ...
|
||||
base, measureParams.k, neighbourhood - 1);
|
||||
separableCalc.initialise();
|
||||
% The offsets of the parents (see runCA for how this is computed, especially for even neighbourhood):
|
||||
fullSetOfParents = ceil(-neighbourhood / 2) : ceil(-neighbourhood / 2) + (neighbourhood-1);
|
||||
% Offsets of all parents can be included here - even 0 and j, these will be eliminated internally:
|
||||
separableCalc.addObservations(caStatesJInts, octaveToJavaIntArray(fullSetOfParents));
|
||||
avSeparable = separableCalc.computeAverageLocalOfObservations();
|
||||
printf("Average separable information = %.4f\n", avSeparable);
|
||||
javaLocalValues = separableCalc.computeLocalFromPreviousObservations(caStatesJInts, ...
|
||||
octaveToJavaIntArray(fullSetOfParents));
|
||||
toc
|
||||
figure(figNum)
|
||||
figNum = figNum + 1;
|
||||
plotLocalInfoValues(javaLocalValues, options.plotOptions);
|
||||
if (options.saveImages)
|
||||
print(sprintf("figures/separable-k%d.eps", measureParams.k), "-color", "-deps");
|
||||
end
|
||||
plottedOne = true;
|
||||
end
|
||||
|
||||
if (not(plottedOne))
|
||||
error(sprintf("Supplied measureId %s did not match any measurement types", measureId));
|
||||
end
|
||||
|
||||
toc
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
% - plotCols - how many columns to plot (default is all)
|
||||
% - plotStartRow - which row to start plotting from (default is 1)
|
||||
% - plotStartCol - which column to start plotting from (default is 1)
|
||||
% - scaleColoursToSubsetOfPlot - whether to plot the darkest blue and red for the max and min of
|
||||
% the entire profile, or use the darkest for the extremes within the subset that we are plotting (default true)
|
||||
% - scaleColoursToExtremes - stretch the darkest red and blue to the max and min of the local values,
|
||||
% regardless of how imbalanced the max and mins are. (Default is false.)
|
||||
% - mainSignVectorLength - length of the longest component (positive or negative values) for the colourmap
|
||||
|
|
@ -34,6 +36,9 @@ function plotLocalInfoValues(localResults, plotOptions)
|
|||
if not(isfield(plotOptions, "plotStartCol"))
|
||||
plotOptions.plotStartCol = 1;
|
||||
end
|
||||
if not(isfield(plotOptions, "scaleColoursToSubsetOfPlot"))
|
||||
plotOptions.scaleColoursToSubsetOfPlot = true;
|
||||
end
|
||||
if not(isfield(plotOptions, "scaleColoursToExtremes"))
|
||||
plotOptions.scaleColoursToExtremes = false;
|
||||
end
|
||||
|
|
@ -46,6 +51,14 @@ function plotLocalInfoValues(localResults, plotOptions)
|
|||
if not(isfield(plotOptions, "scalingScdryComponent"))
|
||||
plotOptions.scalingScdryComponent = .4;
|
||||
end
|
||||
if (plotOptions.plotRows > 1000)
|
||||
printf("*** Limiting number of plotted rows to 1000\n");
|
||||
plotOptions.plotRows = 1000;
|
||||
end
|
||||
if (plotOptions.plotCols > 1000)
|
||||
printf("*** Limiting number of plotted columns to 1000\n");
|
||||
plotOptions.plotCols = 1000;
|
||||
end
|
||||
% Pull some options out for easier coding here:
|
||||
scalingMainComponent = plotOptions.scalingMainComponent;
|
||||
mainSignVectorLength = plotOptions.mainSignVectorLength;
|
||||
|
|
@ -60,16 +73,32 @@ function plotLocalInfoValues(localResults, plotOptions)
|
|||
plotOptions.plotRows, plotOptions.plotCols);
|
||||
% JIDT jar file is assumed to be on the path since we already have java objects coming in
|
||||
mUtils = javaObject('infodynamics.utils.MatrixUtils');
|
||||
minLocal = mUtils.min(localResults);
|
||||
maxLocal = mUtils.max(localResults);
|
||||
% Max and min for the entire local profile (use these for the colour box):
|
||||
minLocalEntireProfile = mUtils.min(localResults);
|
||||
maxLocalEntireProfile = mUtils.max(localResults);
|
||||
else
|
||||
% Pull out the values we'll be plotting
|
||||
localResultsToPlot = localResults(plotOptions.plotStartRow:plotOptions.plotStartRow+plotOptions.plotRows - 1, ...
|
||||
plotOptions.plotStartCol:plotOptions.plotStartCol+plotOptions.plotCols - 1);
|
||||
minLocal = min(min(localResults));
|
||||
maxLocal = max(max(localResults));
|
||||
% Max and min for the entire local profile (use these for the colour box):
|
||||
minLocalEntireProfile = min(min(localResults));
|
||||
maxLocalEntireProfile = max(max(localResults));
|
||||
end
|
||||
% Max and min for what we're plotting (use these for printing out only):
|
||||
minLocalOfPlot = min(min(localResultsToPlot));
|
||||
maxLocalOfPlot = max(max(localResultsToPlot));
|
||||
printf("[max,min] for all spacetime local info dynamics profile is [%.3f, %.3f]\n", maxLocalEntireProfile, minLocalEntireProfile);
|
||||
printf("[max,min] within this particular plot of the profile is [%.3f, %.3f]\n", maxLocalOfPlot, minLocalOfPlot);
|
||||
|
||||
if (plotOptions.scaleColoursToSubsetOfPlot)
|
||||
% Scale the colours to the max and min of the points on the plot
|
||||
minLocal = minLocalOfPlot;
|
||||
maxLocal = maxLocalOfPlot;
|
||||
else
|
||||
% Scale the colours to the max and min of the entire profile (including points not plotted)
|
||||
minLocal = minLocalEntireProfile;
|
||||
maxLocal = maxLocalEntireProfile;
|
||||
end
|
||||
printf("[max,min] for local info dynamics profile is [%.3f, %.3f]\n", maxLocal, minLocal);
|
||||
|
||||
if (minLocal < 0)
|
||||
% We need a negative component for the colorchart
|
||||
|
|
@ -113,7 +142,7 @@ function plotLocalInfoValues(localResults, plotOptions)
|
|||
% Construct the colormap with blue for positive and red for negative
|
||||
colormap([redNegmap; bluePosmap]);
|
||||
% Now, plot the local values with the pre-prepared colormap
|
||||
imagesc(localResultsToPlot);
|
||||
imagesc(localResultsToPlot, [minLocal, maxLocal]);
|
||||
else
|
||||
% We need to pin the minimum value of the blue-only plot to zero.
|
||||
bluemap = prepareColourmap(mainSignVectorLength, true, scalingMainComponent, scalingScdryComponent);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@ function plotRawCa(states, plotOptions, saveIt)
|
|||
if not(isfield(plotOptions, "plotStartCol"))
|
||||
plotOptions.plotStartCol = 1;
|
||||
end
|
||||
if (plotOptions.plotRows > 1000)
|
||||
printf("*** Limiting number of plotted rows to 1000\n");
|
||||
plotOptions.plotRows = 1000;
|
||||
end
|
||||
if (plotOptions.plotCols > 1000)
|
||||
printf("*** Limiting number of plotted columns to 1000\n");
|
||||
plotOptions.plotCols = 1000;
|
||||
end
|
||||
if (nargin < 3)
|
||||
saveIt = false;
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
% - neighbourhood - neighbourhood size for the rule (ECA has neighbourhood 3).
|
||||
% For an even size neighbourhood (meaning a different number of neighbours on each side of the cell),
|
||||
% we take an extra cell from the lower cell indices (i.e. from the left).
|
||||
% The offset of parents can be generated from: ceil(-n / 2) : 1 : ceil(-n / 2) + (n-1), where n is neighbourhood size
|
||||
% - base - number of discrete states for each cell (for binary states this is 2)
|
||||
% - rule - supplied as either:
|
||||
% a. an integer rule number if <= 2^31 - 1 (Wolfram style; e.g. 110, 54 are the complex ECA rules)
|
||||
|
|
|
|||
Loading…
Reference in New Issue