scipy odeint:即使使用可解析的 ODE,在此调用上完成的额外工作也取决于初始值

计算科学 Python scipy
2021-12-08 14:19:34

我正在尝试使用 scipy odeint 求解以下形式的微分方程:dx/dt = funct(x)。

然而,对于一些初始值,我得到一个“ODEintWarning: E​​xcess work done on this call”,即使 ODE 本身似乎是可解析的。为什么数值 ODE 求解器会给我一个警告,我怎样才能让它工作而不是跳到 x > 3e^7?

这是一个最小(非)工作示例:

x0 =0.49 # works, but changing to 0.51 gives the ODEint warning
t = np.linspace(0,10,100)
def funct(x,t):
    return 2*x**2-x
x, out = integrate.odeint(funct, x0, t, full_output = 1)
plt.plot(t,x)

我不太擅长数学,但我认为分析答案应该是:x = 1/(2 + C * exp(t)) 其中 C 是任何常数。

如果是这样,我认为使用 x0=0.51 的初始值也应该是数值可解的,因为 C 存在(C = -0.04)。

我能找到的最接近的问题是: scipy odeint:在此调用上完成的工作过多并且对初始值非常敏感 但是,上一个问题中的 ODE 在分析上会爆炸,而我的则不会。

编辑:我的真实函数和 x 是关于网络的向量和矩阵,而不是解析可解的。

2个回答

如果我没记错的话,对于,您的示例 ODE 会产生,因此会增加,它的时间导数也会增加。因此,解决方案发散,甚至比一段时间后的简单指数更快(当时)。如果从开始,则解是一个常数。对于,解收敛到 0。x>0.5dx/dt>0xx2xx=0.5x<0.5

在发散的情况下,用于动态调整时间步长的误差估计将需要越来越小的时间步长,并且在某一点低于,或者至少使得在机器精度。然后,求解器假定尝试进行集成没有意义并通知您。这种行为是绝对正常的。1015t+dt=t

为了更准确地说明初始值的影响,ODE是伯努利。得到 分母的极点。对于,这给出了这个奇点为积分器提供了一个不可逾越的障碍。可能会有更多信息错误消息,但只是报告步长控制器的故障。x˙=2x2xu=x1

u˙=x2x˙=u2u=2+(u02)etx=x02x0+(12x0)et.
x0>12tpole=ln(x0x012)x0=0.51tpole=ln(51)=3.931825...odeint