簡単なことはどうですか:
sum(A.*B,2)
簡単なテスト (R2013a WinVista 32bit Core duo):
N = 8e3;
A = rand(N);
B = rand(N);
tic
out = zeros(N,1);
for ii = 1:N
out(ii) = A(ii,:)*B(ii,:)';
end
toc
tic
out2 = sum(A.*B,2);
toc
all(out-out2 < 1e5*eps) % note difference in precision
タイムズ
loop 5.6 sec
multsum 0.8 sec
R2013a Win7 64 Xeon E5 での追加テスト
Avg time loop: 2.00906 seconds
Avg time multSum: 0.18114 seconds
Avg time bsxfun: 0.18203 seconds
Avg time reshapeMultSum: 0.18088 seconds
主なポイント:
- この場合のループは非常に非効率的です (予想されます)。
bsxfun()
オーバーヘッドはそれほど大きくありませんが (予想されます)、完全に冗長です。
- 列に再形成してから行列に戻すことも、MATLAB エンジンの列方向の操作 (つまり、最初に行に沿って) の内部「優先」により、利点が得られると予想されます。
- 構文を明確にするために、引き続き multSum: をお勧めします
sum(A.*B,2)
。
テスト スイート (100 回の試行の平均時間、固定行列サイズ 8e3、結果が 1e5*eps に等しい):
N = 8e3;
A = rand(N);
B = rand(N);
tic
for r = 1:100
out = zeros(N,1);
for ii = 1:N
out(ii) = A(ii,:)*B(ii,:)';
end
end
sprintf('Avg time loop: %.5f seconds', toc/100)
tic
for r = 1:100; out2 = sum(A.*B,2); end
sprintf('Avg time multSum: %.5f seconds', toc/100)
tic
for r = 1:100; out3 = sum(reshape(bsxfun(@times,A(:),B(:)),N,N),2); end
sprintf('Avg time bsxfun: %.5f seconds', toc/100)
tic
for r = 1:100; out4 = sum(reshape(A(:).*B(:),N,N),2); end
sprintf('Avg time reshapeMultSum: %.5f seconds', toc/100)