Metadata-Version: 2.4
Name: interpn
Version: 0.2.4
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Dist: numpy>=2
Requires-Dist: pydantic>=2.5.2
Requires-Dist: pytest>=8.0 ; extra == 'test'
Requires-Dist: coverage>=7.3.2 ; extra == 'test'
Requires-Dist: ruff>=0.4.10 ; extra == 'test'
Requires-Dist: pyright==1.1.337 ; extra == 'test'
Requires-Dist: mktestdocs>=0.2.1 ; extra == 'test'
Requires-Dist: scipy>=1.11.4 ; extra == 'test'
Requires-Dist: matplotlib>=3.8 ; extra == 'test'
Requires-Dist: scipy>=1.11.4 ; extra == 'bench'
Requires-Dist: matplotlib>=3.8 ; extra == 'bench'
Requires-Dist: memory-profiler>=0.61.0 ; extra == 'bench'
Requires-Dist: mkdocs>=1.5.3 ; extra == 'doc'
Requires-Dist: mkdocstrings-python>=1.7.5 ; extra == 'doc'
Requires-Dist: mkdocs-material>=9.4.10 ; extra == 'doc'
Provides-Extra: test
Provides-Extra: bench
Provides-Extra: doc
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Summary: N-dimensional interpolation/extrapolation methods
Author-email: James Logan <jlogan03@gmail.com>
Requires-Python: >=3.9, <3.14
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# interpn

Python bindings to the `interpn` Rust library for N-dimensional interpolation and extrapolation. 

[Docs](https://interpnpy.readthedocs.io/en/latest/) |
[Repo](https://github.com/jlogan03/interpnpy) |
[Rust Library (github)](https://github.com/jlogan03/interpn) | 
[Rust Docs (docs.rs)](https://docs.rs/interpn/latest/interpn/)

## Features

| Feature →<br>↓ Interpolant Method | Regular<br>Grid | Rectilinear<br>Grid | Json<br>Serialization |
|-----------------------------------|-----------------|---------------------|-----------------------|
| Linear                            |   ✅            |     ✅              | ✅                    |
| Cubic                             |   ✅            |     ✅              | ✅                    |

The methods provided here, while more limited in scope than scipy's, are

* significantly faster for higher dimensions (1-3 orders of magnitude under most conditions)
* use almost no RAM (and perform no heap allocations at all)
* produce significantly improved floating-point error (by 1-2 orders of magnitude)
* are json-serializable using Pydantic
* can also be used easily in web and embedded applications via the Rust library
* are permissively licensed

![ND throughput 1 obs](./docs/throughput_vs_dims_1_obs.svg)

See [here](https://interpnpy.readthedocs.io/en/latest/perf/) for more info about quality-of-fit, throughput, and memory usage.

## Installation

```bash
pip install interpn
```

## Example: Available Methods

```python
import interpn
import numpy as np

# Build grid
x = np.linspace(0.0, 10.0, 5)
y = np.linspace(20.0, 30.0, 4)
grids = [x, y]

xgrid, ygrid = np.meshgrid(x, y, indexing="ij")
zgrid = (xgrid + 2.0 * ygrid)  # Values at grid points

# Grid inputs for true regular grid
dims = [x.size, y.size]
starts = np.array([x[0], y[0]])
steps = np.array([x[1] - x[0], y[1] - y[0]])

# Initialize different interpolators
# Call like `linear_regular.eval([xs, ys])`
linear_regular = interpn.MultilinearRegular.new(dims, starts, steps, zgrid)
cubic_regular = interpn.MulticubicRegular.new(dims, starts, steps, zgrid)
linear_rectilinear = interpn.MultilinearRectilinear.new(grids, zgrid)
cubic_rectilinear = interpn.MulticubicRectilinear.new(grids, zgrid)
```

## Example: Multilinear Interpolation on a Regular Grid

```python
import interpn
import numpy as np

# Build grid
x = np.linspace(0.0, 10.0, 5)
y = np.linspace(20.0, 30.0, 4)

xgrid, ygrid = np.meshgrid(x, y, indexing="ij")
zgrid = (xgrid + 2.0 * ygrid)  # Values at grid points

# Grid inputs for true regular grid
dims = [x.size, y.size]
starts = np.array([x[0], y[0]])
steps = np.array([x[1] - x[0], y[1] - y[0]])

# Observation points pointed back at the grid
obs = [xgrid.flatten(), ygrid.flatten()]

# Initialize
interpolator = interpn.MultilinearRegular.new(dims, starts, steps, zgrid.flatten())

# Interpolate
out = interpolator.eval(obs)

# Check result
assert np.allclose(out, zgrid.flatten(), rtol=1e-13)

# Serialize and deserialize
roundtrip_interpolator = interpn.MultilinearRegular.model_validate_json(
    interpolator.model_dump_json()
)
out2 = roundtrip_interpolator.eval(obs)

# Check result from roundtrip serialized/deserialized interpolator
assert np.all(out == out2)
```


# License

Licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

