在matlab中有效地计算许多内部产品

Jef*_*Dun 3 matlab vectorization bsxfun

我正在研究一个项目,我需要在这个项目中计算大量的内部产品.我知道我们应该总是尝试在matlab中对操作进行矢量化,但我不知道如何做到这一点......

比方说,我们有两个矩阵,AB大小的N x d地方N是计算在内的产品的数量d方面.

使用for循环很容易实现,但我怀疑存在更有效的方法.for循环实现可能如下所示:

innerprods=zeros(N,1);
for i=1:N
    innerprods(i)=A(i,:)*B(i,:)';
end
Run Code Online (Sandbox Code Playgroud)

有没有人有想法如何矢量化这个?我想bsxfun应该在某些时候发挥作用,但我无法弄清楚如何使用它...

提前致谢!

Ole*_*leg 5

那么简单:

sum(A.*B,2)
Run Code Online (Sandbox Code Playgroud)

一个简单的测试(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
Run Code Online (Sandbox Code Playgroud)

loop     5.6 sec
multsum  0.8 sec
Run Code Online (Sandbox Code Playgroud)

对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
Run Code Online (Sandbox Code Playgroud)

主要外卖点:

  • 在这种情况下循环是非常低效的(预期);
  • 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)
Run Code Online (Sandbox Code Playgroud)