【问题标题】:Vectorize a for loop in which the input depends on the output向量化一个 for 循环,其中输入取决于输出
【发布时间】:2012-11-23 01:01:41
【问题描述】:

我有一个关于循环依赖向量化的复杂问题,我想从你那里得到一些帮助。

让我们X1 是一个长度为n1 的向量,X2 是一个长度为n2F1 的向量是一个N1xn1 矩阵,F2 是一个N2 xn2 矩阵,QN1xN2 矩阵,符号p... 是索引向量。 ntrapz 是梯形数值积分的函数。我想计算矩阵Q如下:

for i1=1:N1
    F1_13tmp=F1(i1, p1_13)';                       % ' 
    F1_13=F1_13tmp(:,ones(n2,1));
    for i2=1:N2
        F2_13 = F2(i2, p2_13);
        Q_13_13 = Q(p1_13, p2_13);
        Q(i1,i2) = Q(i1,i2) + 
              ntrapz(X2(p2_13), ntrapz(X1(p1_13)', Q_13_13.*F1_13).*F2_13);
    end
end

问题是更新Q(i1,i2) 会更改Q_13_13 = Q(p1_13, p2_13) 的值以进行下一次迭代。我想知道我们是否可以矢量化这样的 for 循环。如果没有,有什么加快代码速度的想法吗?

提前感谢您的帮助。

【问题讨论】:

  • 在 Matlab 中对所有内容进行矢量化的旧建议就是这样,旧建议。最近(可能自 2010 年以来)Matlab 运行时的进步使基于循环的程序在许多情况下与矢量化程序一样快。我不会说你不能向量化你的代码(因为循环依赖)或者如果你这样做你不会看到性能改进,但不要提高你对向量化版本将显示显着性能的期望改进,足以证明您(以及一般情况下)花在设计上的时间是合理的。
  • 感谢您的评论。我有 Matlab R2010b,我不知道基于循环的程序是否真的和矢量化程序一样快。在程序中由于N1*N2比较大(91204),所以即使像“Q_13_13 = Q(p1_13, p2_13)”这样的简单命令也需要相当长的时间(1,06s)。

标签: performance matlab for-loop vectorization


【解决方案1】:

矢量化通常是并行操作的方式。但是,在您的情况下,您似乎有顺序操作,并且这些操作通常不适合矢量化。

我不熟悉您使用的函数,但我能想到的唯一可能加快计算速度的方法是以非依赖形式编写它。请注意,这更像是一个数学练习而不是编程练习,这是一个简单的例子:

假设公式等于:

Y(1)=0.5;
Y(t)=0.3*Y(t-1)+epsilon(t);
% Let as assume epsilon is also known
epsilon = rand(9,1)

计算 Y(10) 的简单方法是执行 10 个计算步骤。

for t=2:10
    Y(t)=0.3*Y(t-1)+epsilon(t);
end

计算 Y(10) 的最快方法是这样做(不确定它是否正确,但应该接近)

Y(10)=Y(1)*0.3^9 + sum(epsilon.^(1:9))

因此得出结论:“矢量化”循环的唯一方法是,您是否可以显着帮助计算机并基本上让它进行不同的计算。如果这是不可能的,您当然可以尝试通过将其制作为 mex 文件来挤出一点额外的速度。

【讨论】:

  • 非常感谢您的回答。如果我没记错的话,您的示例将返回 for 循环的最后一个元素。这似乎不适用于我的情况,因为我需要矩阵 Q 的所有位置。在程序中,矩阵 Q 每次迭代都会更新,矩阵 Q 的每个位置都是上次更新 Q 的积分结果. 也许矢量化是不可能的?!
猜你喜欢
  • 2022-11-26
  • 2013-07-25
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 2011-06-13
  • 2014-11-27
相关资源
最近更新 更多