2
votes

I have a NxNx4 matrix(A) and a 4x4 matrix (B). I need to multiply the vector a composed by the four elements of the first matrix A, let's say

a = A(1,1,1) 
    A(1,1,2)
    A(1,1,3)
    A(1,1,4)

by the 4x4 matrix B but I'm not sure if there is a faster and clever solution than using a for loop to build the vector a. Does exist a way to do this computation with few lines of code?

I built A like

A(:,:,1) = rand(20);
A(:,:,2) = rand(20);
A(:,:,3) = rand(20);
A(:,:,4) = rand(20);

and the matrix B

B = rand(4);

now I want to multiply B with

B*[A(1,1,1);A(1,1,2);A(1,1,3);A(1,1,4)]

This, for each element of A

B*[A(1,2,1);A(1,2,2);A(1,2,3);A(1,2,4)]
B*[A(1,3,1);A(1,3,2);A(1,3,3);A(1,3,4)]
...
3
You describe having an N*N*4 matrix, and a 4*4 matrix, and your example a is neither! Please show a minimal reproducible example of your expected input / output, this sounds relatively easy if it were well defined, but at present it's unclear. - Wolfie
How does it look now? - Shika93
That's a lot clearer, my only other question will be what your expected output is? Each multiplication yields a 4*1 vector, I guess your expected output C is a matrix the same size as A? - Wolfie
That's right. C is supposed to be again an NxNx4 matrix. I'm choosing the multidimensional matrix instead of 4 separate matrix to be able to compute the classical multiplication matrix-vector B*a - Shika93
I'm not entirely sure based on your explanation if you simply need bsxfun(@times, ...) or something more advanced like mmx or mtimesx. - Dev-iL

3 Answers

1
votes

You can do this with a simple loop, note loops aren't necessarily slow in newer MATLAB versions. Mileage may vary.

Loops have the advantage of improving code readability, it's extremely clear what's happening here:

% For matrix A of size N*N*4
C = zeros( size( A ) );
for ii = 1:N
    for jj = 1:N
        C( ii, jj, : ) = B * reshape( A( ii, jj, : ), [], 1 );
    end
end
1
votes

A loop solution that has good performance specially when N is large:

s = size(A, 3);
C = A(:,:,1) .* reshape(B(:,1),1,1,[]);
for k = 2:s
    C = C + A(:,:,k) .* reshape(B(:,k),1,1,[]);
end
0
votes

I think this does what you want:

C = permute(sum(bsxfun(@times, permute(B, [3 4 2 1]), A), 3), [1 2 4 3]);

Check:

>> C(1,2,:)
ans(:,:,1) =
   1.501739582138850
ans(:,:,2) =
   1.399465238902816
ans(:,:,3) =
   0.715531734553844
ans(:,:,4) =
   1.617019921519029
>> B*[A(1,2,1);A(1,2,2);A(1,2,3);A(1,2,4)]
ans =
   1.501739582138850
   1.399465238902816
   0.715531734553844
   1.617019921519029