ApproxKit
ApproxKit extends NumPy's Chebyshev approximation tools to arbitrary dimensions and provides fast polynomial and rational approximation methods for scientific computing.
It supports:
- Fast Chebyshev approximation using discrete cosine transforms (DCT)
- N-dimensional Chebyshev fitting
- N-dimensional Chebyshev evaluation
- N-dimensional Chebyshev Vandermonde matrices
- Chebyshev and Chebyshev-Lobatto node generation
- Automatic polynomial-degree selection using AIC
- Padé approximation
- Rational least-squares fitting
- Utility functions for interval transformations
Installation
pip install approxkit
Install with testing support:
pip install "approxkit[test]"
Requirements
- Python 3.11+
- NumPy
- SciPy
- mpmath
Quick Start
Approximate a four-dimensional function on
[(0, 4), (0, 4), (0, 4), (0, 4)]:
from approxkit import ChebyshevND
approx = ChebyshevND.fit_dct(
lambda x, y, z, w: x + y * z + w**2,
n=(8, 8, 8, 8),
domain=[
(0, 4),
(0, 4),
(0, 4),
(0, 4),
],
)
value = approx(0.1, 0.2, 0.3, 0.4)
The approximation behaves like a regular Python function while automatically handling the mapping between the physical domain and the Chebyshev interval [-1, 1].
Chebyshev polynomials are naturally defined on [-1, 1].
Internally, the approximation is evaluated on [-1, 1] while users work directly in physical coordinates.
1D Chebyshev Approximation
Approximate exp(x) on [0, 2]:
import numpy as np
from approxkit import ChebyshevND
approx = ChebyshevND.fit_dct(
np.exp,
n=9,
domain=[(0, 2)],
)
x = np.linspace(0, 2, 50)
assert np.allclose(
approx(x),
np.exp(x),
atol=1e-10,
)
Why ApproxKit?
NumPy provides excellent Chebyshev support for one-, two-, and three-dimensional problems.
ApproxKit generalizes these capabilities to arbitrary dimensions while adding:
- Domain-aware approximation objects
- Fast DCT-based fitting
- Padé approximation
- Rational least-squares fitting
- Unified N-dimensional APIs
This makes ApproxKit useful for:
- Surrogate modeling
- Scientific computing
- Reduced-order models
- Numerical integration
- High-dimensional approximation problems
Approximation Objects
Unlike lower-level fitting routines that only return coefficients, ApproxKit provides high-level approximation objects.
import numpy as np
from approxkit import ChebyshevND
approx = ChebyshevND.fit_dct(
np.exp,
n=9,
)
y = approx(x)
These objects combine:
- model coefficients
- domain metadata
- callable evaluation
- approximation diagnostics
- utility methods
into a single callable interface.
Key Features
N-Dimensional Chebyshev Approximation
Fit and evaluate Chebyshev approximations in any number of dimensions.
from approxkit import chebfitnd
coef = chebfitnd(
(x1, x2, x3, x4, x5),
values,
deg=[4, 4, 4, 4, 4],
)
Domain-Aware Approximation Objects
import numpy as np
from approxkit import ChebyshevND
approx = ChebyshevND.fit_dct(
np.exp,
n=9,
domain=[(0, 2)],
)
y = approx(1.5) # ≈ exp(1.5)
Physical coordinates are automatically mapped to the Chebyshev interval.
Fast DCT-Based Fitting
import numpy as np
from approxkit import chebfit_dct
c = chebfit_dct(
np.tanh,
n=25,
)
Uses discrete cosine transforms to compute coefficients efficiently.
Rational Approximation
import numpy as np
from numpy.polynomial import Polynomial
from approxkit import padefit, padefitlsq
x = np.linspace(0, 2, 100)
# Taylor polynomial for exp
p = Polynomial(
[1, 1, 1 / 2, 1 / 6, 1 / 24]
)
assert np.allclose(
p(x),
np.exp(x),
atol=1e-1,
)
# Classical Padé approximation from Taylor coefficients
pade = padefit(p.coef)
assert np.allclose(
pade(x),
np.exp(x),
atol=1e-2,
)
# Rational least-squares fit from sampled values
rational = padefitlsq(
np.exp,
m=3,
n=3,
a=0,
b=2,
)
assert np.allclose(
rational(x),
np.exp(x),
atol=1e-6,
)
Compared with a Taylor polynomial of the same order, Padé and rational least-squares approximations often achieve substantially higher accuracy over a finite interval.
Supports both classical Padé approximation and least-squares rational fitting.
Chebyshev Node Generation
Generate interpolation and quadrature nodes for interpolation, quadrature, and spectral methods.
from approxkit import chebyshev_nodes, chebyshev_lobatto_nodes
x = chebyshev_nodes(16)
x = chebyshev_lobatto_nodes(16)
Automatic Degree Selection
Select a suitable polynomial degree using Akaike's Information Criterion.
from approxkit import select_degree_aic
deg = select_degree_aic(x, y)
This helps balance approximation accuracy and model complexity.
NumPy vs ApproxKit
| Capability | NumPy | ApproxKit |
|---|---|---|
| 1D fitting | ✓ | ✓ |
| 2D fitting | ✓ | ✓ |
| 3D fitting | ✓ | ✓ |
| N-dimensional fitting (N > 3) | ✗ | ✓ |
| N-dimensional evaluation (N > 3) | ✗ | ✓ |
| N-dimensional Vandermonde matrices (N > 3) | ✗ | ✓ |
| Domain-aware approximation objects | ✗ | ✓ |
| Automatic degree selection (AIC) | ✗ | ✓ |
| Padé approximation | ✗ | ✓ |
| Rational least-squares approximation | ✗ | ✓ |
Familiar NumPy-Style API
ApproxKit extends NumPy's Chebyshev tools:
| NumPy | ApproxKit |
|---|---|
chebval() |
chebvalnd() |
chebvander() |
chebvandernd() |
chebfit2d() / chebfit3d() |
chebfitnd() |
chebpts1() |
chebyshev_nodes() |
chebpts2() |
chebyshev_lobatto_nodes() |
Choosing the Right Method
Decision Guide
What do you want to do?
├─ Approximate a callable function on Chebyshev nodes
│ ├─ 1D or ND approximation object → ChebyshevND.fit_dct()
│ └─ Coefficients only → chebfit_dct()
│
├─ Fit Chebyshev polynomials to arbitrary sampled data
│ ├─ Approximation object → ChebyshevND.fit()
│ ├─ N-dimensional coefficients → chebfitnd()
│ └─ 1D Chebyshev polynomial → chebfit1d()
│
├─ Construct a rational approximation
│ ├─ Taylor coefficients available → padefit()
│ └─ Sampled values available → padefitlsq()
│
└─ Utilities
├─ Choose interpolation nodes → chebyshev_nodes()
├─ Need endpoints included → chebyshev_lobatto_nodes()
└─ Unknown polynomial degree → select_degree_aic()
DCT Fitting
Use chebfit_dct() when:
- Function values are available on Chebyshev nodes
- The function is inexpensive to evaluate on Chebyshev grids
- Maximum fitting speed is desired
import numpy as np
from approxkit import chebfit_dct
c = chebfit_dct(
np.exp,
n=25,
)
Note on n
n specifies the number of Chebyshev nodes used to construct the approximation.
Least-Squares Chebyshev Fitting
Use chebfitnd() when:
- Data are sampled at arbitrary locations
- Experimental or simulation data must be fitted
- Weighted least-squares fitting is desired
from approxkit import chebfitnd
coef = chebfitnd(
(temperature, pressure),
efficiency,
deg=[6, 6],
)
Note on deg
deg specifies the polynomial degree in each dimension.
1D Convenience Fitting
p = chebfit1d(
x,
y,
deg=8,
)
Returns a fitted numpy.polynomial.Chebyshev object and serves as a convenience wrapper around numpy.polynomial.Chebyshev.fit().
Choosing Interpolation Nodes
Use chebyshev_nodes() when:
- Building interpolation polynomials
- Sampling smooth functions
- Minimizing Runge phenomena
x = chebyshev_nodes(32)
Use chebyshev_lobatto_nodes() when:
- Endpoints must be included
- Spectral methods are used
- Minimax approximation workflows are implemented
x = chebyshev_lobatto_nodes(32)
Choosing a Polynomial Degree
Use select_degree_aic() when:
- The polynomial degree is unknown
- Data contain noise
- Overfitting should be avoided
degree = select_degree_aic(
x,
y,
)
p = chebfit1d(
x,
y,
deg=degree,
)
The selected degree minimizes Akaike's Information Criterion (AIC), balancing model complexity against residual error.
Classical Padé Approximation
Use padefit() when Taylor-series coefficients are known.
coeffs = [1, 1, 1 / 2, 1 / 6, 1 / 24]
p = padefit(coeffs)
Rational Least-Squares Approximation
Use padefitlsq() when sampled values are available.
import numpy as np
from approxkit import padefitlsq
p = padefitlsq(
np.exp,
m=3,
n=3,
a=0,
b=2,
)
API Overview
ApproxKit provides both low-level fitting utilities and high-level approximation objects.
from approxkit import (
ChebyshevND,
PadeApproximation,
chebfit_dct,
chebfit1d,
chebfitnd,
chebvalnd,
chebvandernd,
chebyshev_nodes,
chebyshev_lobatto_nodes,
select_degree_aic,
padefit,
padefitlsq,
map_to_interval,
map_from_interval,
)
Approximation Objects
ApproxKit provides high-level approximation objects for both polynomial and rational approximation:
ChebyshevND
PadeApproximation
These objects are callable and carry approximation metadata such as domains, coefficients, poles, zeros, and error estimates.
ChebyshevND
Represents a Chebyshev approximation together with optional domain metadata.
Common Methods
approx(x)
approx.grid(x, y)
approx.truncate(5)
approx.copy()
Features
- Automatic domain mapping
- N-dimensional fitting
- N-dimensional evaluation
- Cartesian-grid evaluation
- Truncation support
- Callable interface
PadeApproximation
Represents a rational approximation
f(x) ≈ P(x) / Q(x)
Common Properties
Mathematical properties
Numerator, denominator, poles, and zeros of the rational approximation.
p.num
p.den
p.zeros
p.poles
Stored metadata
Optional information associated with the approximation.
p.max_error
p.domain
Convenience predicates
Check whether optional metadata is available.
p.has_error_estimate
p.has_domain
Features
- Classical Padé approximation
- Rational least-squares fitting
- Pole and zero analysis
- Domain metadata
- Optional error estimates
Utility Functions
ApproxKit provides utility functions for node generation, degree selection, and domain transformations.
Chebyshev Nodes (Roots of Tₙ)
from approxkit import chebyshev_nodes
x = chebyshev_nodes(16)
These are the roots of the Chebyshev polynomial of the first kind and are commonly used for interpolation because they minimize Runge oscillations. Equivalent to NumPy's chebpts1().
Chebyshev-Lobatto Nodes
from approxkit import chebyshev_lobatto_nodes
x = chebyshev_lobatto_nodes(16)
These are the extrema of the Chebyshev polynomial of the first kind and include the endpoints -1 and 1.
Equivalent to NumPy's chebpts2().
Typical applications:
- Polynomial interpolation
- Spectral methods
- Numerical quadrature
- Minimax approximation algorithms
Automatic Degree Selection
ApproxKit can estimate an appropriate polynomial degree using Akaike's Information Criterion (AIC).
import numpy as np
from approxkit import (
chebfit1d,
select_degree_aic,
)
x = np.linspace(0, 10, 300)
y = np.sin(x**3 / 100) ** 2
degree = select_degree_aic(
x,
y,
)
p = chebfit1d(
x,
y,
deg=degree,
)
This is useful when the appropriate polynomial degree is not known in advance.
Interval Mapping
map_to_interval(x, a, b)
map_from_interval(x, a, b)
Convert values between physical domains and the Chebyshev interval [-1, 1].
Examples
1D Chebyshev Approximation
import numpy as np
from approxkit import ChebyshevND, chebfit_dct, chebvalnd
c = chebfit_dct(
np.exp,
n=9,
)
x = np.linspace(-1, 1, 100)
y = chebvalnd(c, x)
approx = ChebyshevND.fit_dct(
np.exp,
n=9,
)
y1 = approx(x)
approx2 = approx.truncate(5)
y2 = approx2(x)
2D Approximation
import numpy as np
from approxkit import ChebyshevND
approx = ChebyshevND.fit_dct(
lambda x, y: np.tanh(x + y),
n=(12, 12),
)
u = np.linspace(-1, 1, 50)
X, Y = np.meshgrid(
u,
u,
indexing="ij",
)
Z = approx(X, Y)
4D Least-Squares Fit
coef = chebfitnd(
(x1, x2, x3, x4),
values,
deg=[4, 4, 4, 4],
)
Padé Approximation
from approxkit import padefit
coeffs = [
1,
1,
1 / 2,
1 / 6,
1 / 24,
]
p = padefit(coeffs)
y = p(1.0)
Rational Least-Squares Approximation
import numpy as np
from approxkit import padefitlsq
p = padefitlsq(
np.exp,
m=3,
n=3,
a=0,
b=2,
)
Chebyshev Nodes
from approxkit import chebyshev_nodes
x = chebyshev_nodes(8)
Chebyshev-Lobatto Nodes
from approxkit import chebyshev_lobatto_nodes
x = chebyshev_lobatto_nodes(8)
Automatic Degree Selection
import numpy as np
from approxkit import (
chebfit1d,
select_degree_aic,
)
x = np.linspace(0, 10, 300)
y = np.sin(x**3 / 100) ** 2
deg = select_degree_aic(
x,
y,
)
p = chebfit1d(
x,
y,
deg=deg,
)
Interval Mapping
from approxkit import (
map_to_interval,
map_from_interval,
)
x = [-1, 0, 1]
y = map_to_interval(
x,
2,
4,
)
z = map_from_interval(
y,
2,
4,
)
Running Tests
import approxkit
approxkit.test()
or
pytest --pyargs approxkit
Development
git clone https://github.com/pbrod/approxkit.git
cd approxkit
pip install -e .
Install testing support:
pip install -e ".[test]"
Run tests:
pytest --pyargs approxkit
License
BSD 3-Clause License.
Author
Per A. Brodtkorb
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file approxkit-0.2.0.tar.gz.
File metadata
- Download URL: approxkit-0.2.0.tar.gz
- Upload date:
- Size: 33.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8bc6782bf2cd911bceb4bd5282cd30d70921af3c363287f99d11e7056d3f573
|
|
| MD5 |
63e196a8e357cb7b9355cf561255449c
|
|
| BLAKE2b-256 |
e59489910ca29ac7a2bcf9ed48b1ec9d01d1114db6a3f7243084725288983128
|
Provenance
The following attestation bundles were made for approxkit-0.2.0.tar.gz:
Publisher:
publish.yml on pbrod/approxkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
approxkit-0.2.0.tar.gz -
Subject digest:
f8bc6782bf2cd911bceb4bd5282cd30d70921af3c363287f99d11e7056d3f573 - Sigstore transparency entry: 2301395782
- Sigstore integration time:
-
Permalink:
pbrod/approxkit@09589a5e5fe7e28b1266be0ee155d16223125935 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/pbrod
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@09589a5e5fe7e28b1266be0ee155d16223125935 -
Trigger Event:
release
-
Statement type:
File details
Details for the file approxkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: approxkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca21e75fff3db03494382d446e2de164accbd61c7cedcf7bb4db2c41be012e89
|
|
| MD5 |
0d3b610f2f76f14512cc9f94629b8ea6
|
|
| BLAKE2b-256 |
d5b23ed0318d6d88582fc1c3c9d2f410361eb61fc0a8cd8a808c0ca24ee98dea
|
Provenance
The following attestation bundles were made for approxkit-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on pbrod/approxkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
approxkit-0.2.0-py3-none-any.whl -
Subject digest:
ca21e75fff3db03494382d446e2de164accbd61c7cedcf7bb4db2c41be012e89 - Sigstore transparency entry: 2301395946
- Sigstore integration time:
-
Permalink:
pbrod/approxkit@09589a5e5fe7e28b1266be0ee155d16223125935 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/pbrod
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@09589a5e5fe7e28b1266be0ee155d16223125935 -
Trigger Event:
release
-
Statement type: