Scipy odeint的时间值为负

时间:2019-06-17 23:13:05

标签: python scipy odeint

我正在尝试使用scipy.integrate.odeint从最后一次的边界条件解出ODE系统,并一直努力到最初的时间(如此处所述:Backward integration in time using scipy odeint)。

但是,odeint会迭代为负的时间值-在我正在寻找的实际解决方案范围之外-这会导致错误,因为我的ODE依赖于时间的平方根,并且我的函数返回一个复数值而不是实数。

以下是重现此问题的示例:

    import numpy as np 
    from scipy.integrate import odeint
    tmax = 4e4
    tmin = 1
    t = np.linspace(tmax,tmin,1e3)
    param0 = [1] #value of x at tmax

    def func(param,t):
        x = param[0]
        dxdt = 1e-10/np.sqrt(t)
        print(t) #show what values of t are tried by odeint
        return dxdt

    res = odeint(func,param0,t)

很快print(t)显示负值,resnan填充。

是否有一种方法可以防止odeint变为负值?为什么它尝试输入数组t之外的值?

对于我的实际代码,我发现了一些避免nan结果的方法,例如在函数中添加if t<0: t=0(在这里不起作用)或施加很小的最大时间步长( hmax<tmin),但这会使计算时间更长。

请注意,Scipy odeint Non-negative solution是相关的,但我的问题略有不同:我并不担心否定的解决方法x,而不会担心否定的论点t

1 个答案:

答案 0 :(得分:0)

我建议使用solve_ivp而不是旧的odeint。请注意,solve_ivp期望f(t,y)代替f(y,t)作为您的颂歌的右侧:

import numpy as np 
from scipy.integrate import solve_ivp
tmax = int(4e4)
tmin = 1
t = np.linspace(tmax, tmin, int(1e3))
param0 = [1] #value of x at tmax

def func(t, param):
    dxdt = 1e-10/np.sqrt(t)
    return dxdt

res = solve_ivp(func, y0=param0, t_span=[tmax, tmin], t_eval=t)

其中t_eval=t确保解决方案将在时间点t处存储。否则,求解器将选择时间点。