Multiply then sum elements of two matrices
Mostrar comentarios más antiguos
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 comentario
Ron Fredericks
el 12 de Dic. de 2020
Another way to calculate Frobenious dot product:
trace( A'*B );
Respuesta aceptada
Más respuestas (3)
Bruno Luong
el 28 de Feb. de 2011
I believe
sum(A(:).*B(:))
would be faster than dot(...) if that matter.
2 comentarios
Walter Roberson
el 28 de Feb. de 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
el 1 de Mzo. de 2011
James Tursa
el 28 de Feb. de 2011
A bit of self-promotion:
mtimesx(A(:),'T',B(:),'speedomp')
You can find mtimesx here:
2 comentarios
James Tursa
el 28 de Feb. de 2011
Or if you prefer to stay with MATLAB built-in functions:
A(:).'*B(:)
F
el 1 de Mzo. de 2011
Matt Fig
el 28 de Feb. de 2011
1 voto
Another (this should be faster than calling SUM):
reshape(A,1,[])*reshape(B,[],1)
9 comentarios
Walter Roberson
el 28 de Feb. de 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
el 28 de Feb. de 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
el 28 de Feb. de 2011
The fastest (2010B-64 Window 7) is
ps = A(:).'*B(:);
It obviously use multithreading BLAS, which is hard to beat.
Bruno
James Tursa
el 28 de Feb. de 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
el 28 de Feb. de 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
el 28 de Feb. de 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
el 28 de Feb. de 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
el 28 de Feb. de 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
el 1 de Mzo. de 2011
Categorías
Más información sobre Graphics Objects en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!