【问题标题】:Vectorize for loop with interdependent iterations使用相互依赖的迭代向量化 for 循环
【发布时间】:2015-12-19 15:34:44
【问题描述】:

r 是一个向量:

23 1 24 5 4 3 7 8

L 是一个向量。

L=
 2, 4, 6, 5, 3

我正在尝试对这段代码进行矢量化处理。由于迭代是相互依赖的(即prev_weight = prev_weight - weight_from),我无法找到一种好的矢量化方法。目标显然是最小化执行时间。

    total_weight = sum(r(L));
    prev_weight = total_weight;

    len=length(L);

    dist = 0.0;
    for i=2:len-1
        from=L(i);
        to=L(i+1);
        dist = dist + d(from,to) * prev_weight;
        weight_from = r(from);
        prev_weight = prev_weight - weight_from;
    end

【问题讨论】:

  • dfromto 是什么?
  • @Divakar:d 是距离矩阵(二维数组)。 from 和 to 相应地定义为 L(i) 和 L(i+1)。此代码估计加权行程长度。

标签: performance matlab vectorization


【解决方案1】:

这种依赖关系可以追溯到cummulative sum 操作,它构成了下面列出的矢量化解决方案的基础 -

%// Vectorized way to get "d(from,to)" across all iterations with SUB2IND
vals = d(sub2ind(size(d),L(2:end-1),L(3:end)))

%// Vectorized way to get "r(from)" as we already have all "from" indices
weight_from1 = r(L(2:end-1))

%// Magic happens here as we trace the dependency with cumsum and thus
%// get all previous weights in one go
prev_weight1 = total_weight - [0 cumsum(weight_from1(1:end-1))]

%// Finally get the distance with elementwise multiplication and summing
%// being simulated with dot product
dist_out = vals*prev_weight1.'

【讨论】:

  • 我检查了您的解决方案。看起来很好。就一个问题。虽然 weight_from1 与我的解决方案相同,但 prev_weight1 与我的 prev_weight 略有不同。为什么会发生这种情况?
  • 如果length(L)小于等于2怎么办?
  • @KlausosKlausos 所以对于len <=2,因为它不会进入循环,你可以用len >2检查这种情况:做这个矢量化解决方案,否则0。我认为轻微的不匹配是因为在非常大的数组上执行累积操作时,当它试图将一个元素添加到已经累积的巨大数字时。
  • 我测量了矢量化解决方案的总执行时间,它甚至比我原来的解决方案还要长。矢量化工作人员真的很烦人。在 Java 或 C 中正确实现事物要容易得多,以避免以后出现执行时间过长的问题。不过还是感谢您提供了一个不错的解决方案。
  • @KlausosKlausos 真的吗?我真的期待矢量化解决方案更快!嗯,我有点惊讶!
猜你喜欢
  • 2021-04-12
  • 2020-03-03
  • 2011-09-18
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 2020-07-25
相关资源
最近更新 更多