【问题标题】:How to vectorize two for loops in matlab for speed up如何在matlab中向量化两个for循环以加快速度
【发布时间】:2014-06-06 02:41:35
【问题描述】:

如何通过 MATLAB 中的矢量化来加速下面的两个 for 循环?这是迭代算法的一部分,我需要做很多次。

Temp1=0;
Temp2=0;

for i=1:m_plus
    for j=1:m_minus
        Temp1=Temp1+(p_m(j,:)-p_p(i,:))';
        Temp2=Temp2+(p_m(j,:)-p_p(i,:))'*(p_m(j,:)-p_p(i,:));
    end
end

【问题讨论】:

  • m_plus 和 m_minus 的值是多少? p_m 和 p_p 的尺寸是多少?它们可以有多大?
  • m_plus 和 m_minus 是标量值。 p_m 和 p_p 是具有不同行和相同列的非方阵。例如:p_m: 1000 * 200 和 p_p: 1500 * 200

标签: matlab loops vectorization


【解决方案1】:

假设

m_plus = size(p_p,1);
m_minus = size(p_m,1);

那么很容易做到Temp1 没有循环

Temp1 = (m_plus*sum(p_m)-m_minus*sum(p_p))'

对于Temp2,很容易摆脱其中一个循环,

Temp2 = 0;
for idx = 1:m_plus
    temp = p_m-ones(m_minus,1)*p_p(idx,:); % or could use bsxfun to do this
    Temp2 = Temp2 + temp'*temp;
end

虽然稍加思考,也有可能摆脱这个循环。

【讨论】:

  • 亲爱的戈达德,感谢您的回答和时间。我检查了两种情况下 Temp1 和 Temp2 的结果(有矢量化和没有矢量化),Temp2 的结果略有不同。请让我知道它仍然正确吗?
  • 这个小差异对我的代码中的最终结果没有影响。我很感激你。我将尝试删除第二个循环。再次感谢戈达德。
  • 差值应在 1e-15(或更小)范围内。这是由于执行数学运算的顺序不同。对于它们的计算顺序,两者都是正确的。
  • +1 为这个聪明的方法,另外让我注意到这个有趣的问题!
【解决方案2】:

另一种受Phil's smart answer启发的矢量化方法-

t1 = bsxfun(@minus,p_m,permute(p_p,[3 2 1]));
t2 = reshape(permute(t1,[1 3 2]),m_minus*m_plus,[]);
Temp1 = sum(t2)'; %//'
Temp2 = t2'*t2;

【讨论】:

  • 谢谢 Divakar,但是,当我在 matlab 上测试了这两个代码时。行 Temp2 = t2'*t2;耗费大量时间,因此代码比只使用一个 for 循环要慢。我不明白为什么这条线很耗时。
  • @Pey 这个bsxfun 实现的Temp1 的计算肯定看起来比@Phil 的解决方案要慢,但是Temp2 这个解决方案的计算需要来自bsxfun 的值。总体而言,Temp1Temp2 的计算与@Phil 的解决方案相当,但我不确定我的解决方案是否比其他解决方案显示出任何明显的性能改进。
  • 感谢您的解释。但是,您的努力是值得的,因为您没有使用任何 for 循环。我从你和 Phil 解决方案中学到了很多关于矢量化的知识。
  • @Pey 听起来真的很棒!
猜你喜欢
  • 2021-06-11
  • 1970-01-01
  • 2012-10-24
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
相关资源
最近更新 更多