Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## 0.11.0 2026-01-15

### Changed

* !Remove recursive implementations
* All dimensionalities now use const-generic bounded implementations
* For dimensions higher than const-unrolling limit, a run-time loop of the same form is used
* No notable change in performance for high dimensions
* No change to API for `::interpn` convenience functions
* All methods are now compatible with static analysis of memory usage via cargo-call-stack
* Refactor internals to reduce duplication
* Improve form of early bounds checks to be interpreted correctly by the compiler
* 30% speedup in some cases, no effect on most
* Bounds checks done via iterator do not always result in optimizing out panic branches
* Test cubic methods in higher dimensions

## 0.10.0 2026-01-10

### Added
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "interpn"
version = "0.10.0"
version = "0.11.0"
edition = "2024"
rust-version = "1.87" # 2025-05-15
authors = ["James Logan <jlogan03@gmail.com>"]
Expand Down Expand Up @@ -35,7 +35,7 @@ itertools = { version = "0.14.0", optional = true }
[dev-dependencies]
rand = "0.9.2"
criterion = "0.8.1"
ndarray = "0.17.1"
ndarray = "0.17.2"

[features]
default = ["std", "crunchy/limit_64", "par"]
Expand Down
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@
[Rust Docs](https://docs.rs/interpn/latest/interpn/)

N-dimensional interpolation/extrapolation methods, no-std and no-alloc compatible,
prioritizing correctness, performance, and compatiblity with memory-constrained environments.
prioritizing correctness, performance, and compatibility with memory-constrained environments.

Available as a rust crate and python library.

## Features

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

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

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

<br>

<img src="./docs/speedup_vs_dims_1_obs_linear_inverted.svg" alt="">

For larger jobs such as image processing, the non-allocating evaluation pattern results
in a nearly-linear thread speedup, limited only by thread spawning overhead and memory bandwidth.

<img src="./docs/speedup_vs_threads_10000000_obs_inverted.svg" alt="">

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

## Installation
Expand All @@ -48,6 +53,9 @@ after installing this extra compiler dependency:
rustup component add llvm-tools-preview
```

An LLVM install matching the version used by rustc is also required for doing PGO;
see the `./scripts/distr_pgo.sh` or CI workflows for the exact version.

## Rust Examples

### Regular Grid
Expand Down
2 changes: 1 addition & 1 deletion docs/1d_quality_of_fit_Rectilinear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/1d_quality_of_fit_Rectilinear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/1d_quality_of_fit_Regular.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/1d_quality_of_fit_Regular.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/2d_quality_of_fit_Rectilinear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/2d_quality_of_fit_Rectilinear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/2d_quality_of_fit_Regular.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/2d_quality_of_fit_Regular.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_cubic.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_cubic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_linear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_prealloc_cubic.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_prealloc_cubic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_prealloc_linear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/3d_throughput_vs_nobs_prealloc_linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_cubic.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_cubic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_linear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_prealloc_cubic.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_prealloc_cubic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_prealloc_linear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/4d_throughput_vs_nobs_prealloc_linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 23 additions & 18 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
# InterpN

[Writeup](https://jlogan.dev/blog/#2025-11-10-interpn-fast-interpolation) |
[Repo](https://github.com/jlogan03/interpn) |
[Python Docs](https://interpnpy.readthedocs.io/en/latest/) |
[Rust Docs](https://docs.rs/interpn/latest/interpn/)

This library provides serializable N-dimensional interpolators
backed by compute-heavy code written in Rust.
N-dimensional interpolation/extrapolation methods, no-std and no-alloc compatible,
prioritizing correctness, performance, and compatibility with memory-constrained environments.

These methods perform zero allocation when evaluated (except, optionally, for the output).
Because of this, they have minimal per-call overhead, and are particularly
effective when examining small numbers of observation points. See the [performance](/perf) page for detailed benchmarks.
Available as a rust crate and python library.

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

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

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

Expand All @@ -26,13 +27,14 @@ The methods provided here, while more limited in scope than scipy's,
* can also be used easily in web and embedded applications via the Rust library
* are permissively licensed

--8<--
docs/speedup_vs_dims_1_obs_linear.html
--8<--
<br>

<img src="./speedup_vs_dims_1_obs_linear_inverted.svg" alt="">

For larger jobs such as image processing, the non-allocating evaluation pattern results
in a nearly-linear thread speedup, limited only by thread spawning overhead and memory bandwidth.

--8<--
docs/speedup_vs_dims_1_obs_cubic.html
--8<--
<img src="./speedup_vs_threads_10000000_obs_inverted.svg" alt="">

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

Expand All @@ -44,14 +46,16 @@ pip install interpn

## Profile-Guided Optimization

To build the extension with profile-guided optimization, do `uv run python ./scripts/run_pgo.py`
after installing these extra compiler dependencies:
To build the extension with profile-guided optimization, do `sh ./scripts/distr_pgo.sh`
after installing this extra compiler dependency:

```bash
cargo install cargo-pgo
rustup component add llvm-tools-preview
```

An LLVM install matching the version used by rustc is also required for doing PGO;
see the `./scripts/distr_pgo.sh` or CI workflows for the exact version.

## Rust Examples

### Regular Grid
Expand Down Expand Up @@ -182,6 +186,7 @@ out2 = roundtrip_interpolator.eval(obs)
assert np.all(out == out2)
```


# License

Licensed under either of
Expand Down
2 changes: 1 addition & 1 deletion docs/nearest_quality_of_fit.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/nearest_quality_of_fit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1000_obs_cubic.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1000_obs_cubic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1000_obs_linear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1000_obs_linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1_obs_cubic.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1_obs_cubic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1_obs_linear.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/speedup_vs_dims_1_obs_linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/speedup_vs_dims_1_obs_linear_inverted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/speedup_vs_threads_10000000_obs.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/speedup_vs_threads_10000000_obs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions docs/speedup_vs_threads_10000000_obs_inverted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading