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.25
和t0=0
,这和y(t)=t/2+1/4
是一样的。在这种情况下 y(1)=0.75
.
solve_ivp
与odeint
的比较
第一from scipy.integrate import solve_ivp, odeint
.
通过写入 odeint(lambda y,t: 2*y-t,[0.25],[0,1])
我们得到预期的结果 y(0)=0.25
和 y(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.25
和 y(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.25
和 y(1)=0.82772876
.
并且如果您在更长的时间跨度内尝试此操作,对于此特定示例,solve_ivp
的结果只会变得更糟。
我是不是漏掉了什么?
我要睡觉了...
根据 odeint documentation,该函数必须是 func(y, t)
类型(尽管如果您指定它它确实接受 f(t,y)
)。
并且根据 solve_ivp documentation,函数的类型必须是 func(t, y)
。
示例 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.25
和t0=0
,这和y(t)=t/2+1/4
是一样的。在这种情况下 y(1)=0.75
.
solve_ivp
与odeint
的比较
第一from scipy.integrate import solve_ivp, odeint
.
通过写入 odeint(lambda y,t: 2*y-t,[0.25],[0,1])
我们得到预期的结果 y(0)=0.25
和 y(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.25
和 y(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.25
和 y(1)=0.82772876
.
并且如果您在更长的时间跨度内尝试此操作,对于此特定示例,solve_ivp
的结果只会变得更糟。
我是不是漏掉了什么?
我要睡觉了...
根据 odeint documentation,该函数必须是 func(y, t)
类型(尽管如果您指定它它确实接受 f(t,y)
)。
并且根据 solve_ivp documentation,函数的类型必须是 func(t, y)
。