ChebyshevND
Fast multidimensional Chebyshev interpolation in Python, using DCTs to compute coefficients, Numba-accelerated Clenshaw recursions for evaluation, and structured coefficient pruning for compression.
For smooth functions, Chebyshev interpolation converges spectrally: the error decays exponentially with the number of nodes per axis. ChebyshevND turns a tensor grid of function samples into an interpolant that can be evaluated anywhere in the domain at close to machine precision — with built-in error estimates that come free from the coefficient decay.
Features
- Interpolant classes for 1D–4D (
ChebyshevInterpolant1D…ChebyshevInterpolant4D) - Coefficients computed with a single fast DCT (
scipy.fft), on either Chebyshev root nodes or Gauss–Lobatto (endpoint-including) nodes - Numba-jitted Clenshaw evaluation kernels, also usable standalone
(
clenshaw_1d…clenshaw_4d,clenshaw_nd) - A-posteriori error estimates from trailing coefficient magnitudes
- Structured pruning (
optimize) that trims insignificant trailing coefficient slices under a global error budget - Dimension precomputation (
precompute_x) for cheap repeated evaluation when one variable is held fixed
Installation
pip install chebyshevnd
Requires Python ≥ 3.10, with numpy, scipy, and numba installed
automatically. To install the development version from source:
git clone https://github.com/Philip-Lynch/chebyshevND.git
cd chebyshevND
pip install -e .
Quickstart
Sample your function at Chebyshev nodes, build the interpolant from the values, evaluate anywhere:
import numpy as np
from chebyshevnd import ChebyshevInterpolant1D, chebyshev_nodes
f = lambda x: 1.0 / (1.0 + 25 * x**2) # Runge function
a, b = -1.0, 1.0
x_nodes = chebyshev_nodes(100, a, b)
interp = ChebyshevInterpolant1D(f(x_nodes), a, b)
interp.evaluate(0.3) # a float
interp.evaluate(np.linspace(a, b, 50)) # an array
interp.relative_error() # a-posteriori error estimate
In higher dimensions, sample on the tensor grid (indexing='ij') and pass
the value array with per-axis domain bounds:
from chebyshevnd import ChebyshevInterpolant3D, chebyshev_nodes
f = lambda x, y, z: np.sin(x) * np.cos(y) * np.exp(-z)
x = chebyshev_nodes(20, 0.0, 2.0)
y = chebyshev_nodes(20, -1.0, 3.0)
z = chebyshev_nodes(20, 1.0, 4.0)
X, Y, Z = np.meshgrid(x, y, z, indexing="ij")
interp = ChebyshevInterpolant3D(f(X, Y, Z), 0.0, 2.0, -1.0, 3.0, 1.0, 4.0)
interp.evaluate(1.3, 0.5, 2.5)
interp.optimize(rel_tol=1e-8) # prune insignificant coefficients
interp.effective_grid() # e.g. (10, 13, 11) — down from (20, 20, 20)
interp.precompute_x(1.3) # collapse x once ...
interp.evaluate_yz(0.5, 2.5) # ... then evaluate repeatedly in (y, z), ~3x faster
The example notebooks walk through each dimension, including convergence, coefficient decay, pruning, and precomputation timings.
How it works
- Sampling. The function is sampled on a tensor grid of Chebyshev nodes —
either the roots of $T_N$ (
chebyshev_nodes) or the Gauss–Lobatto extrema including the endpoints (chebyshev_gauss_lobatto_nodes). - Coefficients. The Chebyshev expansion coefficients are obtained with a single n-dimensional DCT (type II for root nodes, type I for Gauss–Lobatto), costing $O(M \log M)$ for $M$ grid points.
- Evaluation. The tensor series is evaluated with nested Clenshaw recursions, compiled with Numba. Evaluation never reconstructs polynomial values explicitly, which keeps it numerically stable.
- Compression. For smooth functions the coefficients decay geometrically
along every axis, so most of the tensor is numerically irrelevant.
optimizegreedily discards trailing slices while keeping the summed discarded magnitude — an upper bound on the introduced uniform error — under a relative tolerance you choose. Trailing coefficient magnitudes also provide error estimates (absolute_error,relative_error) without any extra function samples.
Roadmap
Planned for future releases:
- Interpolants beyond 4D (5D/6D) via a generic n-dimensional kernel
- Analytic partial derivatives of interpolants, evaluated efficiently through the relationship between Chebyshev polynomials of the first and second kind
- Precomputation over multiple leading dimensions for even cheaper repeated evaluation
Development
Run the test suite with:
pip install -e .
pip install pytest
pytest
Citation
The techniques implemented in this package were derived and developed for:
H. Khalvati, P. Lynch, O. Burke, L. Speri, M. van de Meent, and Z. Nasipak, Systematic errors in fast relativistic waveforms for Extreme Mass Ratio Inspirals, Phys. Rev. D 113, 084042 (2026), arXiv:2509.08875.
If this package contributes to your research, please cite that paper — machine-readable citation metadata is in CITATION.cff.
@article{Khalvati2026systematic,
author = {Khalvati, Hassan and Lynch, Philip and Burke, Ollie and
Speri, Lorenzo and van de Meent, Maarten and Nasipak, Zachary},
title = {Systematic errors in fast relativistic waveforms for
Extreme Mass Ratio Inspirals},
journal = {Phys. Rev. D},
volume = {113},
pages = {084042},
year = {2026},
doi = {10.1103/4ly7-zn15},
eprint = {2509.08875},
archivePrefix = {arXiv},
primaryClass = {gr-qc}
}
License
MIT — see LICENSE.
Metadata
Release files for ChebyshevND 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chebyshevnd-0.1.0.tar.gz | 19.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chebyshevnd-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.2 kB
Release files / chebyshevnd-0.1.0.tar.gz
| Download URL | chebyshevnd-0.1.0.tar.gz |
|---|---|
| Size | 19.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fa48545b7480282323dd01c5d75567f7ff0607d93eb3a7cec5896919ce541919
|
|
BLAKE2b-256 checksum How to use checksums |
3d67423dd008d9d0043a58ac196d94b244d65aa2f4e7e546b23de1b36ed3c20e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency logRelease files / chebyshevnd-0.1.0-py3-none-any.whl
| Download URL | chebyshevnd-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2b3cbd30347228b80b46d18e0dd064c98147db9a7e7916261d92bf032602c87
|
|
BLAKE2b-256 checksum How to use checksums |
29d3e691a0a19fc7c8ee7d8c9ada36b0df369923dcf58e6c744ea50d5a35a859
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency log