【问题标题】:speeding up some for loops in matlab加快matlab中的一些for循环
【发布时间】:2014-03-20 14:35:55
【问题描述】:

基本上,我正在尝试使用正向欧拉法求解二阶微分方程。我的代码中有一些 for 循环,这需要相当长的时间来解决,我想加快速度。有没有人有任何建议我该怎么做?

当查看它所花费的时间时,我注意到我在第 14 行的end 占用了我总时间的 45%。 end 到底在做什么?为什么要花这么多时间?

这是我的简化代码:

t = 0:0.01:100;
dt = t(2)-t(1);
B = 3.5 * t;
F0 = 2 * t;

BB=zeros(1,length(t));  % Preallocation
x = 2;                  % Initial value
u = 0;                  % Initial value

for ii = 1:length(t)
    for kk = 1:ii
        BB(ii) = BB(ii) + B(kk) * u(ii-kk+1)*dt;    % This line takes the most time
    end                                             % This end takes 45% of the other time
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * (F0(ii) - BB(ii));
end

运行代码需要 8.552 秒。

【问题讨论】:

  • 您可能会通过标记正确的语言获得更多帮助,因为答案可能取决于语言。
  • 您可以尝试用卷积的总和(conv 函数)替换最内层的循环,但我还没有完成。
  • 另外,如果您不介意预分配BB,不妨也预分配xu
  • @JoeSerrano 我尝试使用conv 函数,但它实际上比我目前的方法慢得多。

标签: performance matlab for-loop


【解决方案1】:

我认为你可以去掉内循环:

for ii = 1:length(t)
    for kk = 1:ii
        BB(ii) = BB(ii) + B(kk) * u(ii-kk+1)*dt;    % This line takes the most time
    end                                             % This end takes 45% of the other time
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * (F0(ii) - BB(ii));
end

所以BB(ii) = BB(ii)(初始化为零)+ sum for 1 to ii of BB(kk)* u(ii-kk+1).dt

但是 kk = 1:ii,所以对于给定的iiii-kk+1 → ii-(1:ii) + 1ii:-1:1

所以我认为这相当于:

for ii = 1:length(t)

    BB(ii) = sum(B(1:ii).*u(ii:-1:1)*dt);
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * (F0(ii) - BB(ii));

end

使用任何一种方法对我来说都不需要长达 8 秒,但只有一个循环的版本大约快 2 倍(BB 的输出似乎相同)。

【讨论】:

  • ii:-1:1 只是颠倒了索引的顺序吗?但除此之外,它非常出色!
  • 是的 - 这相当于只是翻转它。当然,可能有更优雅的编写方式。 ;)
  • fliplr 或 flipud 翻转向量。这些函数可能更具可读性,但似乎需要大约 3 倍的时间
【解决方案2】:

B(kk) * u(ii-kk+1)的sum循环只是conv(B(1:ii),u(1:ii),'same')

【讨论】:

    【解决方案3】:

    在 matlab 中加速循环的最好方法是尽量避免它们。尝试您是否能够执行矩阵运算而不是内部循环。例如,尝试将您在那里进行的计算分成小部分,然后决定是否有部分您可以提前执行而不知道循环的下一次迭代的结果。

    对于问题的第二部分,我的猜测:: end 包含检查循环是否运行另一轮,并且该检查本身并不长,但调用了 50.015.001 次!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多