Multiply each element of a vector with a matrix

I want to multiply each element of a vector with a matrix such that I end up with a 3D matrix (or higher dimentions).
For example if A is a vector and B is a matrix I would write:
for indx=1:length(A)
result(:,:,indx)=A(indx).*B
end
Is for-loops the way to go here or are there any better solutions?

 채택된 답변

Sean de Wolski
Sean de Wolski 2012년 3월 8일

4 개 추천

BSXFUN!!!
B = [1 2; 3 4];
A = 1:5;
D = bsxfun(@times,B,reshape(A,1,1,numel(A)));
kron is notorious (at least in older versions) for being very slow.
And obligatory timings:
B = repmat([1 2; 3 4],10,10);
A = 1:50;
t1 = 0;
t2 = 0;
t3 = 0;
for ii = 1:100
tic
C = reshape(kron(A,B),[size(B),numel(A)]);
t1=t1+toc;
tic
D = bsxfun(@times,B,reshape(A,1,1,numel(A)));
t2=t2+toc;
tic
for indx = length(A):-1:1 % Backwards for pre-allocation
result(:, :, indx) = A(indx) .* B;
end
t3=t3+toc;
end
isequal(C,D,result)
[t1 t2 t3]
%{
ans =
1
ans =
0.0128 0.0069 0.0098
%}

댓글 수: 5

Jan
Jan 2012년 3월 8일
+1. BSXFUN. Even the three exclamation marks are no exaggeration.
Friedrich
Friedrich 2012년 3월 8일
+1 Nice one and its a way faster than kron and reshape.
Thank you! For my code I found that this was about 10 times faster than the for-loop.
I was also wondering if there is something similar for multiplicating a 2d matrix with slices 3d matrix?
for matrix multiplication, use a for-loop or James Tursa's mtimex on the FEX.
for element by element:
bsxfun(@times,magic(3),rand(3,3,10));

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

James Tursa
James Tursa 2012년 3월 8일

4 개 추천

Yet another method for completeness using an outer product formulation. May not be any faster than bsxfun et al:
result = reshape(B(:)*A(:).',[size(B) numel(A)]);
(This tip actually comes from Bruno via another thread)

댓글 수: 2

Nice
This is also a good solution. Sometimes a little faster than the bsxfun, and sometimes a little slower. It seems to depend on the sizes of the matrix and the vector.

댓글을 달려면 로그인하십시오.

Friedrich
Friedrich 2012년 3월 8일

1 개 추천

Hi,
try kron and reshape:
B = [1 2; 3 4]
A = 1:5
reshape(kron(A,B),[size(B),numel(A)])

댓글 수: 6

Thanks for a quick answer.
I tried this, but it was actually slower than the for loop.
Friedrich
Friedrich 2012년 3월 8일
Every other way I can think of is more complex and not very fast. So its seems that a for loop is the best way here.
Jan
Jan 2012년 3월 8일
You can look into the code of KRON. As far as I remember, this is a FOR loop also.
Friedrich
Friedrich 2012년 3월 8일
No there isnt. Its meshrgrid and smart indexing
Jan
Jan 2012년 3월 8일
I feel so blind without a Matlab installation. Is MESHGRID free of FOR loops now? I've read all the basic function in Matlab 4, 5.3, 6.5, 2008b, 2009a. Now I'm starting to get confused when I read them in 2011b again. It would be so nice to have a list of changes for each function...
Looking in meshgrid in 2012a it is just a series of reshapes and ones() used for indexing.

댓글을 달려면 로그인하십시오.

Jan
Jan 2012년 3월 8일

1 개 추천

Did you pre-allocate the output?
result = zeros([size(B), length(A)]);
for indx = 1:length(A)
result(:, :, indx) = A(indx) .* B;
end
Or:
for indx = length(A):-1:1 % Backwards for pre-allocation
result(:, :, indx) = A(indx) .* B;
end

댓글 수: 1

Yes I did. In my case the for-loop is fast enough. I was just hoping for a neater solution. I never thought of backwards for-loops for pre-allocation.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by