I have a problem which I hope can be easily solved. A is a NG matrix, B is NG matrix. The goal is to get matrix C
which is equal to multiplying each column of transposed A by each row of B and summing resulting matrices; total number of such matrices before summing is NN, their size is GG This can be easily done in MatLab with two for-loops:
N=5;
G=10;
A=rand(N,G);
B=rand(N,G);
C=zeros(G);
for n=1:1:N
for m=1:1:N
C=C+A(m,:)'*B(n,:);
end
end
However, for large matrices it is quite slow.
So, my question is: is there a more efficient way for calculating C matrix in Matlab?
Thank you
There are several ways to multiply each column of a matrix by the corresponding element of the vector. The first is to use the REPMAT function to expand the vector to the same size as the matrix and them perform elementwise multiplication using . * -- however, this will require a large amount of memory.
In order for matrix multiplication to be defined, the number of columns in the first matrix must be equal to the number of rows in the second matrix. To find A B AB AB , we take the dot product of a row in A and a column in B.
If you write it all out for two 3×3 matrices, you'll find that the operation basically equals this:
C = bsxfun(@times, sum(B), sum(A).');
Running each of the answers here for N=50
, G=100
and repeating each method 100 times:
Elapsed time is 13.839893 seconds. %// OP's original method
Elapsed time is 19.773445 seconds. %// Luis' method
Elapsed time is 0.306447 seconds. %// Robert's method
Elapsed time is 0.005036 seconds. %// Rody's method
(a factor of ≈ 4000 between the fastest and slowest method...)
I think this should improve the performance significantly
C = zeros(G);
for n = 1:N
C = C + sum(A,1)'*B(n,:);
end
You avoid one loop, and should also avoid the problems of running out of memory. According to my benchmarking, it's about 20 times faster than the approach with two loops. (Note, I had to benchmark in Octace since I don't have MATLAB on this PC).
Use bsxfun
instead of the loops, and then sum
twice:
C = sum(sum(bsxfun(@times, permute(A, [2 3 1]), permute(B,[3 2 4 1])), 3), 4);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With