jeanjacquesvivde
jeanjacquesvivde

Reputation: 41

how to sum cells/ struct in matlab

I am trying to add vertically the lists of a database like DB (see below) contained in a cell.

DB={ {[11 12]}  {[13 14]} {[15 16]} {[17 18]} {[19 20]};

    {[21 22]} {[23 24]} {[25 26]} {[27 28]} {[29 30]};

    {[31 32]} {[33 34]} {[35 36]} {[37 38]} {[39 40]}}

I would like to get:

 [33 36]  [69 72] [75 78] [81 44] [ 87 90 ]

I tried with a 'for' loop (see below) ... but taking too much time.

How could I do this with the minimum of 'for' loops or even better, without any loop?

Thank you very much for your attention.

sum=[ ]
for j=1:5
    sumi=0
    for i=1:3
    sumi=sumi+ c2{i,j}{1}
    end
    sum=[sum sumi]
end

Upvotes: 2

Views: 65

Answers (3)

Luis Mendo
Luis Mendo

Reputation: 112749

Based on your code, you can achieve the same result with

result = sum(cell2mat(cellfun(@(x) x, DB)), 1);

or better (thanks to @Wolfie)

result = sum(cell2mat(reshape([DB{:}], size(DB, 1), [])), 1);

This converts your cell array of cell arrays into a numerical 2D array, and then sums along the vertical dimension. However, this is not likely to be much faster than your current code.

The issue with your approach is not the code, but the data type. If possible, you should define your DB variable directly as a numerical 2D array. That way the code would be simpler and faster: result = sum(DB, 1);. Normally, cell arrays in Matlab are only used if the contents are not homogenous in size or in type.

Upvotes: 5

Wolfie
Wolfie

Reputation: 30146

One slightly faster approach is to reduce to a single loop, and pre-allocate the output:

n = 2;
s = NaN( 1, n*size(DB,2) );
for ii = 1:size(DB,2)
    col = vertcat(DB{:,ii});
    s(n*(ii-1)+1:n*ii) = sum( vertcat(col{:}) );
end

Note that n here is the number of elements within each cell, which in your example was 2.

Upvotes: 3

ThomasIsCoding
ThomasIsCoding

Reputation: 102529

Maybe you can try

table2cell(varfun(@(x) sum(cell2mat(x),1),cell2table(DB)))

and you will obtain the result presented like

  1×5 cell array

    {[63 66]}    {[69 72]}    {[75 78]}    {[81 84]}    {[87 90]}

Upvotes: 2

Related Questions