scipy.odeint 理解内部时间步长

问题描述 投票:0回答:1

我正在 scipy 中使用 odeint 来集成函数。该函数实际上是一个向量(它是下面L_total 函数 的返回值)。我遇到的问题是,对于该向量的某些条目,集成非常简单,这意味着它不需要许多内部子步骤,但是对于其他一些值,集成应该更详细。我假设 odeint 需要多个子步骤,这就是应用于向量的每个条目的子步骤。如果这个假设是正确的,是否有一种方法可以根据函数向量中的条目以有效的方式分配 scipy 中的最大内部子步骤数?我知道通过使用 IF 语句,我可能能够更改允许的最大步数,但我担心这会花费更多的计算时间,而这正是我想要减少的时间。我的代码如下所示:

def L_total(self, r, d, u):
    tem = self.T(u)
    condlist = [numpy.log10(tem) <= 2, numpy.log10(tem) >= 2]
    choicelist = [self.L1(r, d, tem), self.L2(r, tem)]
    return numpy.select(condlist, choicelist) #This is the returned value for the scipy integration, i.e. the vector I want to integrate

def integrate_function(self, i_0, time_final, r, d):
    def f(i, t):
        return - self.L_total(r, d, i)
    time = numpy.linspace(0., time_final, 2)
    result = odeint(f, i_0, time)
    return result[-1]

最后一个函数工作正常一段时间,直到变量 tem 的值增加,然后我收到一条消息,提示“此调用完成了多余的工作”,建议是增加允许的时间步数:

 lsoda--  at current t (=r1), mxstep (=i1) steps   ^@^@
   taken on this call before reaching tout     ^@^@
  in above message,  i1 =       500
  in above message,  r1 =  0.3319309749049D+03

此调用完成了过多的工作(可能是错误的 Dfun 类型)

增加参数 mxstep 的数量听起来像是解决方案,但事实上只要 log(tem)< 2 the integration is easy and the number of internal timesteps can be small, I don't want to waste time on this easy integration, the idea is to only increase the mxstep value for certain values of the vector. A way to do it is:

def integrate_function(self, i_0, time_final, r, d, tem):
    def f(i, t):
        return - self.L_total(r, d, i)
    time = numpy.linspace(0., time_final, 2)
    if numpy.log10(tem)<=2:
        result = odeint(f, i_0, time, mxstep=10) 
    else:
        result = odeint(f, i_0, time, mxstep=1000)
    return result[-1]

但是向量函数的长度非常大,因此它会消耗大量的计算时间,因为我必须在另一个循环内执行此循环。我需要的是效率,因为我的代码已经花费了很多时间。

python-2.7 numpy scipy odeint
1个回答
1
投票

odeint
自动选择的子时间步对于系统中的所有方程都是相同的。这是因为,通常情况下,在求解 ODE 系统时,无法单独处理各个分量:必须在同一时间点知道所有分量,才能找到当时的导数。

对于“非耦合系统”,其中方程彼此无关,上述对时间步长可能造成不必要的约束。在这种情况下,在循环中求解各个方程实际上可能比将它们作为一个系统进行处理更快。

© www.soinside.com 2019 - 2024. All rights reserved.