Scipy 集成: solve_ivp "always worse" 比 odeint 好吗?

Scipy integrate: is solve_ivp "always worse" than odeint?

示例 ODE 的解析解

我通过解决以下初始值问题来测试这些方法之间的差异:

y'=2*y-t

您可以通过考虑 y(t) 是齐次解 y_h(t)=c1*exp(2t) 和特定解 y_p(t)=t/2+1/4 的线性组合来解析求解此问题。通过代入 y(t0)=y0 找到常量 c1。那么解析解为:

y(t)=(y0-t0/2-1/4)*exp(2*(t-t0))+t/2+1/4

注意如果y0=0.25t0=0,这和y(t)=t/2+1/4是一样的。在这种情况下 y(1)=0.75.


solve_ivpodeint

的比较

第一from scipy.integrate import solve_ivp, odeint.

通过写入 odeint(lambda y,t: 2*y-t,[0.25],[0,1]) 我们得到预期的结果 y(0)=0.25y(1)=0.75.

但是,通过写入 solve_ivp(lambda y,t: 2*y-t,t_span=[0,1],y0=[0.25],t_eval=[0,1]) 我们得到结果 y(0)=0.25y(1)=0.82775742

this question, solve_ivp should have the 'LSODA' method and have its tolerances adjusted in order to fairly compare it to odeint. By reading the scipy odeint documentation 中所述,我们看到公差在 1.49e-8 左右。

solve_ivp(lambda y,t: 2*y-t,t_span=[0,1],y0=[0.25],t_eval=[0,1],method='LSODA',atol=1.49e-8,rtol=1.49e-8) 仍然产生 y(0)=0.25y(1)=0.82772876.

并且如果您在更长的时间跨度内尝试此操作,对于此特定示例,solve_ivp 的结果只会变得更糟。


我是不是漏掉了什么?

我要睡觉了...

根据 odeint documentation,该函数必须是 func(y, t) 类型(尽管如果您指定它它确实接受 f(t,y))。

并且根据 solve_ivp documentation,函数的类型必须是 func(t, y)