Metadata-Version: 2.4
Name: convinterp
Version: 0.2.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Dist: numpy
Requires-Dist: sympy ; extra == 'derivation'
Requires-Dist: pytest ; extra == 'test'
Requires-Dist: juliacall ; extra == 'test'
Requires-Dist: sympy ; extra == 'test'
Provides-Extra: derivation
Provides-Extra: test
License-File: LICENSE
Summary: High-order convolution interpolation, derivatives and integrals on uniform grids in any dimension, with a Rust core
Keywords: interpolation,convolution,derivatives,numerical methods,scientific computing
Author: Nikolaj Maack Bielefeld
License-Expression: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://convinterp.org
Project-URL: Julia package, https://github.com/NikoBiele/ConvolutionInterpolations.jl
Project-URL: Repository, https://github.com/NikoBiele/convinterp

# convinterp

High-order convolution interpolation on uniform grids in any number of dimensions, with
derivatives and integrals, for Python. The core is written in Rust; the kernels are exact
polynomials.

convinterp is a port of the Julia package
[ConvolutionInterpolations.jl](https://github.com/NikoBiele/ConvolutionInterpolations.jl), by the
same author, and is tested against it.

**Documentation: [convinterp.org](https://convinterp.org)**, with a user guide and accuracy and
speed comparisons with SciPy.

**Status: alpha.** Interpolation, derivatives and integrals on uniform grids work in any
dimension. Scattered data are coming.

## Installation

```
pip install convinterp
```

## Example

```python
import numpy as np
from convinterp import convolution_interpolation

# 1D: data on a uniform grid
x = np.linspace(0.0, 2 * np.pi, 50)                     # 50 uniformly spaced knots
itp = convolution_interpolation(x, np.sin(x))           # the interpolant of sin(x)
print(itp(1.0))                                         # ≈ sin(1) = 0.841471

# derivatives: one order for the whole interpolant
d_itp = convolution_interpolation(x, np.sin(x), derivative=1)
print(d_itp(1.0))                                       # ≈ cos(1) = 0.540302

# integrals: a negative order, zero at the first knot x[0] = 0
i_itp = convolution_interpolation(x, np.sin(x), derivative=-1)
print(i_itp(1.0))                                       # ≈ 1 − cos(1) = 0.459698

# 2D: one knot array per axis, and data whose axis d runs along knots[d]
y = np.linspace(0.0, 1.0, 30)                           # knots of the second axis
data = np.sin(x)[:, None] * np.exp(y)[None, :]          # sin(x)·exp(y) on the 50 × 30 grid
itp2 = convolution_interpolation((x, y), data)          # the 2D interpolant
print(itp2(1.0, 0.5))                                   # ≈ sin(1)·exp(0.5) = 1.387351

# a mixed derivative, with an order per axis: ∂²/∂x∂y
dxy = convolution_interpolation((x, y), data, derivative=(1, 1))
print(dxy(1.0, 0.5))                                    # ≈ cos(1)·exp(0.5) = 0.890808

# arrays of points broadcast like NumPy arrays: here a 3 × 4 table of values
xs = np.array([[0.5], [1.0], [1.5]])                    # a column of x coordinates
ys = np.array([[0.1, 0.2, 0.3, 0.4]])                   # a row of y coordinates
print(itp2(xs, ys).shape)                               # (3, 4)
```

## Kernels

`kernel="auto"` (the default) chooses by the number of dimensions: `"b7"` in 1D and 2D, `"b5"` in
3D, and narrower kernels beyond. You can choose any of:

| kernel | order of accuracy | highest derivative | highest integral |
|---|---|---|---|
| `"a0"` | nearest neighbour | none | 2 |
| `"a1"` | linear | none | 2 |
| `"a3"`, `"a4"`, `"a5"`, `"a7"` | cubic and higher | 1 | 4 |
| `"b5"`, `"b7"`, `"b9"`, `"b11"`, `"b13"` | high order | 3 to 7 | 6 to 8 |

## Boundary conditions

The data are extended beyond each boundary by extrapolation: `bc="detect"` (the default) uses
polynomial extrapolation where the data near the boundary allow it and linear otherwise. You can
also choose `"poly"`, `"linear"` or `"quadratic"`, separately for each side and each axis.

## Citing

If you use convinterp in your work, please cite it:
[doi.org/10.5281/zenodo.22972816](https://doi.org/10.5281/zenodo.22972816) (always the latest
version). A BibTeX entry is on the [About page](https://convinterp.org/about.html).

## Declaration of AI Assistance

The Rust core and much of the Python code of convinterp were written with substantial assistance
from Claude (Anthropic). The mathematical methods, the kernels and the reference implementation
come from the author's Julia package
[ConvolutionInterpolations.jl](https://github.com/NikoBiele/ConvolutionInterpolations.jl), and the
port is validated against it: the test suite compares convinterp with the Julia package across
kernels, boundary conditions, derivative and integral orders and dimensions, with the boundary
coefficients agreeing bit for bit. The author has reviewed and is responsible for all code.

## License

MIT
