Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster concatenation of cell arrays of different sizes

I have a cell array of size m x 1 and each cell is again s x t cell array (size varies). I would like to concatenate vertically. The code is as follows:

function(cell_out) = vert_cat(cell_in)
    [row,col] = cellfun(@size,cell_in,'Uni',0);
    fcn_vert = @(x)([x,repmat({''},size(x,1),max(cell2mat(col))-size(x,2))]);
    cell_out = cellfun(fcn_vert,cell_in,'Uni',0); % Taking up lot of time
    cell_out = vertcat(cell_out{:});
end

Step 3 takes a lot of time. Is it the right way to do or is there any another faster way to achieve this?

like image 693
nik Avatar asked Jan 24 '26 11:01

nik


1 Answers

cellfun has been found to be slower than loops (kind of old, but agrees with what I have seen). In addition, repmat has also been a performance hit in the past (though that may be different now). Try this two-loop code that aims to accomplish your task:

function cellOut = vert_cat(c)

    nElem  = length(c);
    colPad = zeros(nElem,1);
    nRow   = zeros(nElem,1);
    for k = 1:nElem
        [nRow(k),colPad(k)] = size(c{k});
    end
    colMax = max(colPad);
    colPad = colMax - colPad;

    cellOut = cell(sum(nRow),colMax);
    bottom  = cumsum(nRow) - nRow + 1;
    top     = bottom + nRow - 1;
    for k = 1:nElem
        cellOut(bottom(k):top(k),:) = [c{k},cell(nRow(k),colPad(k))];
    end

end

My test for this code was

A = rand(20,20);
A = mat2cell(A,ones(20,1),ones(20,1));
C = arrayfun(@(c) A(1:c,1:c),randi([1,15],1,5),'UniformOutput',false);
ccat = vert_cat(c);
like image 129
TroyHaskin Avatar answered Jan 26 '26 02:01

TroyHaskin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!