2013-05-07 76 views
4

编辑:这个问题是由于一个bug,修复SciPy的0.15暂停SciPy的odeint

因为我开发和测试代码,我可以做一个简单的错误,就像一个NameError。当我使用scipy.integrate.odeint时,odeint将打印错误消息,但是保持整合,无论我请求多少次时间步,因此我得到许多相同的错误消息。我认为它具有这种行为,以便在算术错误发生时(例如,除以零)可以继续进行,但这对编程错误没有帮助。

有没有办法让scipy在第一个错误信息后停止?如果我能够阻止错误而不是算术例外,那将是最好的。

+2

此错误已被报告https://github.com/scipy/scipy/issues/2570 – astrojuanlu 2013-06-24 10:09:48

+2

这在SciPy 0.15 https://github.com/scipy/scipy/pull/4052中已修复。 – Ben 2015-02-10 11:18:23

回答

2

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代码如何被用来允许odeintthis SO question与LSODA通信的机制。

+0

我想我正在使用你的'fake_odeint'函数,直到bug解决! – astrojuanlu 2013-07-01 21:50:37