Skip to main content

Python wrapper of LSODA (solving ODEs) which can be called from within numba functions.

Project description

numbalsoda

numbalsoda is a python wrapper to the LSODA method in ODEPACK, which is for solving ordinary differential equation initial value problems. LSODA was originally written in Fortran. numbalsoda is a wrapper to a C++ re-write of the original code: https://github.com/dilawar/libsoda

This package is very similar to scipy.integrate.solve_ivp (see here), when you set method = 'LSODA'. But, scipy.integrate.solve_ivp invokes the python interpreter every time step which can be slow. Also, scipy.integrate.solve_ivp can not be used within numba jit-compiled python functions. In contrast, numbalsoda never invokes the python interpreter during integration and can be used within a numba compiled function which makes numbalsoda a lot faster than scipy for most problems (see benchmark folder).

Installation

numbalsoda should work on Windows, Linux, or MacOS. Install with pip:

python -m pip install numbalsoda

Basic usage

from numbalsoda import lsoda_sig, lsoda
from numba import njit, cfunc
import numpy as np

@cfunc(lsoda_sig)
def rhs(t, u, du, p):
    du[0] = u[0]-u[0]*u[1]
    du[1] = u[0]*u[1]-u[1]*p[0]

funcptr = rhs.address # address to ODE function
u0 = np.array([5.,0.8]) # Initial conditions
data = np.array([1.0]) # data you want to pass to rhs (data == p in the rhs).
t_eval = np.linspace(0.0,50.0,1000) # times to evaluate solution

usol, success = lsoda(funcptr, u0, t_eval, data = data)
# usol = solution
# success = True/False

The variables u, du and p in the rhs function are pointers to an array of floats. Therefore, operations like np.sum(u) or len(u) will not work. However, you can use the function nb.carray() to make a numpy array out of the pointers. For example:

import numba as nb

@cfunc(lsoda_sig)
def rhs(t, u, du, p):
    u_ = nb.carray(u, (2,))
    p_ = nb.carray(p, (1,))
    # ... rest of rhs goes here using u_ and p_

Above, u_ and p_ are numpy arrays build out of u and p, and so functions like np.sum(u_) will work.

Also, note lsoda can be called within a jit-compiled numba function (see below). This makes it much faster than scipy if a program involves many integrations in a row.

@njit
def test():
    usol, success = lsoda(funcptr, u0, t_eval, data = data)
    return usol
usol = test() # this works!

@njit
def test_sp():
    sol = solve_ivp(f_scipy, t_span, u0, t_eval = t_eval, method='LSODA')
    return sol
sol = test_sp() # this does not work :(

Passing data to the right-hand-side function

In the examples shown above, we passed a an single array of floats to the right-hand-side function:

# ...
data = np.array([1.0])
usol, success = lsoda(funcptr, u0, t_eval, data = data)

However, sometimes you might want to pass more data types than just floats. For example, you might want to pass several integers, an array of floats, and an array of integers. This is possible, but a little tricky. The notebook passing_data_to_rhs_function.ipynb gives an example that explains how.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

numbalsoda-0.2.1.tar.gz (111.6 kB view hashes)

Uploaded Source

Built Distributions

numbalsoda-0.2.1-pp37-pypy37_pp73-win_amd64.whl (55.7 kB view hashes)

Uploaded PyPy Windows x86-64

numbalsoda-0.2.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (34.8 kB view hashes)

Uploaded PyPy manylinux: glibc 2.12+ x86-64

numbalsoda-0.2.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl (30.9 kB view hashes)

Uploaded PyPy manylinux: glibc 2.12+ i686

numbalsoda-0.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (28.9 kB view hashes)

Uploaded PyPy macOS 10.9+ x86-64

numbalsoda-0.2.1-cp310-cp310-win_amd64.whl (55.7 kB view hashes)

Uploaded CPython 3.10 Windows x86-64

numbalsoda-0.2.1-cp310-cp310-win32.whl (50.2 kB view hashes)

Uploaded CPython 3.10 Windows x86

numbalsoda-0.2.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (34.8 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.12+ x86-64

numbalsoda-0.2.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl (30.9 kB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.12+ i686

numbalsoda-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl (28.9 kB view hashes)

Uploaded CPython 3.10 macOS 10.9+ x86-64

numbalsoda-0.2.1-cp39-cp39-win_amd64.whl (55.7 kB view hashes)

Uploaded CPython 3.9 Windows x86-64

numbalsoda-0.2.1-cp39-cp39-win32.whl (50.2 kB view hashes)

Uploaded CPython 3.9 Windows x86

numbalsoda-0.2.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (34.8 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

numbalsoda-0.2.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl (30.9 kB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.12+ i686

numbalsoda-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl (28.9 kB view hashes)

Uploaded CPython 3.9 macOS 10.9+ x86-64

numbalsoda-0.2.1-cp38-cp38-win_amd64.whl (55.7 kB view hashes)

Uploaded CPython 3.8 Windows x86-64

numbalsoda-0.2.1-cp38-cp38-win32.whl (50.2 kB view hashes)

Uploaded CPython 3.8 Windows x86

numbalsoda-0.2.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (34.8 kB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

numbalsoda-0.2.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl (30.9 kB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.12+ i686

numbalsoda-0.2.1-cp38-cp38-macosx_10_9_x86_64.whl (28.9 kB view hashes)

Uploaded CPython 3.8 macOS 10.9+ x86-64

numbalsoda-0.2.1-cp37-cp37m-win_amd64.whl (55.7 kB view hashes)

Uploaded CPython 3.7m Windows x86-64

numbalsoda-0.2.1-cp37-cp37m-win32.whl (50.2 kB view hashes)

Uploaded CPython 3.7m Windows x86

numbalsoda-0.2.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (34.8 kB view hashes)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64

numbalsoda-0.2.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl (30.9 kB view hashes)

Uploaded CPython 3.7m manylinux: glibc 2.12+ i686

numbalsoda-0.2.1-cp37-cp37m-macosx_10_9_x86_64.whl (28.9 kB view hashes)

Uploaded CPython 3.7m macOS 10.9+ x86-64

numbalsoda-0.2.1-cp36-cp36m-win_amd64.whl (55.7 kB view hashes)

Uploaded CPython 3.6m Windows x86-64

numbalsoda-0.2.1-cp36-cp36m-win32.whl (50.2 kB view hashes)

Uploaded CPython 3.6m Windows x86

numbalsoda-0.2.1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (34.8 kB view hashes)

Uploaded CPython 3.6m manylinux: glibc 2.12+ x86-64

numbalsoda-0.2.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl (30.9 kB view hashes)

Uploaded CPython 3.6m manylinux: glibc 2.12+ i686

numbalsoda-0.2.1-cp36-cp36m-macosx_10_9_x86_64.whl (28.9 kB view hashes)

Uploaded CPython 3.6m macOS 10.9+ x86-64

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page