Multiply then sum elements of two matrices
Show older comments
What's the best way to 1) multiply all the elements between two similar sized matrices then 2) sum them into one single number/outcome?
1 Comment
Ron Fredericks
on 12 Dec 2020
Another way to calculate Frobenious dot product:
trace( A'*B );
Accepted Answer
More Answers (3)
Bruno Luong
on 28 Feb 2011
I believe
sum(A(:).*B(:))
would be faster than dot(...) if that matter.
2 Comments
Walter Roberson
on 28 Feb 2011
Heh. I just looked at the source for dot. It does sum(conj(a).*b) so yes, your suggestion should be slightly faster due to have a small bit less overhead.
F
on 1 Mar 2011
James Tursa
on 28 Feb 2011
A bit of self-promotion:
mtimesx(A(:),'T',B(:),'speedomp')
You can find mtimesx here:
2 Comments
James Tursa
on 28 Feb 2011
Or if you prefer to stay with MATLAB built-in functions:
A(:).'*B(:)
F
on 1 Mar 2011
Matt Fig
on 28 Feb 2011
1 vote
Another (this should be faster than calling SUM):
reshape(A,1,[])*reshape(B,[],1)
9 Comments
Walter Roberson
on 28 Feb 2011
I speculate that it would be slower. There have been reports that calling reshape with [] as a parameter is much slower than calling reshape with an explicit size.
reshape(A,1,numels(A))*reshape(B,numels(B),1)
would not have that difficulty.
I wonder about the speed difference...
When I suggested dot(), I was thinking in terms of the fact that the low level math libraries include optimized dot product routines, so I was expecting dot() to be a built-in. As it turns out not to be, I wonder if the Just In Time compiler is able to recognize the idiom and turn it in to a call to the library dot routines ?
Matt Fig
on 28 Feb 2011
I just checked and using RESHAPE is faster than using SUM (factor of 2.3), for
size(A) == [1000,1000].
Also, calling with NUMEL does speed things up even further, as you suggest. I knew about those reports you mention, but for some reason I thought MATLAB would deal with a vector reshape just as fast. Not.
Bruno Luong
on 28 Feb 2011
The fastest (2010B-64 Window 7) is
ps = A(:).'*B(:);
It obviously use multithreading BLAS, which is hard to beat.
Bruno
James Tursa
on 28 Feb 2011
For OP's benefit: The main difference between the sum(etc) methods and the matrix multiply methods is that for the sum(etc) methods an intermediate (potentially large) variable needs to be created to hold the results of the individual element-wise products, and then this needs to be summed up. So there is extra overhead in allocating, storing, re-accessing, and freeing involved. I believe that MATLAB has gotten smarter in recognizing the conj(a).*b and similar constructs and not forming conj(a) explicitly, but I don't know this for sure and under what circumstances it does. In any event, I would always avoid dot and sum(etc) in favor of a matrix multiply.
Walter Roberson
on 28 Feb 2011
Bruno, could you time A(:)'*B(:) against dot(A,B) for complex values? If there is a non-trivial speed difference, then perhaps Matlab could improve the performance of dot(). Subject to accuracy being the same, of course. {At the moment I don't see why the accuracies might differ materially.}
Bruno Luong
on 28 Feb 2011
Walter, here is the timing for 1e6 elements:
>> tic; ps1=A(:)'*B(:); toc
Elapsed time is 0.015140 seconds.
>> tic; ps1=A(:)'*B(:); toc
Elapsed time is 0.015249 seconds.
>> tic; ps1=A(:)'*B(:); toc
Elapsed time is 0.015283 seconds.
>> tic; ps2=dot(A(:),B(:)); toc
Elapsed time is 0.024569 seconds.
>> tic; ps2=dot(A(:),B(:)); toc
Elapsed time is 0.029747 seconds.
>> tic; ps2=dot(A(:),B(:)); toc
Elapsed time is 0.029475 seconds.
>>
James Tursa
on 28 Feb 2011
For complex arguments I would definitely advise using MTIMESX in 'SPEED' or 'SPEEDOMP' mode because loops are used in this case so that the input arrays are only accessed once (i.e., the memory is dragged through the high level cache only once). MATLAB, on the other hand, uses a series of real (not complex) BLAS calls to accomplish the calculation and this forces the input arrays to be dragged through the high level cache twice. This results in a significant speed improvement for MTIMESX.
James Tursa
on 28 Feb 2011
e.g., 32-bit WinXP Intel Core 2 Duo:
>> A = rand(3000) + rand(3000)*1i;
>> B = rand(3000) + rand(3000)*1i;
>>
>> tic;dot(A(:),B(:));toc
Elapsed time is 0.158458 seconds.
>> tic;dot(A(:),B(:));toc
Elapsed time is 0.165634 seconds.
>>
>> tic;A(:)'*B(:);toc
Elapsed time is 0.101896 seconds.
>> tic;A(:)'*B(:);toc
Elapsed time is 0.101962 seconds.
>>
>> mtimesx('speedomp')
ans =
SPEEDOMP
>> tic;mtimesx(A(:),'C',B(:));toc
Elapsed time is 0.061016 seconds.
>> tic;mtimesx(A(:),'C',B(:));toc
Elapsed time is 0.061558 seconds.
The symmetric case difference is even more dramatic:
>> tic;dot(A(:),A(:));toc
Elapsed time is 0.146473 seconds.
>> tic;dot(A(:),A(:));toc
Elapsed time is 0.146098 seconds.
>>
>> tic;A(:)'*A(:);toc
Elapsed time is 0.084071 seconds.
>> tic;A(:)'*A(:);toc
Elapsed time is 0.082746 seconds.
>>
>> tic;mtimesx(A(:),'C',A(:));toc
Elapsed time is 0.032382 seconds.
>> tic;mtimesx(A(:),'C',A(:));toc
Elapsed time is 0.032521 seconds.
F
on 1 Mar 2011
Categories
Find more on Operators and Elementary Operations 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!