5
votes

I need to multiply a matrix A with n matrices, and get n matrices back. For example, multiply a 2x2 matrix with 3 2x2 matrices stacked as a 2x2x3 Matlab array. bsxfun is what I usually use for such situations, but it only applies for element-wise operations. I could do something like:

blkdiag(a, a, a) * blkdiag(b(:,:,1), b(:,:,2), b(:,:,3))

but I need a solution for arbitrary n - ?

3
mathworks.com/matlabcentral/newsreader/view_thread/311944 check out the comments for FEX linksDan
Cannot test now, but in the example times is used, perhaps mtimes can be substituted here.Dennis Jaheruddin

3 Answers

7
votes

You can reshape the stacked matrices. Suppose you have k-by-k matrix a and a stack of m k-by-k matrices sb and you want the product a*sb(:,:,ii) for ii = 1..m. Then all you need is

sza = size(a);
b = reshape( b, sza(2), [] ); % concatenate all matrices aloong the second dim
res = a * b; 
res = reshape( res, sza(1), [], size(sb,3) ); % stack back to 3d
3
votes

Your solution can be adapted to arbitrary size using comma-saparated lists obtained from cell arrays:

[k m n] = size(B);
Acell = mat2cell(repmat(A,[1 1 n]),k,m,ones(1,n));
Bcell = mat2cell(B,k,m,ones(1,n));
blkdiag(Acell{:}) * blkdiag(Bcell{:});

You could then stack the blocks on a 3D array using this answer, and keep only the relevant ones.

But in this case a good old loop is probably faster:

C = NaN(size(B));
for nn = 1:n
    C(:,:,nn) = A * B(:,:,nn);
end
1
votes

For large stacks of matrices and/or vectors over which to execute matrix multiplication, speed can start becoming an issue. To avoid re-inventing the wheel, you could simply compile and use the following fast MEX code: MTIMESX - Mathworks. As a rule of thumb, MATLAB is often quite inefficient at executing for loops over large numbers of operations which look like they should be vectorizable; I cannot think of a straightforward way of generalising Shai's answer to this case.