Concatenate subcells through one dimension of a cell array without using loops in MATLAB -



Concatenate subcells through one dimension of a cell array without using loops in MATLAB -

i have cell array. each cell contains vector of variable length. example:

example_cell_array=cellfun(@(x)x.*rand([length(x),1]),cellfun(@(x)ones(x,1), num2cell(ceil(10.*rand([7,4]))), 'uniformoutput', false), 'uniformoutput', false)

i need concatenate contents of cells downwards through 1 dimension perform operation on each concatenated vector generating scalar each column in cell array (like sum() illustration - actual operation complex, time consuming, , not naturally vectorisable - diffent length vecotrs).

i can loops (for concatenated vector sum example) follows:

[m n]=size(example_cell_array); result=zeros(1,n); cat_cell_array=cell(1,n); n=1:n cat_cell_array{n}=[]; m=1:m cat_cell_array{n}=[cat_cell_array{n};example_cell_array{m,n}]; end end result=cell2mat(cellfun(@(x)sum(x), cat_cell_array, 'uniformoutput', false))

unfortunately way slow. (my cell array 1mx5 vectors in each cell ranging in length 100-200)

is there simple way produce concatenated cell array vectors contained in cells have been concatenated downwards 1 dimension?

something like:

dim=1; cat_cell_array=(?concatcells?(dim,example_cell_array);

edit: since many people have been testing solutions: fyi, function i'm applying each concatenated vector circ_kappa(x) available circular statistics toolbox

some approaches might suggest unpack numeric info example_cell_array using {..} , after concatenation pack bigger sized cells form cat_cell_array. then, 1 time again need unpack numeric info concatenated cell array perform operation on each cell.

now, in view, multiple unpacking , packing approaches won't efficient ones if example_cell_array isn't 1 of intended outputs. so, considering these, allow me suggest 2 approaches here.

loopy approach

the first 1 for-loop code -

data1 = vertcat(example_cell_array{:}); %// extract numeric info 1 time starts = [1 sum(cellfun('length',example_cell_array),1)]; %// intervals lengths idx = cumsum(starts); %// indices work on intervals basis result = zeros(1,size(example_cell_array,2)); %// replace "result(size(example_cell_array,2))=0;" performance k1 = 1:numel(idx)-1 result(k1) = sum(data1(idx(k1):idx(k1+1)-1)); end

so, need edit sum actual operation.

almost-vectorized approach

if example_cell_array has lot of columns, sec suggestion almost vectorized approach, though doesn't perform badly either little number of columns. code uses cellfun @ first line lengths each cell in concatenated version. cellfun wrapper loop code, not expensive in terms of runtime , that's why categorized approach almost vectorized one.

the code -

lens = sum(cellfun('length',example_cell_array),1); %// intervals lengths maxlens = max(lens); numlens = numel(lens); array1(maxlens,numlens)=0; array1(bsxfun(@ge,lens,[1:maxlens]')) = vertcat(example_cell_array{:}); %//' result = sum(array1,1);

the thing need now, create operation run on column basis array1 using mask created bsxfun implementation. thus, if array1 m x 5 sized array, need select valid elements each column using mask , operation on elements. allow me know if need more info on masking issue.

hope 1 of these approaches work you!

quick tests: using 250000x5 sized example_cell_array, quick tests show both these approaches sum operation perform , give 400x speedup on code in question @ end.

arrays matlab vectorization cells cell-array

Comments

Popular posts from this blog

xslt - DocBook 5 to PDF transform failing with error: "fo:flow" is missing child elements. Required content model: marker* -

mediawiki - How do I insert tables inside infoboxes on Wikia pages? -

SQL Server : need assitance parsing delimted data and returning a long concatenated string -