odeint
是C代码的Python包装,它调用调用C代码来调用我的Python回调代表dy/dt的LSODA(Fortran子例程)。 LSODA不会传递Python异常,并且从C代码的一位跳到另一位很难实现。
我在使用ode
而不是odeint
找到了令人满意的解决方案。我发现ode
开始使用起来比较复杂,但在Python中抛出异常时,它的行为是正确的。下面的fake_odeint()
函数是一个开始于使我的目的足够好的odeint
函数,以便我可以在我现有的代码中进行交换。使用ode
而不是odeint
的缺点是LSODA每个时步调用一次;这个调用在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)
我看着的的Fortran,C,和Python代码如何被用来允许odeint
在this SO question与LSODA通信的机制。
此错误已被报告https://github.com/scipy/scipy/issues/2570 – astrojuanlu 2013-06-24 10:09:48
这在SciPy 0.15 https://github.com/scipy/scipy/pull/4052中已修复。 – Ben 2015-02-10 11:18:23