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

时间:2014-04-11 02:54:51

标签: 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

当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))

2 个答案:

答案 0 :(得分:6)

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

g = sum(H) .^ 2;

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

修改

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

g = diag(H.' * M * H);

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

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

g = sum(M.' * H .* H);

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

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

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

答案 1 :(得分:1)

对于您编辑过的代码,这可行 -

H1 = permute(H,[1 3 2]);
H2 = permute(H,[3 1 2]);
p1 = bsxfun(@times,H2,H1);
p1 = bsxfun(@times,p1,M);
g = sum(reshape(p1,Ne*Ne,[]),1)';

尽管如此,这并没有很好的性能提升,因为它仅在有限范围的小型数据集上更快一点。