Runge-Kutta ODE Integrator Implemented in Cython and Numba.
Project description
CyRK
Runge-Kutta ODE Integrator Implemented in Cython and Numba
CyRK provides fast integration tools to solve systems of ODEs using an adaptive time stepping scheme. CyRK can accept differential equation functions that are written in pure Python or njited numba, speeding up development time. The purpose of this package is to provide some functionality of scipy's solve_ivp with improved performance.
Currently, CyRK's numba (njit-safe) implementation is 10-100x faster than scipy's solve_ivp function. The cython implementation is 5-30x faster. The cython function is also largely pre-compiled which avoids most of the initial performance hit found with using the numba version.
Installation
It is recommended you use an Anaconda environment. CyRK has been tested on Python 3.8--3.10
To install simply open a terminal and call:
pip install CyRK
If not installing from a wheel, CyRK will attempt to install Cython
and Numpy
in order to compile the cython code.
After the files have been compiled, cython will be uninstalled and CyRK's runtime dependencies
(see the pyproject.toml file for the latest list) will be installed instead.
A new installation of CyRK can be tested quickly by running the following from a python console.
from CyRK import test_cyrk, test_nbrk
test_cyrk()
# You will hopefully see the message "CyRK's cyrk_ode was tested successfully."
test_nbrk()
# You will hopefully see the message "CyRK's nbrk_ode was tested successfully."
Installation Troubleshooting
Please report installation issues. We will work on a fix and/or add workaround information here.
- If you see a "Can not load module: CyRK.cy" or similar error then the cython extensions likely did not compile during installation. Try running
pip install CyRK --no-binary="CyRK"
to force python to recompile the cython extensions locally (rather than via a prebuilt wheel). - On MacOS: If you run into problems installing CyRK then reinstall using the verbose flag (
pip install -v .
) to look at the installation log. If you see an error that looks like "clang: error: unsupported option '-fopenmp'" then you may have a problem with yourllvm
orlibomp
libraries. It is recommended that you install CyRK in an anaconda environment with the following packagesconda install numpy scipy cython llvm-openmp
. See more discussion here and the steps taken here.
Development and Testing Dependencies
If you intend to work on CyRK's code base you will want to install the following dependencies in order to run CyRK's test suite.
conda install pytest scipy matplotlib jupyter
conda install
can be replaced with pip install
if you prefer.
Using CyRK
CyRK's API is similar to SciPy's solve_ivp function. A differential equation can be defined in python such as:
import numpy as np
from numba import njit
# For even more speed up you can use numba's njit to compile the diffeq
@njit
def diffeq_nb(t, y):
dy = np.empty_like(y)
dy[0] = (1. - 0.01 * y[1]) * y[0]
dy[1] = (0.02 * y[0] - 1.) * y[1]
return dy
initial_conds = np.asarray((20., 20.), dtype=np.complex128)
time_span = (0., 50.)
rtol = 1.0e-7
atol = 1.0e-8
The ODE can then be solved using the numba function by calling CyRK's nbrk_ode
:
from CyRK import nbrk_ode
time_domain, y_results, success, message = \
nbrk_ode(diffeq_nb, time_span, initial_conds, rk_method=1, rtol=rtol, atol=atol)
To call the cython version of the integrator you need to slightly edit the differential equation so that it does not return the derivative. Instead, the output is passed as an input argument (a np.ndarray) to the function.
@njit
def diffeq_cy(t, y, dy):
dy[0] = (1. - 0.01 * y[1]) * y[0]
dy[1] = (0.02 * y[0] - 1.) * y[1]
Alternatively, you can use CyRK's conversion helper functions to automatically convert between numba/scipy and cyrk function calls.
from CyRK import nb2cy, cy2nb
@njit
def diffeq_nb(t, y):
dy = np.empty_like(y)
dy[0] = (1. - 0.01 * y[1]) * y[0]
dy[1] = (0.02 * y[0] - 1.) * y[1]
return dy
diffeq_cy = nb2cy(diffeq_nb, use_njit=True)
diffeq_nb2 = cy2nb(diffeq_cy, use_njit=True)
You can then call the ODE solver in a similar fashion as the numba version.
from CyRK import cyrk_ode
time_domain, y_results, success, message = \
cyrk_ode(diffeq_cy, time_span, initial_conds, rk_method=1, rtol=rtol, atol=atol)
Optional Inputs
Both the numba and cython versions of the ODE solver have the following optional inputs:
rtol
: Relative Tolerance (default is 1.0e-6).atol
: Absolute Tolerance (default is 1.0e-8).max_step
: Maximum step size (default is +infinity).first_step
: Initial step size (default is 0).- If 0, then the solver will try to determine an ideal value.
args
: Python tuple of additional arguments passed to thediffeq
.t_eval
: Both solvers uses an adaptive time stepping protocol based on the recent error at each step. This results in a final non-uniform time domain of variable size. If the user would like the results at specific time steps then they can provide a np.ndarray array at the desired steps tot_eval
. The solver will then interpolate the results to fit this array.rk_method
: Runge-Kutta method (default is 1; all of these methods are based off of SciPy implementations):0
- "RK23" Explicit Runge-Kutta method of order 3(2).1
- "RK45" Explicit Runge-Kutta method of order 5(4).2
- "DOP853" Explicit Runge-Kutta method of order 8.
capture_extra
andinterpolate_extra
: CyRK has the capability of capturing additional parameters during integration. Please seeDocumentation\Extra Output.md
for more details.
Limitations and Known Issues
- Issue 1: Absolute tolerance can only be passed as a single value (same for all y's).
Citing CyRK
It is great to see CyRK used in other software or in scientific studies. We ask that you cite back to CyRK's GitHub website so interested parties can learn about this package.
Renaud, Joe P. (2022). CyRK - ODE Integrator Implemented in Cython and Numba. Zenodo. https://doi.org/10.5281/zenodo.7093266
In addition to citing CyRK, please consider citing SciPy and its references for the specific Runge-Kutta model that was used in your work. CyRK is largely an adaptation of SciPy's functionality. Find more details here.
Pauli Virtanen, Ralf Gommers, Travis E. Oliphant, Matt Haberland, Tyler Reddy, David Cournapeau, Evgeni Burovski, Pearu Peterson, Warren Weckesser, Jonathan Bright, Stéfan J. van der Walt, Matthew Brett, Joshua Wilson, K. Jarrod Millman, Nikolay Mayorov, Andrew R. J. Nelson, Eric Jones, Robert Kern, Eric Larson, CJ Carey, İlhan Polat, Yu Feng, Eric W. Moore, Jake VanderPlas, Denis Laxalde, Josef Perktold, Robert Cimrman, Ian Henriksen, E.A. Quintero, Charles R Harris, Anne M. Archibald, Antônio H. Ribeiro, Fabian Pedregosa, Paul van Mulbregt, and SciPy 1.0 Contributors. (2020) SciPy 1.0: Fundamental Algorithms for Scientific Computing in Python. Nature Methods, 17(3), 261-272.
Contribute to CyRK
Please look here for an up-to-date list of contributors to the CyRK package.
CyRK is open-source and is distributed under the Creative Commons Attribution-ShareAlike 4.0 International license.
You are welcome to fork this repository and make any edits with attribution back to this project (please see the
Citing CyRK
section).
- We encourage users to report bugs or feature requests using GitHub Issues.
- If you would like to contribute but don't know where to start, check out the good first issue tag on GitHub.
- Users are welcome to submit pull requests and should feel free to create them before the final code is completed so that feedback and suggestions can be given early on.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for CyRK-0.5.3-pp39-pypy39_pp73-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ea69d1cfc99d8cc50e3d6da9957a1de73da3e99861d891facc6136580fd0558d |
|
MD5 | 97501b2c58fd6fd3f5466c9ebb3412b1 |
|
BLAKE2b-256 | e9bbcc152e944b2d43efd530d69f645ca8512bcdfd314664f837568a1c2c97f6 |
Hashes for CyRK-0.5.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 686e95d1bb0962e181f55623e33ebafcfcf813d4bee4c1be252c63ae94170811 |
|
MD5 | fd5e3422e80a157f6b306c0a874ca58a |
|
BLAKE2b-256 | 4d31bec1b192e77f40c7c4f63602cfbe077ca835d977cca394777bf56885b6ed |
Hashes for CyRK-0.5.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c6f87438e64d68b74644c0f71762f271bc58c715d23a76cfdec05ebc2642389e |
|
MD5 | 9f88995c60d0b05b3f5dee6666634866 |
|
BLAKE2b-256 | dffdd65484ec26a5a0bd43eb55453e1002c9e401be56820468665540b873364a |
Hashes for CyRK-0.5.3-pp38-pypy38_pp73-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | abdee911d65202298482f239c43a6fa537bc76151d4302a417d4368ac1ad9bb5 |
|
MD5 | 7e6eceba7d3bd3eda4d1a01ee4376eec |
|
BLAKE2b-256 | c9d42d97972b8ec31bcc663c6e12d4d360735f2719893de8320114a6d0b8f6c9 |
Hashes for CyRK-0.5.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6f8df1fb4ccd8a8fb8ce4fe305df353d72fe96c73ac67fbcba9c6c6dd969c251 |
|
MD5 | c730a5fb697bf7bfa6a642d81addfdc3 |
|
BLAKE2b-256 | 4a9fe8f9b9d1554f61b62cb3502fb6b624b5ef8a32d42a2ac50a629ab37aee05 |
Hashes for CyRK-0.5.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fca98d01acb2ba19db0f1668a26ac087e101456935a14a25ef6d1f88fc148b5f |
|
MD5 | f7327ab63aca4f231e38292851be4602 |
|
BLAKE2b-256 | bc195cfa6784cc0687406f4ea9411a9c0b999be8c5a1e3b71e9ecdca9fde3158 |
Hashes for CyRK-0.5.3-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6bb84b748b2604c78331ce4dc4e038d563dbe54d1d7c8f55f7a634932763faab |
|
MD5 | 5cf3cf60c727a46c23c624f6087b87aa |
|
BLAKE2b-256 | e532035e6556c0c39bbe771aca3d44e3c57610dd7c282bc88d70c26e51ffa1a1 |
Hashes for CyRK-0.5.3-cp310-cp310-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eff58503010487a59450acece9f82d33a21e552356b1a19a600c37209799c75b |
|
MD5 | 4bf58a6f709cb6b7c99358978cb9b980 |
|
BLAKE2b-256 | 723aeae12f5049b9e63f8cdeecb5350a87d8d8427435fdf645d3428e931430e0 |
Hashes for CyRK-0.5.3-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a1ae01ef17aa298391cac09277f933e1d669b2a6705872bd466175fb9fd975ec |
|
MD5 | addb66de378dd44f197647880753e4e0 |
|
BLAKE2b-256 | 0d3444d8d3f4c1235e410cc8dfc9a4eb96a0d67a6983a3d6696ee5578622e2e5 |
Hashes for CyRK-0.5.3-cp310-cp310-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 74a63b28994e459239377e6116d48eb0633b23c7e134d711873881f07360e21a |
|
MD5 | e5692a4fa24aa2d9c506ec470ab9b4ac |
|
BLAKE2b-256 | 47e228484d8e4b4dd4ed946fb97a357db4760735cab42b7c5059884dbda534bb |
Hashes for CyRK-0.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a665d3f5e267811445c2f866361f1608b2c4a5d192d7270c9b9fb2e83fa45f42 |
|
MD5 | 0bae1a8a19f43d684196f82b7301111f |
|
BLAKE2b-256 | 8946cdfcbf047d7c3d76cde3c449856f3406f5217f4bb6e04e44dc8d77ded256 |
Hashes for CyRK-0.5.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b7166d8e4462d60b99225aa35cb54602e12ebf129ac58771abe1546425b39814 |
|
MD5 | 7fae60edf0186f5e6c56ff04f5b5feb6 |
|
BLAKE2b-256 | e4a363472fad291e7e14fa3b4d2b7836a19faa76a7ea50a2acc17365f32329b5 |
Hashes for CyRK-0.5.3-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 26bef995f03a428ebcc71d1f1f3cdaea168581e2b5532ab2fdb2dccade466477 |
|
MD5 | 61a42ec6b6cf96f55bd28d437e5e26d5 |
|
BLAKE2b-256 | 4883784498ba5a44c1a3090ca1fa80be026a56b04358cb0c3293f599c7bffdea |
Hashes for CyRK-0.5.3-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7e4a6a53385a245f0c18088f02c2d1256a8f0917a0a7af42a7988510080246a5 |
|
MD5 | c5fb3d18cc9a8d067ec09e989858225c |
|
BLAKE2b-256 | b800e3c7bdb24fc76984d4932cd66a3d9cc2e729110478a0ebb25075e292fb95 |
Hashes for CyRK-0.5.3-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c2eac9cb0493acd0c3f540dc0076b2ca9fbb86f18a76bc1a76ae632c72fc2ed7 |
|
MD5 | 7f277fa4cdffc3b612d7ed639340b2a6 |
|
BLAKE2b-256 | c14f7218ace05172df2b2b59b9b2fed4ac1a93693eb03ba665b3e46292fbb364 |
Hashes for CyRK-0.5.3-cp39-cp39-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 250d7a674d3599d8c9e41911fd7d9d85c6829112b25e9b8aa97a25eb480a3653 |
|
MD5 | 5d6b3c97406cdda664e7423e778c2201 |
|
BLAKE2b-256 | 67c04979e471d4b8e9d02540ed1dea6d4d652b9623cb2f565b64b8877057234d |
Hashes for CyRK-0.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | de1f05654a527102356e66e4c5ca38be2eeecb63da2e44618d4864f6558d9b5e |
|
MD5 | 4b1b865c0e491d95bd3e56c9cd2c4c3e |
|
BLAKE2b-256 | 795d7f775c790672dcfc6997c86a7777091d4697eed36d21f6a1113a4b8c7492 |
Hashes for CyRK-0.5.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 37d2044e6bd8ac2e29ad0ea4b971a3c1e384abf6366a5e30a46ff33a84b5c25a |
|
MD5 | 6d156ea9f67c3626e562fb1471e171b7 |
|
BLAKE2b-256 | c1df5b2c210cb3844344683f975498ba4a947ea382bbfc40c07fdeea64f12bab |
Hashes for CyRK-0.5.3-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e070469794dc51cc823b202253f520242a4347176fbd9b0be6df5a2f73f93ee6 |
|
MD5 | 449a1a977d7bd17e307a2c028ee93867 |
|
BLAKE2b-256 | 432fac974ee866cef851b6eea239c503a9c10837269c3beb25dbf95e5dc9e0b4 |
Hashes for CyRK-0.5.3-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d9383c8f3a28cc8a779f6ecb91da97ef10eb015400ec13beac20b9728bc91ca3 |
|
MD5 | c1dc38ab912aa4ac638807019d8c1530 |
|
BLAKE2b-256 | e5559f7327c5db70dbd73e4e5ec747ab08fd9703922f3a80db8db1c83c0b5ec8 |
Hashes for CyRK-0.5.3-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1ee584e3f6435fb9e5141cbfdfe20b765b73df431385bd61b6fa14d96754ba03 |
|
MD5 | 850c6113437b759e182a642108b8b759 |
|
BLAKE2b-256 | 2fe8be920072873099e592c4e0d93f286d7ab3861bf97444b662cc1df604675c |
Hashes for CyRK-0.5.3-cp38-cp38-musllinux_1_1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 309e2ac9006e6a6decd3d607b8c2030648158480c993c7a53bf04b618b22f47d |
|
MD5 | 506fcfaabc00361f61a36825aa6d0d0e |
|
BLAKE2b-256 | 52bd956ae45d465bc76f2da6f0125c35d79dd49be9954ee6815e4cdd3835529f |
Hashes for CyRK-0.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6ada2badd74d421f456c94f5dec5ab7facddbdffabfbc5a45adee7397096e265 |
|
MD5 | a28fde55485591408ff7896cb5143d9a |
|
BLAKE2b-256 | 105a5551ba8c31b2337dd083f05fba5ecc259948108603479cd8d36ee8c0170f |
Hashes for CyRK-0.5.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 72b59d1f5b33fe496035ad590a13bb623954bbfe9cb575a2c1a994bb43986eeb |
|
MD5 | 4c68e202f99d3dae5f3463ccebe2c128 |
|
BLAKE2b-256 | b0f5cccc2353b4f9349ee67076e12f14b0609330a40bed5456fa28a6c622ed29 |
Hashes for CyRK-0.5.3-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 15de5af7b552ee37058865961ae6ca812f976f6ee927c4b7e21010728f93026b |
|
MD5 | 4168ea9f58b4d677e5f68a9e58bd1023 |
|
BLAKE2b-256 | 128c0f4ef3b1d7027fdcef02678e3fc0c8459f218147e9291ede44925d11b3a5 |