%% CAindex mimics a cell array
% Written by Will Jackson
% Copyright 2010 The MathWorks, Inc.
classdef CAindex
properties
CA
end
methods
function obj = CAindex(cellarray)
if nargin > 0
obj.CA = cellarray;
end
end
function obj = set.CA(obj, value)
if iscell(value) || isempty(value)
obj.CA = value;
else
error('Unable to assign value to cell array');
end
end
function varargout = subsref(obj,s)
switch s(1).type
% Use the built-in subsref for dot notation on a cell
% array, except when setting or getting the CA property
case '.'
nargout
%varargout = cell(1,nargout(@()builtin('subsref',obj,s)));
varargout{:} = builtin('subsref',obj,s);
%Use built-in subsref unless a string is given. Then,
%search for that string in the first row and return the
%data beneath it as a cell array
case '()'
if ischar(s.subs{1})
i = strmatch(s.subs, obj.CA(1,:));
if ~isempty(i)
varargout = cell(numel(obj.CA(2:end,i)),1);
varargout(:) = {obj.CA(2:end,i)};
return
end
end
varargout{:} = subsref(obj.CA,s);
varargout{:} = subsref(obj.CA,s);
%Use built-in subsref unless a string is given. Then,
%search for that string in the first row and return the
%data beneath it as a comma separated list
case '{}'
if ischar(s.subs{1})
i = strmatch(s.subs{1}, obj.CA(1,:));
if ~isempty(i)
varargout = cell(numel(obj.CA(2:end,i)),1);
[varargout{:}] = obj.CA{2:end,i};
return
end
end
varargout = cell(numel(obj,s.subs{:}),1);
[varargout{:}] = subsref(obj.CA,s);
end
end
function obj = subsasgn(obj,s,val)
if isempty(s) && iscell(val)
obj.CA = val;
end
switch s(1).type
% Use the built-in subsref for dot notation on a cell
% array, except when setting or getting the CA property
case '.'
if strcmp(s.subs,'CA') && iscell(val);
obj.CA = val;
else
obj.CA = subsasgn(obj.CA,s,val);
end
%Use built-in subsasgn unless a string is given. Then,
%search for that string in the first row and set the
%data beneath it with val
case '()'
if isnumeric(val)
val = num2cell(val);
end
if isequal(val,[]) || isequal(val,{})
val = {[]};
end
%If given a string, look for it in first row
if ischar(s.subs{1}) && ~isequal(s.subs{1},':') && ~isequal(s.subs{1},'end')
i = [];
if ~isempty(obj.CA)
i = strmatch(s.subs{1}, obj.CA(1,:));
end
% If string not found, create new row
if isempty(i)
i = builtin('end',obj.CA,2,2) + 1;
obj.CA{1,i} = s.subs{1};
end
maxindex = length(val(:)) + 1;
obj.CA(2:maxindex,i) = val(:);
% Nullify old values in column
if(maxindex < numel(obj.CA(2:end,end)))
obj.CA(maxindex+1:numel(obj.CA(:,i)),i) = ...
cell(numel(obj.CA(:,i))- maxindex, 1);
end
obj.CA = removeemptyrows(obj.CA);
return
end
obj.CA = subsasgn(obj.CA,s,val);
obj.CA = removeemptyrows(obj.CA);
%Use built-in subsasgn unless a string is given. Then,
%search for that string in the first row and set the
%data beneath it to val
case '{}'
% Without an array or cell (array) or for NULL, simply
% use the default subasgn
if ~(isnumeric(val) || iscell(val)) || isempty(val)
obj.CA = subsasgn(obj.CA,s,val);
return
end
s(1).type = '()';
obj = subsasgn(obj,s,val);
end
end
function obj = vertcat(varargin)
a = CAindex(cell(size(varargin(:))));
for i = 1:length(varargin(:))
a(i) = varargin{i};
end
obj = CAindex(vertcat(a.CA));
end
function obj = horzcat(varargin)
a = CAindex(cell(size(varargin(:))));
for i = 1:length(varargin(:))
a(i) = varargin{i};
end
obj = CAindex(horzcat(a.CA));
end
function n = numel(obj, varargin)
if nargin == 1 && isa(obj, 'CAindex')
% This is so that plot and disp can work with obj.plot
% syntax (otherwise it would be called for each element)
n = 1;
return
elseif ischar(varargin{1})
i = strmatch(varargin{1}, obj.CA(1,:));
if ~isempty(i)
n = length(obj.CA(2:end,1));
return
end
end
n = builtin('numel', obj.CA, varargin{:});
end
function ind = end(obj,k,n)
ind = builtin('end',obj.CA,k,n);
end
function obj = transpose(obj)
obj.CA = (obj.CA).';
end
function obj = ctranspose(obj)
obj.CA = (obj.CA)';
end
function s = size(obj)
s = size(obj.CA);
end
function disp(varargin)
for i = 1:length(varargin)
disp([varargin{i}.CA]);
end
end
function plot(obj)
% Convert empty cells to NaN's for plotting
newcell = cellfun(@toNaN, obj.CA(2:end,:), 'UniformOutput', false);
% Convert cell array to matrix
m = cell2mat(newcell);
plot(m);
legend(obj.CA(1,:))
end
end
end
function CA = removeemptyrows(CA)
for j = size(CA,1):-1:1
if ~all(cellfun(@isempty,CA(j,:)))
CA = CA(1:j,:);
break;
end
end
end
function varargout = toNaN(varargin)
if(isempty(varargin{:}))
varargout{:} = NaN;
else
varargout = varargin;
end
end