6
votes

I have a cell array of cell(1, n) called A, with each cell entry containing a matrix of mxn. So, in effect, my cell array contains n matrices of size mxn.

I then have another cell array called B, with n pxm matrices stored in it.

What I need to do is multiply the two against each other, as in: A[1] * B[1], A[2] * B[2], ..., A[n] * B[n]. I then need to store the results as individual matrices of their own, and sum them up.

The matrices are conformal for multiplication, but because cell array B contains less rows than cell array A, when I use cellfun(@times A, B, 'UniformOutput', true) I get an unequal matrices error.

This seems to indicate that cellfun can only multiply individual cells when the matrices have equal numbers of rows and columns.

Now, I could perform this by using various loops, or by calling cell2mat and mat2cell, and so on. I could also just store everything as a matrix array rather than using cells... but - I would prefer to use cells.

So - my question is: Is there a good way of doing this using only cellfun? I have tried various combinations of argument inputs already - but with no luck so far.

2

2 Answers

2
votes

To do this with cellfun, just define your own anonymous function:

C = cellfun(@(a,b) a*b, A, B, 'UniformOutput', 0);

Now, as you posed the question, you cannot multiply A*B, because the inner dimensions don't agree. Instead, I tested this with B*A, where the dimensions do agree: p=1, m=3, n=3.

A = {eye(3), rand(3), magic(3)};
B = {[1 2 3], [3 5 1], [7 8 8]};

C = cellfun(@(a,b) b*a, A, B, 'UniformOutput', 0);

Cmat = cat(3, C{:});
S = sum(Cmat, 3);

The sum is done by concatenating each array of C over a third dimension then summing over it.

2
votes

Yes, the arguments need to be of the same size. From help cellfun:

A = cellfun(FUN, B, C, ...) evaluates FUN using the contents of the cells of cell arrays B, C, ... as input arguments. The (I,J,...)th element of A is equal to FUN(B{I,J,...}, C{I,J,...}, ...). B, C, ... must all have the same size.

So either use loops, or remove the extra elements from the cell with a larger number of elements before you call cellfun:

% assuming B has more elements than A
B(numel(A)+1:end) = [];