Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Topic: Cell intersection
Replies: 0

 John Posts: 6 Registered: 5/10/13
Cell intersection
Posted: May 13, 2013 7:48 AM

I have a struct array allData containing various parameters for each trial,
I wrote a function (findTrialIntersections) to obtain index numbers of intersections of these parameters. These could later be used to plot them.

The result of this function is a multidimensional cell containting the index numbers.
intersections = findTrialIntersections(allData, 'participant','targetPresent','feature')
for example, wil result in al 7x2x3 cell (7 participants, target present/absent, 3 features) containing arrays of index number for those specific combination.

This function tends to be very slow when a lot of inputs are given because of the combinatorinal explosion.

The solution I came up with was to find the index numbers per conditions/dimension first, and then intersect them somehow.

In the example above this would be
7 matrices for the first dimension containing corresponding index numbers
2 matrices for the 2nd dimension containing corresponding index numbers
3 matrices for the 3rd dimension containing corresponding index numbers

Right now I am storing these matrices in a dimension x values cell with empty values to deal with the difference in values.

So this will be a ('participant','targetPresent','feature') x 7 (7 partcipants) cell, of which the last columns will not be entirely filled for the 2nd and 3 row. In each cell, the index numbers are stored.

This is how far I have come. Does anybody now how I could intersect these index numbers with these high dimensions?

I was thinking of repeating each row of the cell (singleCondCell) in all irrelevant conditions
and then intersect the new cells somehow using a cellfun.

However, I do not now wheter/how this is possible, and if it will buy me much time.

I hope you'll be able to help me, if anything is unclear, just ask!

Old slow function:
function intersections = findTrialIntersections(allData, varargin)
% looks all the unique values of given trial fields up and calucates
% mean, median, std and n for all combinations.
% Each dimension of the matrix represents a given variabele and the number of
% values whitin an dimension reflect the unique values of the
% variabele.
% If en empty argument is given, a dimension with 1 value is added (not
% affecting the data)

%remove 1x1 cell layer if existent
if iscell(varargin{1})
varargin = varargin{1};
end

%convert conditions to cell and look all unique values to use up.
for v = 1:length(varargin)
condition = varargin(v);
condition = char(condition{1});
conditions{v} = condition;

if isempty(condition)
%argument is empty, create 1*1 dimension
allValues{v} = {[]};
elseif isfield(allData,condition)
%argument is not empty, has to be a field

if ischar([allData.(condition)])
allValues{v} = unique({allData.(condition)});
else
allValues{v} = unique([allData.(condition)]);
end
else
error([condition ' is not a valid field of allData.']);
end

end

%calculate the length of different the dimensions
dimensions = cellfun(@(va) length(va),allValues);

%preallocate matrices
intersections = cell(dimensions);

%create a full factorial lookup table for all possible intersections
condValuesIndex = fullfact(dimensions);

for index = 1:length(condValuesIndex);

trials = 1:length(allData);

%determine pointer
pointer = condValuesIndex(index,:);
pointer = num2cell(pointer);
pointer = sub2ind(dimensions,pointer{:});

%select relevant values for all dimensions
for c=1:length(conditions)

%select relevant condition and value
condition = conditions{c};
values = allValues{c};

if isempty(condition)
%empty dimension, do not change trials
else

if iscell(values)
value = values{condValuesIndex(index,c)};
else
value = values(condValuesIndex(index,c));
end

%updata relevant trials
trials = mintersect(trials,findTrial(allData,condition,value));

end

end

intersections{pointer} = trials;

end

%remove 1x1 cell layer if existent
if iscell(varargin{1})
varargin = varargin{1};
end

%convert conditions to cell and look all unique values to use up.
for v = 1:length(varargin)
condition = varargin(v);
condition = all2str(condition{1});
conditions{v} = condition;

if isempty(condition)
%argument is empty, create 1*1 dimension
allValues{v} = {[]};
elseif isfield(allData,condition)
%argument is not empty, has to be a field

if ischar([allData.(condition)])
allValues{v} = unique({allData.(condition)});
else
allValues{v} = unique([allData.(condition)]);
end
else
error([condition ' is not a valid field of allData.']);
end

end

%calculate the length of different the dimensions
dimensions = cellfun(@(va) length(va),allValues);

%preallocate matrices
meanMatrix = zeros(dimensions);
medianMatrix = zeros(dimensions);
stdMatrix = zeros(dimensions);
nMatrix = zeros(dimensions);
legendCell = cell(dimensions);

%create a full factorial lookup table for all possible intersections
condValuesIndex = fullfact(dimensions);

for index = 1:length(condValuesIndex);

trials = 1:length(allData);

%determine pointer
pointer = condValuesIndex(index,:);
pointer = num2cell(pointer);
pointer = sub2ind(dimensions,pointer{:});

%clear and preallocate legendstring
legendString = [];

%select relevant values for all dimensions
for c=1:length(conditions)

%select relevant condition and value
condition = conditions{c};
values = allValues{c};

if isempty(condition)
%empty dimension, do not change trials
else

if iscell(values)
value = values{condValuesIndex(index,c)};
else
value = values(condValuesIndex(index,c));
end

legendString = [legendString condition ' = ' num2str(value) ', '];

%updata relevant trials
trials = mintersect(trials,findTrial(allData,condition,value));

end

end

meanMatrix(pointer) = mean([allData(trials).(yVar)]);
medianMatrix(pointer) = median([allData(trials).(yVar)]);
stdMatrix(pointer) = std([allData(trials).(yVar)]);
nMatrix(pointer) = length([allData(trials).(yVar)]);

legendCell{pointer} = legendString;

end

Start of a new and hopefully faster function:
function intersections = findTrialFullFact(allData, varargin)
% looks all the unique values of given trial fields up and calucates
% mean, median, std and n for all combinations.
% Each dimension of the matrix represents a given variabele and the number of
% values whitin an dimension reflect the unique values of the
% variabele.
% If en empty argument is given, a dimension with 1 value is added (not
% affecting the data)

%remove 1x1 cell layer if existent
if iscell(varargin{1})
varargin = varargin{1};
end

%convert conditions to cell and look all unique values to use up.
for c = 1:length(varargin)
condition = varargin(c);
condition = all2str(condition{1});
conditions{c} = condition;

if ~isempty(condition) && isfield(allData,condition)
%argument is not empty, has to be a field

if ischar([allData.(condition)])
values = unique({allData.(condition)});
else
values = unique([allData.(condition)]);
end

% if iscell(values)
% value = values{condValuesIndex(index,c)};
% else
% value = values(condValuesIndex(index,c));
% end

for v = 1:length(values)
%updata relevant trials
singleCondTrials{c,v} = findTrial(allData,condition,values(v));

end

else
error([condition ' is not a valid field of allData.']);
end

end

%calculate the length of different the dimensions
dimensions = sum(~cellfun('isempty',singleCondTrials),2)

%preallocate matrices
intersections = cell(dimensions);