1
votes

A simple example to illustrate all elements of a matrix multiplying each element of a vector to generate a 3D array.

M = reshape(1:12,4,3);
V = 1:2;
n = length(V);
A = nan([size(M),n]);
for ii = 1 : n
  A(:,:,ii) = M * V(ii);
end

then

A(:,:,1) =

 1     5     9
 2     6    10
 3     7    11
 4     8    12

A(:,:,2) =

 2    10    18
 4    12    20
 6    14    22
 8    16    24

Or by repmat both M and V to the size of [4,3,2],

A = repmat(M,1,1,n) * reshape(V(ones(size(M)),:),[size(M),n])

It creates two 3D array by repmat besides the resulting 3d array A.

How to make it efficiently WITHOUT for loop and save the memory use?

According to the answer by @Lincoln,

A = bsxfun(@times, repmat(M,1,1,n), reshape(1:n, 1, 1, n));

repmat the vector V to 3d is not necessary.

Is it possible to create NO 3d array if the final result wanted is 2d, the sum of A along the 3rd dim? By for loop, the code would be

M = reshape(1:12,4,3);
V = 1:2;
n = length(V);
A = 0;
for ii = 1 : n
  A = A + M * V(ii);
end
1
@percusse in the first code snippet, n = length(V)Lee
what happened to my comment I don't know. But for n=2 you don't have much benefit from vectorization.percusse
@percusses the code snippet is a simple demonstration to clarify my problem. The true data are quite large. I cannot print millions of lines here.....Lee
That's why I asked what n is in your application but nevermind.percusse

1 Answers

2
votes

Try replacing the for.. loop with:

M_rep = repmat(M,1,1,n) %//repeat M in the 3rd dimension n times
v = reshape(1:n, 1, 1, n) %//create a vector [1 2 .. n] pointing in the third dimension
A = bsxfun(@times, M_rep, v) %//vector multiply them in the third dimension

In your above example, n=2.

EDIT (to your added question): To sum without allocating A:

B = sum(bsxfun(@times, M_rep, v),3);