通过置换来避免matlab脚本中的'for'循环

xue*_*liu 2 matlab bsxfun

我有一个代码如下:

Ne = 100;
H = rand(Ne,Ne);
g = zeros(Ne,1);

for e =1:Ne
    hue = H(:,e);
    ss1 =  bsxfun(@times, hue', hue) .* M;   % M is a Ne*Ne matrix
    g(e) = sum(ss1(:));
end
Run Code Online (Sandbox Code Playgroud)

当Ne> 1000时,它运行得非常慢.

我阅读了matlab文档,并找到了permute函数是一种可能的加速方法.但我试了整整一天却失败了.

这是我的代码,我不知道出了什么问题.

C = permute(bsxfun(@times, permute(H, [1 3 2]), permute(H', [1 3 2])), [1 3 2]);
g = sum(sum(C))
Run Code Online (Sandbox Code Playgroud)

Raf*_*iro 6

如果你做数学计算,你会发现你所要做的就是:

g = sum(H) .^ 2;
Run Code Online (Sandbox Code Playgroud)

运行速度:0.000681秒,Ne = 1000(原始代码耗时3.047315秒).

编辑:

现在,对于您编辑的代码,您所要做的就是:

g = diag(H.' * M * H);
Run Code Online (Sandbox Code Playgroud)

运行速度:0.072273秒,Ne = 1000.

如果您注意到如果重新排列术语,则可以获得加速,您可以避免第二次矩阵乘法(更改为点积),您只需要对列进行求和,如下所示:

g = sum(M.' * H .* H);
Run Code Online (Sandbox Code Playgroud)

运行速度:0.044190秒,Ne = 1000.

做数学总是一个好主意.我们花了一些时间,但代码获得了很好的加速.:)

注意:通过平均一百次运行的时间来测量运行速度.