【问题标题】:octave is slow; suggestions八度很慢;建议
【发布时间】:2016-07-08 18:04:48
【问题描述】:

在 Octave 4.0.0 和 MATLAB 2014 中都运行了以下代码。时间差很愚蠢,即超过两个数量级。在 Windows 笔记本电脑上运行。可以做些什么来提高 Octave 的计算速度?

startTime = cputime;
iter = 1;  % iter is the current iteration of the loop
itSum = 0;  % itSum is the sum of the iterations
stopCrit = sqrt(275);  % stopCrit is the stopping criteria for the while loop
while itSum < stopCrit
   itSum = itSum + 1/iter;
   iter = iter + 1;
   if iter > 1e7, break, end
end
iter-1
totTime = cputime - startTime

八度:totTime ~ 112

MATLAB:totTime

【问题讨论】:

  • 我不知道您是否注意到您的函数计算谐波系列的总和。因此,如果您有很多迭代,您最好使用 sum(1./(1:exp(stopCrit)) 例如,然后调整总和,直到 sum(1./(1:#iteration)) = stopCrit。

标签: performance matlab octave computation


【解决方案1】:

在循环中需要多次迭代才能计算代码中的结果。矢量化代码将有助于加快速度。我的以下代码与您所做的完全一样,但对计算进行了相当多的矢量化。看看有没有帮助。

startTime = cputime;
iter = 1;  % iter is the current iteration of the loop
itSum = 0;  % itSum is the sum of the iterations
stopCrit = sqrt(275);  % stopCrit is the stopping criteria for the while loop
step=1000;
while(itSum < stopCrit && iter <= 1e7)
    itSum=itSum+sum(1./(iter:iter+step));
    iter = iter + step+ 1;
end
iter=iter-step-1;
itSum=sum(1./(1:iter));
for i=(iter+1):(iter+step)
    itSum=itSum+1/i;
    if(itSum+1/i>stopCrit)
        iter=i-1;
        break;
    end
end
totTime = cputime - startTime

使用上面的代码,我的运行时间只有大约 0.6 秒。如果你不关心循环停止的确切时间,下面的代码会更快:

startTime = cputime;
iter = 1;  % iter is the current iteration of the loop
itSum = 0;  % itSum is the sum of the iterations
stopCrit = sqrt(275);  % stopCrit is the stopping criteria for the while loop
step=1000; 
while(itSum < stopCrit && iter <= 1e7)
    itSum=itSum+sum(1./(iter:iter+step));
    iter = iter + step+ 1;
end
iter=iter-step-1;
totTime = cputime - startTime

在后一种情况下,我的运行时间只有大约 0.35 秒。

【讨论】:

  • 有点混乱,因为您的代码执行的步骤长度为step+1
  • @Daniel,你是对的。我的代码的目的只是为了说明对代码进行矢量化可以加快很多速度。除了step=1001之外,还有很多方法可以改进我的代码,比如调整步长,使用二分法找到第一个循环后的最后一个位置itSum&lt;stopCrit等等。
【解决方案2】:

你也可以试试:

    itSum = sum(1./(1:exp(stopCrit)));
    %start the iteration
    iter  = exp(stopCrit-((stopCrit-itSum)/abs(stopCrit-itSum))*(stopCrit-itSum));
    itSum = sum(1./(1:iter))

使用这种方法,您将只有 1 或 2 次迭代。但是当然你每次对整个数组求和。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2018-10-17
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多