Question

Edit: This problem is due to a bug, fixed in Scipy 0.15

As I'm developing and testing code, I may make a simple error, like a NameError. When I use scipy.integrate.odeint, odeint will print the error message, but keep integrating for however many timesteps I request, so I get many identical error messages. I presume that it has this behavior so that it can proceed when arithmetic errors occur (eg, divide by zero), but this is unhelpful behavior for programming errors.

Is there a way to get scipy to stop after the first error message? It would be best if I could get it to stop for bugs but not for arithmetic exceptions.

Was it helpful?

Solution

odeint is a Python wrapper for C code which calls LSODA (a Fortran subroutine) which calls C code to call my Python callback representing dy/dt. LSODA doesn't pass the Python exception, and jumping from one bit of the C code to another is troublesome to implement.

I have found a satisfactory solution in just using ode instead of odeint. I find ode to be more complicated to get started using, but it behaves the right way when an exception is thrown in Python. The fake_odeint() function below is a start at making a function that works like odeint well enough for my purposes so that I can swap it out in my existing code. The downside to using ode instead of odeint is that LSODA gets called once per timestep; this call happens in C with odeint and more slowly in Python in 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)

I looked into the mechanics of how Fortran, C, and Python code are used to allow odeint to communicate with LSODA in this SO question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top