Metadata-Version: 2.1
Name: CyRK
Version: 0.1.1
Summary: Runge-Kutta ODE Integrator Implemented in Cython and Numba.
Home-page: https://github.com/jrenaud90/CyRK
Author: Joe P. Renaud
Author-email: joe.p.renaud@gmail.com
Classifier: Development Status :: 4 - Beta
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Cython
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Natural Language :: English
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE.md

# CyRK
<div style="text-align: center;">
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/Python-3.7|3.8|3.9|3.10-blue" alt="Python Version 3.7-3.10" /></a>
<a href="https://codecov.io/gh/jrenaud90/CyRK" ><img src="https://codecov.io/gh/jrenaud90/CyRK/branch/main/graph/badge.svg?token=MK2PqcNGET" alt="Code Coverage"/></a>
<a href="https://github.com/jrenaud90/CyRK/actions/workflows/push_tests_win.yml"><img src="https://github.com/jrenaud90/CyRK/actions/workflows/push_tests_win.yml/badge.svg?branch=main" alt="Windows Tests" /></a>
<a href="https://github.com/jrenaud90/CyRK/actions/workflows/push_tests_win.yml"><img src="https://github.com/jrenaud90/CyRK/actions/workflows/push_tests_mac.yml/badge.svg?branch=main" alt="MacOS Tests" /></a>
<a href="https://github.com/jrenaud90/CyRK/actions/workflows/push_tests_win.yml"><img src="https://github.com/jrenaud90/CyRK/actions/workflows/push_tests_ubun.yml/badge.svg?branch=main" alt="Ubuntu Tests" /></a>
</div>

---

<a href="https://github.com/jrenaud90/CyRK/releases"><img src="https://img.shields.io/badge/CyRK-0.1.1 Alpha-orange" alt="CyRK Version 0.0.1 Alpha" /></a>


**Runge-Kutta ODE Integrator Implemented in Cython and Numba**

CyRK provides fast ODE integration while still allowing for differential equations written in Python. 

CyRK's numba (njit-safe) implementation is 13-25x faster than scipy's solve_ivp function. The cython implementation is about 20x
faster. The cython function is also largely pre-compiled which avoids most of the initial performance hit found
with the numba version.

![CyRK Performance](CyRK_SciPy_Compare_v0-0-1-dev4.png)

## Installation

It is recommended you use an [Anaconda](https://www.anaconda.com/products/distribution) environment.

To install simply open a terminal (in administrator mode if using Windows) and call:

`pip install CyRK`

This will create a dynamic (editable) link to the CyRK directory so that future updates can be more easily installed.

During installation, CyRK will attempt to install Cython and Numpy in order to compile the cython code (unless
installation is happening via a pre-compiled wheel). After the files have been compiled, cython will be uninstalled and
CyRK's runtime dependencies (see setup.py for the latest list) will be installed instead.

### Installation Troubleshooting

*There are currently no reported installation issues.
If you run into one please [report it](https://github.com/jrenaud90/CyRK/issues). We will work on a fix and/or add
workaround information 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:

```python
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(t, y):
    dy = list()
    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`:

```python
from CyRK import nbrk_ode
time_domain, y_results, success, message = \
    nbrk_ode(diffeq, 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. 

```python
@njit
def diffeq(t, y, dy):
    dy[0] = (1. - 0.01 * y[1]) * y[0]
    dy[1] = (0.02 * y[0] - 1.) * y[1]
```

You can then call the ODE solver in a similar fashion as the numba version.

```python
from CyRK import cyrk_ode
time_domain, y_results, success, message = \
    cyrk_ode(diffeq, 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 the `diffeq`.
- `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 to `t_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](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html)):
  - `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.

### Limitations and Known Issues

- [Issue 1](https://github.com/jrenaud90/CyRK/issues/1): Absolute tolerance can only be passed as a single value
(same for all y's).
- [Issue 3](https://github.com/jrenaud90/CyRK/issues/3): Right now the cython version only allows for complex-valued
y-values.
- [Issue 5](https://github.com/jrenaud90/CyRK/issues/5): The numba solver is worse than the pure python scipy solver at
large timespans (high integration times).

## 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](https://github.com/jrenaud90/CyRK) website so more users learn about this package.

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](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html).

## Contribute to CyRK
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](https://github.com/jrenaud90/CyRK/issues).
- If you would like to contribute but don't know where to start, check out the 
[good first issue](https://github.com/jrenaud90/CyRK/labels/good%20first%20issue) 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.
