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:
joseph.lizier 2012-10-29 02:04:49 +00:00
parent a75b1ebf07
commit 2b67cede61
4 changed files with 137 additions and 9 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)