A compact way to sum the elements contained in two cell arrays (considering the case of empty cells as well)

3 views (last 30 days)
Given two cell arrays a and b, as in the example here below, is there any compact way to:
  • sum the elements of the first cell array of a with the elements of the first cell array of b,
  • sum the elements of the second cell array of a with the elements of the second cell array of b,
  • sum the elements of the third cell array of a with the elements of the third cell array of b,
  • and so on.....?
Something like this for example ?
c{1} = a{1}+b{1}
c{2} = a{2}+b{2}
c{3} = a{3}+b{3}
...
Please see the following example:
% Input
>> a
a =
3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]}
{[21 0 0 0 0 0 0 31 64 53 50 81 55 72 76 93 108 81 81 52 50 38 32 41]}
{[ 0 0 0 0 0 0 0 0 29 35 32 41 34 42 21 38 23 36 30 32 0 0 0 0]}
>> b
b =
3×1 cell array
{0×0 double }
{[548 296 154 116 148 220 370 773 1149 1014 1282 1182 1305 1303 1335 1463 1587 1465 1470 1114 1083 786 941 934]}
{[ 56 41 23 0 0 0 48 49 127 182 235 239 252 227 255 301 226 199 176 109 110 91 108 68]}
% Desired Output
>> c
c =
3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]}
{[569 296 154 116 148 220 370 804 1213 1067 1332 1263 1360 1375 1411 1556 1695 1546 1551 1166 1133 824 973 975]}
{[ 56 41 23 0 0 0 48 49 156 217 267 280 286 269 276 339 249 235 206 141 110 91 108 68]}
>>

Accepted Answer

Stephen23
Stephen23 on 9 Feb 2023
Edited: Stephen23 on 9 Feb 2023
a = {[0,0,0,0,0,0,0,36,43,48,42,49,51,64,55,57,86,69,53,37,35,37,31,0];
[21,0,0,0,0,0,0,31,64,53,50,81,55,72,76,93,108,81,81,52,50,38,32,41];
[0,0,0,0,0,0,0,0,29,35,32,41,34,42,21,38,23,36,30,32,0,0,0,0]};
b = {[];
[548,296,154,116,148,220,370,773,1149,1014,1282,1182,1305,1303,1335,1463,1587,1465,1470,1114,1083,786,941,934];
[56,41,23,0,0,0,48,49,127,182,235,239,252,227,255,301,226,199,176,109,110,91,108,68]};
This works if either a or b contain empty matrices:
f = @(x,y)sum(cat(3,x,y),3);
c = cellfun(f,a,b,'uni',0)
c = 3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]} {[569 296 154 116 148 220 370 804 1213 1067 1332 1263 1360 1375 1411 1556 1695 1546 1551 1166 1133 824 973 975]} {[ 56 41 23 0 0 0 48 49 156 217 267 280 286 269 276 339 249 235 206 141 110 91 108 68]}
It relies on this behavior of the CAT() function: "When concatenating an empty array to a nonempty array, cat omits the empty array in the output. For example, cat(2,[1 2],[]) returns the row vector [1 2]."
  3 Comments
Paul
Paul on 9 Feb 2023
Excellent solution.
One case that could cause a problem would be if a and b both contained an empty matrix in the same element and those emptys are not compatible for concatentation:
f = @(x,y)sum(cat(3,x,y),3);
a={zeros(0,1)};
b={zeros(1,0)};
c = cellfun(f,a,b,'uni',0)
Error using cat
Dimensions of arrays being concatenated are not consistent.

Error in solution (line 1)
f = @(x,y)sum(cat(3,x,y),3);
So it depends on what the possibilites are for however those empty matrices showed up in a and b. Also, if the empties are of different dimension and compatible for concatenation, make sure to look at how this works and that it gives the result you want.
If the empty matrix in a or b will alwasy be 0 x 0, as in the example, then there should never be a problem, I don't believe.
Sim
Sim on 9 Feb 2023
Oh, sharp insight, I did not notice this aspect...! So, in case both a and b contained an empty matrix in the same element, and those empties were not compatible for concatenation, I would get that error... Well, at least, I would get an error that I could try to solve, and not just an unexpected odd value/outcome without any error, that I would not likely have noticed... :-)

Sign in to comment.

More Answers (1)

Paul
Paul on 9 Feb 2023
Edited: Paul on 9 Feb 2023
Would be easier if the first element of b weren't empty. Logic would need to be modified a bit if there is a possiblity that a can contain empty arrays.
a = {[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0];
[21 0 0 0 0 0 0 31 64 53 50 81 55 72 76 93 108 81 81 52 50 38 32 41];
[ 0 0 0 0 0 0 0 0 29 35 32 41 34 42 21 38 23 36 30 32 0 0 0 0]};
b = {[];
[548 296 154 116 148 220 370 773 1149 1014 1282 1182 1305 1303 1335 1463 1587 1465 1470 1114 1083 786 941 934] ;
[ 56 41 23 0 0 0 48 49 127 182 235 239 252 227 255 301 226 199 176 109 110 91 108 68]} ;
k = cellfun(@isempty,b);
c = cell(size(a));
c(k) = a(k);
c(~k)= cellfun(@(a,b) a+b,a(~k),b(~k),'Uni',0);
c
c = 3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]} {[569 296 154 116 148 220 370 804 1213 1067 1332 1263 1360 1375 1411 1556 1695 1546 1551 1166 1133 824 973 975]} {[ 56 41 23 0 0 0 48 49 156 217 267 280 286 269 276 339 249 235 206 141 110 91 108 68]}
  3 Comments
Paul
Paul on 9 Feb 2023
You're not wrong, that only checks if b is empty. Would also need to check for empty elements of I'd need to also check for empty cells in a and then deal with all combinations of empty/not-empty appropriately.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!