Ale*_*ary 5 python scipy odeint
编辑:这个问题是由于一个错误引起的,已在 Scipy 0.15 中修复
当我开发和测试代码时,我可能会犯一个简单的错误,例如 NameError。当我使用 scipy.integrate.odeint 时,odeint 将打印错误消息,但会继续集成我请求的多个时间步,因此我收到许多相同的错误消息。我认为它具有这种行为,以便在发生算术错误(例如除以零)时它可以继续进行,但这对于编程错误来说是无益的行为。
有没有办法让 scipy 在第一条错误消息后停止?如果我能让它因错误而不是算术异常而停止,那就最好了。
odeint
是 C 代码的 Python 包装器,它调用 LSODA(Fortran 子例程),后者调用 C 代码来调用代表 dy/dt 的 Python 回调。LSODA 不会传递 Python 异常,并且从 C 代码的一位跳转到另一位实现起来很麻烦。
我找到了一个令人满意的解决方案,只需使用而ode
不是odeint
. 我发现ode
开始使用比较复杂,但是当 Python 中抛出异常时,它的行为方式是正确的。下面的函数fake_odeint()
是创建一个足以满足我的目的的函数的开始odeint
,以便我可以在现有代码中交换它。ode
使用而不是使用 LSODA 的缺点odeint
是每个时间步调用一次;这个调用在 C 中发生,odeint
在 Python 中发生得更慢ode
。
import numpy as np
from scipy.integrate import ode
def fake_odeint(func, y0, t, Dfun=None):
ig = ode(func, Dfun)
ig.set_integrator('lsoda',
method='adams')
ig.set_initial_value(y0, t=0.)
y = []
for tt in t:
y.append(ig.integrate(tt))
return np.array(y)
Run Code Online (Sandbox Code Playgroud)
我研究了如何使用 Fortran、C 和 Python 代码在这个 SO 问题odeint
中与 LSODA 进行通信的机制。