2

我有一个代码如下:

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

2 回答 2

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。

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

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

于 2014-04-11T05:30:35.713 回答
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)';

但是,这并没有很大的性能改进,因为它仅在有限范围的小数据大小上要快一些。

于 2014-04-11T04:32:29.500 回答