Row by column multiplication
17 views (last 30 days)
Show older comments
Consider two matrices A and B defined by
A=rand(10,3);
B=rand(3,10);
I'm interested in multiplying the vectors defined the first, second, and third rows in B by the vectors defined the first, second, and third columns in A, respectively. My intent is to generate ten, 3X3 matrices defined by
Matrix1= B(:,1)*A(1,:)
Matrix2= B(:,2)*A(2,:)
...
Matrix10= B(:,10)*A(10,:)
My initial thought was something like
B(:,1:10)*A(1:10,:)
but this approach populates the matrices B and A prior to multiplication, yielding a single 3X3 matrix. How to I change the "order-of-operations" if you will---call each vector on a term-by-term basis, multiplying in between each call to generate the desired matrix? Of course, I really want to avoid having to use for loops.
0 Comments
Accepted Answer
Matt J
on 15 Oct 2012
Here's a completely vectorized method, which requires James Tursa's MTIMESX function, available at the link below
A=reshape(A',1,3,10);
B=reshape(B,3,1,10);
C=mtimesx(B,A)
3 Comments
Amandeep Gautam
on 22 Oct 2015
I wonder if there is anything wrong with A' * B? Seems like it does the same thing. Can you comment?
Matt J
on 22 Oct 2015
That will generate an error
>> A=rand(10,3); B=rand(3,10); A'*B
Error using *
Inner matrix dimensions must agree.
More Answers (4)
Azzi Abdelmalek
on 15 Oct 2012
Edited: Azzi Abdelmalek
on 15 Oct 2012
for k=1:10
matrix{k}=B(:,k)*A(k,:)
end
%or
for k=1:10
matrix(:,:,k)=B(:,k)*A(k,:)
end
0 Comments
Matt Fig
on 15 Oct 2012
Edited: Matt Fig
on 15 Oct 2012
I think you can avoid FOR loops, but I see no reason to do so here:
A=randi(10,10,3);
B=randi(10,3,10);
for ii = 10:-1:1,C{ii} = B(:,ii)*A(ii,:);end
Here is a vectorization, but I can almost guarantee you it will be slower than the above FOR loop:
cellfun(@mtimes,mat2cell(B,3,ones(1,10)).',mat2cell(A,ones(1,10),3),'Un',0)
0 Comments
Matt J
on 15 Oct 2012
Here's a 1-liner. It's syntactically brief, but not superior to using loops directly,
C=cellfun(@(a,b) a(:)*b(:).', num2cell(B,1), num2cell(A,2).', 'uni',0)
0 Comments
Richard Brown
on 15 Oct 2012
Edited: Richard Brown
on 15 Oct 2012
There is a built in way to do it quickly if you use sparse multiplication. Essentially, you construct the block diagonal matrix blkdiag(B(:, 1), ... , B(:, N)) directly, and multiply it by A to give Y = [B(:, 1)*A(1, :) ; ... ; B(:, N) * A(N, :)]
N = 10000;
A = rand(N, 3);
B = rand(3, N);
I = 1:3*N;
J = repmat(1:N, 3, 1);
Y = mat2cell(sparse(I, J, B) * A, repmat(3, N, 1), 3);
edit: brief explanation added
3 Comments
Richard Brown
on 16 Oct 2012
Well, it depends what precisely speaking we mean by "built in" doesn't it?! My definition is that if it comes with a basic MATLAB install it's builtin.
Also, the mat2cell call isn't necessary -- it's just to convert it to the output format in some of the other answers. And the code doesn't touch the branch of repmat that uses for loops. Poor old for loops, they get such a hard time here :)
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!