在出现第一个错误时停止 scipy odeint

Ale*_*ary 5 python scipy odeint

编辑:这个问题是由于一个错误引起的,已在 Scipy 0.15 中修复

当我开发和测试代码时,我可能会犯一个简单的错误,例如 NameError。当我使用 scipy.integrate.odeint 时,odeint 将打印错误消息,但会继续集成我请求的多个时间步,因此我收到许多相同的错误消息。我认为它具有这种行为,以便在发生算术错误(例如除以零)时它可以继续进行,但这对于编程错误来说是无益的行为。

有没有办法让 scipy 在第一条错误消息后停止?如果我能让它因错误而不是算术异常而停止,那就最好了。

Ale*_*ary 2

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 进行通信的机制。