Skip to content

Commit

Permalink
changed name to numbalsoda
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicholaswogan committed Feb 24, 2022
1 parent a389ae8 commit edb2192
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 71 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ add_library(lsoda SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/LSODA.cpp
set_target_properties(lsoda PROPERTIES PREFIX "lib")

if (SKBUILD)
install(TARGETS lsoda DESTINATION NumbaLSODA)
install(TARGETS lsoda DESTINATION numbalsoda)
else()
install(TARGETS lsoda DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/NumbaLSODA/)
install(TARGETS lsoda DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/numbalsoda/)
endif()
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# NumbaLSODA
# numbalsoda

`NumbaLSODA` is a python wrapper to the LSODA method in [ODEPACK](https://computing.llnl.gov/projects/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
`numbalsoda` is a python wrapper to the LSODA method in [ODEPACK](https://computing.llnl.gov/projects/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](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html)), 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).
This package is very similar to `scipy.integrate.solve_ivp` ([see here](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html)), 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:
`numbalsoda` should work on Windows, Linux, or MacOS. Install with pip:

```
python -m pip install NumbaLSODA
python -m pip install numbalsoda
```

## Basic usage

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

Expand Down
34 changes: 17 additions & 17 deletions benchmark/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Benchmarks

This is a comparison `NumbaLSODA`, `scipy.integrate.solve_ivp` and Julia's DifferentialEquations.jl. I look at one non-stiff problem (lorenz) and one stiff problem (rober). Below are the results.
This is a comparison `numbalsoda`, `scipy.integrate.solve_ivp` and Julia's DifferentialEquations.jl. I look at one non-stiff problem (lorenz) and one stiff problem (rober). Below are the results.

For larger problems (more ODEs), there will be smaller differences between NumbaLSODA and Scipy because Scipy will spend relatively less time doing operations in python (which is slow), and will spend more time in optimized machine code (which is fast).
For larger problems (more ODEs), there will be smaller differences between numbalsoda and Scipy because Scipy will spend relatively less time doing operations in python (which is slow), and will spend more time in optimized machine code (which is fast).

Also, Scipy might be faster than NumbaLSODA for stiff problems with > ~500 ODEs because Scipy uses highly optimized BLAS and LAPACK routines for matrix inversion (intel MKL or OpenBLAS), while NumbaLSODA uses home-brewed and less optimized BLAS routines.
Also, Scipy might be faster than numbalsoda for stiff problems with > ~500 ODEs because Scipy uses highly optimized BLAS and LAPACK routines for matrix inversion (intel MKL or OpenBLAS), while numbalsoda uses home-brewed and less optimized BLAS routines.

## Non-stiff (Lorenz)

| | Time | Relative to NumbaLSODA |
| | Time | Relative to numbalsoda |
|--------------|-------------|------------------------|
| NumbaLSODA | 3.421 ms | 1x |
| numbalsoda | 3.421 ms | 1x |
| Scipy LSODA | 595.029 ms | 174x |
| Scipy RK45 | 1744.073 ms | 510x |
| Scipy DOP853 | 1052.442 ms | 308x |
Expand All @@ -19,15 +19,15 @@ Also, Scipy might be faster than NumbaLSODA for stiff problems with > ~500 ODEs

## Stiff (Rober)

| | Time | Relative to NumbaLSODA |
|--------------------|------------|------------------------|
| NumbaLSODA | 0.221 ms | 1x |
| Scipy LSODA | 26.483 ms | 120x |
| Scipy BDF | 158.911 ms | 719x |
| Scipy Radau | 167.977 ms | 760x |
| Julia TRBDF2 | 5.765 ms | 26.08x |
| Julia CVODE_BDF | 1.115 ms | 5.045x |
| Julia LSODA | 0.264 ms | 1.194x |
| Julia Rodas5 | 0.762 ms | 3.45x |
| Julia Rodas5 + StaticArrays | 0.173 ms | 0.78x |
| Julia Rodas5 + StaticArrays + Analytical Jacobian | 0.113 ms | 0.511x |
| | Time | Relative to numbalsoda |
| ------------------------------------------------- | ---------- | ---------------------- |
| numbalsoda | 0.221 ms | 1x |
| Scipy LSODA | 26.483 ms | 120x |
| Scipy BDF | 158.911 ms | 719x |
| Scipy Radau | 167.977 ms | 760x |
| Julia TRBDF2 | 5.765 ms | 26.08x |
| Julia CVODE_BDF | 1.115 ms | 5.045x |
| Julia LSODA | 0.264 ms | 1.194x |
| Julia Rodas5 | 0.762 ms | 3.45x |
| Julia Rodas5 + StaticArrays | 0.173 ms | 0.78x |
| Julia Rodas5 + StaticArrays + Analytical Jacobian | 0.113 ms | 0.511x |
3 changes: 1 addition & 2 deletions benchmark/benchmark.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

using OrdinaryDiffEq, StaticArrays, BenchmarkTools, Sundials, LSODA, ModelingToolkit
using OrdinaryDiffEq, StaticArrays, BenchmarkTools, Sundials, ModelingToolkit

println("Lorenz")
# Lorenz
Expand Down Expand Up @@ -35,7 +35,6 @@ prob = ODEProblem(rober,[1.0,0.0,0.0],(0.0,1e5),[0.04,3e7,1e4])
@btime solve(prob,Rodas5(),reltol=1.0e-8,abstol=1.0e-8, saveat = 1000) # 761.578 μs (633 allocations: 53.05 KiB)
@btime solve(prob,TRBDF2(),reltol=1.0e-8,abstol=1.0e-8, saveat = 1000) # 5.765 ms (11415 allocations: 524.14 KiB)
@btime solve(prob,CVODE_BDF(),reltol=1.0e-8,abstol=1.0e-8, saveat = 1000) # 1.115 ms (6954 allocations: 295.83 KiB)
@btime solve(prob,lsoda(),reltol=1.0e-8,abstol=1.0e-8, saveat = 1000) # 263.684 μs (2169 allocations: 185.09 KiB)

# rober
function rober_static(u,p,t)
Expand Down
6 changes: 3 additions & 3 deletions benchmark/benchmark_lorenz.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import numpy as np
from NumbaLSODA import lsoda_sig, lsoda
from numbalsoda import lsoda_sig, lsoda
from scipy.integrate import solve_ivp
import timeit
import numba as nb

# NumbaLSODA
# numbalsoda
@nb.cfunc(lsoda_sig,boundscheck=False)
def f_nb(t, u_, du_, p_):
u = nb.carray(u_, (3,))
Expand Down Expand Up @@ -56,7 +56,7 @@ def time_sp_DOP853():
t_sp_LSODA = timeit.Timer(time_sp_LSODA).timeit(number=iters)/iters*1e3
t_sp_RK45 = timeit.Timer(time_sp_RK45).timeit(number=iters)/iters*1e3
t_sp_DOP853 = timeit.Timer(time_sp_DOP853).timeit(number=iters)/iters*1e3
print("NumbaLSODA time =",'%.3f'%t_nb,'ms') # 3.421 ms
print("numbalsoda time =",'%.3f'%t_nb,'ms') # 3.421 ms
print("Scipy LSODA time =",'%.3f'%t_sp_LSODA,'ms') # 595.029 ms
print("Scipy RK45 time =",'%.3f'%t_sp_RK45,'ms') # 1744.073 ms
print("Scipy DOP853 time =",'%.3f'%t_sp_DOP853,'ms') # 1052.442 ms
Expand Down
6 changes: 3 additions & 3 deletions benchmark/benchmark_robber.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from NumbaLSODA import lsoda_sig, lsoda
from numbalsoda import lsoda_sig, lsoda
import numba as nb
import numpy as np
from scipy.integrate import solve_ivp
Expand Down Expand Up @@ -36,7 +36,7 @@ def f_sp(t, u, p):
usol_nb, success = lsoda(funcptr, u0, t_eval, args, rtol=rtol, atol=atol)

if not np.all(np.isclose(usol_sp.y.T,usol_nb)):
print("Scipy and NumbaLSODA solutions DO NOT match!!!\n")
print("Scipy and numbalsoda solutions DO NOT match!!!\n")

@nb.njit(boundscheck=False)
def time_nb():
Expand All @@ -62,7 +62,7 @@ def time_sp_Radau():
t_sp_BDF = timeit.Timer(time_sp_BDF).timeit(number=iters)/iters*1e3
t_sp_Radau = timeit.Timer(time_sp_Radau).timeit(number=iters)/iters*1e3

print("NumbaLSODA time =",'%.3f'%t_nb,'ms') # 0.221 ms
print("numbalsoda time =",'%.3f'%t_nb,'ms') # 0.221 ms
print("Scipy LSODA time =",'%.3f'%t_sp_LSODA,'ms') # 26.483 ms
print("Scipy BDF time =",'%.3f'%t_sp_BDF,'ms') # 158.911 ms
print("Scipy Radau time =",'%.3f'%t_sp_Radau,'ms') # 167.977 ms
53 changes: 26 additions & 27 deletions comparison2scipy.ipynb

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions compile.sh

This file was deleted.

8 changes: 4 additions & 4 deletions passing_data_to_rhs_function.ipynb

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
long_description = f.read()

setup(
name="NumbaLSODA",
packages=['NumbaLSODA'],
version='0.1.7',
name="numbalsoda",
packages=['numbalsoda'],
version='0.2.0',
license='MIT',
install_requires=['numpy','numba'],
author = 'Nicholas Wogan',
Expand All @@ -18,6 +18,6 @@
long_description=long_description,
long_description_content_type='text/markdown',
python_requires='>3.6',
url = "https://github.com/Nicholaswogan/NumbaLSODA",
url = "https://github.com/Nicholaswogan/numbalsoda",
cmake_args=['-DSKBUILD=ON']
)
2 changes: 1 addition & 1 deletion tests/test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from NumbaLSODA import lsoda_sig, lsoda
from numbalsoda import lsoda_sig, lsoda
from numba import njit, cfunc
import numpy as np

Expand Down

0 comments on commit edb2192

Please sign in to comment.