Multiply then sum elements of two matrices

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?

 Accepted Answer

It is not clear from your question whether corresponding elements are to be multiplied or if you are wanting to do a matrix multiplication.
If corresponding elements are to be multiplied, then you could calculate the sum-of-products using
dot(A(:),B(:))

1 Comment

The mathematical name of the operation is called Frobenius Product, by the way.

Sign in to comment.

More Answers (3)

I believe
sum(A(:).*B(:))
would be faster than dot(...) if that matter.

2 Comments

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.
Hi Bruno and Walter, thanks for the answers. I used them both and they worked! I'm new to Matlab so I don't know yet how to clock the processing time....I will learn. Great user community feedback!

Sign in to comment.

A bit of self-promotion:
mtimesx(A(:),'T',B(:),'speedomp')
You can find mtimesx here:

2 Comments

Or if you prefer to stay with MATLAB built-in functions:
A(:).'*B(:)
James, thanks for the answer as well!

Sign in to comment.

Matt Fig
Matt Fig on 28 Feb 2011
Another (this should be faster than calling SUM):
reshape(A,1,[])*reshape(B,[],1)

9 Comments

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 ?
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.
The fastest (2010B-64 Window 7) is
ps = A(:).'*B(:);
It obviously use multithreading BLAS, which is hard to beat.
Bruno
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.
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.}
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.
>>
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.
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.
Matt, thanks for your feedback as well. Yours works too - but I never would have figured that out...something to think about. Again, great user community here.

Sign in to comment.

Categories

Find more on Operators and Elementary Operations in Help Center and File Exchange

Asked:

F
F
on 28 Feb 2011

Commented:

on 12 Dec 2020

Community Treasure Hunt

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

Start Hunting!