Jasper
Jasper

Reputation: 75

Acessing multiple structure fields in matlab without looping through it

I Have a 8x18 structure with each cel containing a column vector of occurrences of a single event. I want to obtain data from some of these fields concatenated in a single array, without having to loop through it. I can't seem to find a way to vertically concatenate the fields I am interested in in a single array.

As an example I create the following structure with between 1 and 5 occurrences per cell:

s(62).vector(8,18).heading.occurrences=[1;2;3];
for i=1:62
    for j=1:8
        for k=1:18
            y=ceil(rand(1)*5);
            s(i).vector(j,k).heading.occurrences=rand(y,1);
        end
    end
end

Now if want to obtain all occurrences in several cells while keeping i constant at for instant i=1 the following works:

ss=s(1).vector([1 26 45]);                     
h=[ss.heading];            
cell2mat({h.occurrences}')

Now I would want to do the same for s, for instance s([1 2 3]).vector([1 26 45]), how would that work? I have tried xx=s([1 2 3]), yy=xx.vector([1 26 45]) but this however yields the error:

Expected one output from a curly brace or dot indexing expression, but there were 3 results.

Is this also possible with a vector operation?

Upvotes: 6

Views: 471

Answers (2)

gnovice
gnovice

Reputation: 125874

Here's a vectorized solution that accommodates using index vectors for s and the field vector:

sIndex = [1 2 3];    % Indices for s
vIndex = [1 26 45];  % Indices for 'vector' field

v = reshape(cat(3, s(sIndex).vector), 144, []);
h = [v(vIndex, :).heading];
out = vertcat(h.occurrences);

It uses cat to concatenate all the vector fields into an 8-by-18-by-numel(sIndex) matrix, reshapes that into a 144-by-numel(sIndex) matrix, then indexes the rows specified by vIndex and collects their heading and occurrences fields, using vertcat instead of cell2mat.

Upvotes: 3

kedarps
kedarps

Reputation: 861

It's difficult to vectorize the entire operation, but this should work.

% get vector field and store in cell array
s_new = { s(1:3).vector };

% now extract heading field, this is a cell-of-cells
s_new_heading = cellfun(@(x) { x.heading }', s_new, 'UniformOutput', false);

occurences = {};
for iCell = 1:length(s_new_heading)
    % use current cell
    cellHere = s_new_heading{iCell};

    % retain indices of interest, these could be different for each cell
    cellHere = cellHere([ 1 26 45 ]);

    % extract occurrences
    h = cellfun(@(x) x.occurrences, cellHere, 'UniformOutput', false);
    h_mat = cell2mat(h);

    % save them in cell array 
    occurences = cat(1, occurences, h_mat);
end

Upvotes: 1

Related Questions