Skip to content

API Reference

ChebyshevApproximation

Multi-dimensional Chebyshev approximation using barycentric interpolation.

Pre-computes barycentric weights for all dimensions at build time, enabling uniform O(N) evaluation complexity for every dimension. Supports analytical derivatives via spectral differentiation matrices.

Parameters:

Name Type Description Default
function callable

Function to approximate. Signature: f(point, data) -> float where point is a list of floats and data is arbitrary additional data (can be None).

required
num_dimensions int

Number of input dimensions.

required
domain list of (float, float)

Bounds [(lo, hi), ...] for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension.

required
max_derivative_order int

Maximum derivative order to support. Default is 2.

2

Examples:

>>> import math
>>> def f(x, _):
...     return math.sin(x[0]) + math.sin(x[1])
>>> cheb = ChebyshevApproximation(f, 2, [[-1, 1], [-1, 1]], [11, 11])
>>> cheb.build()
>>> cheb.vectorized_eval([0.5, 0.3], [0, 0])
0.7764...

nodes(num_dimensions, domain, n_nodes) staticmethod

Generate Chebyshev nodes without evaluating any function.

Use this to obtain the grid points, evaluate your function externally (e.g. on an HPC cluster), then pass the results to :meth:from_values.

Parameters:

Name Type Description Default
num_dimensions int

Number of dimensions.

required
domain list of (float, float)

Lower and upper bounds for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension.

required

Returns:

Type Description
dict

'nodes_per_dim' : list of 1-D arrays — Chebyshev nodes for each dimension, sorted ascending.

'full_grid' : 2-D array, shape (prod(n_nodes), num_dimensions) — Cartesian product of all nodes. Row order matches np.ndindex(*n_nodes) (C-order), so values.reshape(info['shape']) produces the correct tensor.

'shape' : tuple of int — expected shape of the tensor (== tuple(n_nodes)).

Examples:

>>> info = ChebyshevApproximation.nodes(1, [[-1, 1]], [5])
>>> info['shape']
(5,)
>>> info['full_grid'].shape
(5, 1)

build(verbose=True)

Evaluate the function at all node combinations and pre-compute weights.

Parameters:

Name Type Description Default
verbose bool

If True, print build progress. Default is True.

True

eval(point, derivative_order)

Evaluate using dimensional decomposition with barycentric interpolation.

Parameters:

Name Type Description Default
point list of float

Query point, one coordinate per dimension.

required
derivative_order list of int

Derivative order per dimension (0 = function value, 1 = first derivative, 2 = second derivative).

required

Returns:

Type Description
float

Interpolated value or derivative at the query point.

Raises:

Type Description
RuntimeError

If build() has not been called.

fast_eval(point, derivative_order)

Fast evaluation using pre-allocated cache (skips validation).

.. deprecated:: 0.3.0 Use :meth:vectorized_eval instead, which is ~150x faster via BLAS GEMV and requires no optional dependencies.

Parameters:

Name Type Description Default
point list of float

Query point.

required
derivative_order list of int

Derivative order per dimension.

required

Returns:

Type Description
float

Interpolated value or derivative.

vectorized_eval(point, derivative_order)

Fully vectorized evaluation using NumPy matrix operations.

Replaces the Python loop with BLAS matrix-vector products. For 5-D with 11 nodes: 5 BLAS calls instead of 16,105 Python iterations.

Parameters:

Name Type Description Default
point list of float

Query point, one coordinate per dimension.

required
derivative_order list of int

Derivative order per dimension.

required

Returns:

Type Description
float

Interpolated value or derivative.

Raises:

Type Description
RuntimeError

If build() has not been called.

vectorized_eval_batch(points, derivative_order)

Evaluate at multiple points.

Parameters:

Name Type Description Default
points ndarray

Points of shape (N, num_dimensions).

required
derivative_order list of int

Derivative order per dimension.

required

Returns:

Type Description
ndarray

Results of shape (N,).

vectorized_eval_multi(point, derivative_orders)

Evaluate multiple derivative orders at the same point, sharing weights.

Pre-computes normalized barycentric weights once per dimension and reuses them across all derivative orders. Computing price + 5 Greeks costs ~0.29 ms instead of 6 x 0.065 ms = 0.39 ms.

Parameters:

Name Type Description Default
point list of float

Query point.

required
derivative_orders list of list of int

Each inner list specifies derivative order per dimension.

required

Returns:

Type Description
list of float

One result per derivative order.

Raises:

Type Description
RuntimeError

If build() has not been called.

get_derivative_id(derivative_order)

Return derivative order as-is (for API compatibility).

error_estimate()

Estimate the supremum-norm interpolation error.

Computes Chebyshev expansion coefficients via DCT-II for each 1-D slice of the tensor, and returns the sum of per-dimension maximum last-coefficient magnitudes:

.. math::

\hat{E} = \sum_{d=1}^{D}
    \max_{\text{slices along } d} |c_{n_d - 1}|

This follows the ex ante error estimation from Ruiz & Zeron (2021), Section 3.4, adapted for Type I Chebyshev nodes.

Returns:

Type Description
float

Estimated maximum interpolation error (sup-norm).

Raises:

Type Description
RuntimeError

If build() has not been called.

__getstate__()

Return picklable state, excluding the original function and eval cache.

__setstate__(state)

Restore state and reconstruct the eval cache.

save(path)

Save the built interpolant to a file.

The original function is not saved — only the numerical data needed for evaluation. The saved file can be loaded with :meth:load without access to the original function.

Parameters:

Name Type Description Default
path str or path - like

Destination file path.

required

Raises:

Type Description
RuntimeError

If the interpolant has not been built yet.

load(path) classmethod

Load a previously saved interpolant from a file.

The loaded object can evaluate immediately; no rebuild is needed. The function attribute will be None. Assign a new function before calling build() again if a rebuild is desired.

Parameters:

Name Type Description Default
path str or path - like

Path to the saved file.

required

Returns:

Type Description
ChebyshevApproximation

The restored interpolant.

Warns:

Type Description
UserWarning

If the file was saved with a different PyChebyshev version.

.. warning::

This method uses :mod:pickle internally. Pickle can execute arbitrary code during deserialization. Only load files you trust.

from_values(tensor_values, num_dimensions, domain, n_nodes, max_derivative_order=2) classmethod

Create an interpolant from pre-computed function values.

The resulting object is fully functional: evaluation, derivatives, integration, rootfinding, algebra, extrusion/slicing, and serialization all work exactly as if build() had been called.

Parameters:

Name Type Description Default
tensor_values ndarray

Function values on the Chebyshev grid. Shape must equal tuple(n_nodes). Entry tensor_values[i0, i1, ...] corresponds to the function evaluated at (nodes[0][i0], nodes[1][i1], ...), where nodes are the arrays returned by :meth:nodes.

required
num_dimensions int

Number of dimensions.

required
domain list of (float, float)

Lower and upper bounds for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension.

required
max_derivative_order int

Maximum derivative order (default 2).

2

Returns:

Type Description
ChebyshevApproximation

A fully built interpolant with function=None.

Raises:

Type Description
ValueError

If tensor_values shape does not match n_nodes, contains NaN or Inf, or if dimension parameters are inconsistent.

Examples:

>>> import math
>>> info = ChebyshevApproximation.nodes(1, [[0, 3.15]], [20])
>>> vals = np.sin(info['full_grid'][:, 0]).reshape(info['shape'])
>>> cheb = ChebyshevApproximation.from_values(vals, 1, [[0, 3.15]], [20])
>>> abs(cheb.vectorized_eval([1.0], [0]) - math.sin(1.0)) < 1e-10
True

extrude(params)

Add new dimensions where the function is constant.

The extruded interpolant evaluates identically to the original regardless of the new coordinate(s), because Chebyshev basis functions form a partition of unity: the barycentric weights sum to 1, so replicating tensor values along a new axis produces the same result for any coordinate in the new domain.

Parameters:

Name Type Description Default
params tuple or list of tuples

Single (dim_index, (lo, hi), n_nodes) or a list of such tuples. dim_index is the position in the output space (0-indexed). n_nodes must be >= 2 and lo < hi.

required

Returns:

Type Description
ChebyshevApproximation

A new, higher-dimensional interpolant (already built). The result has function=None and build_time=0.0.

Raises:

Type Description
RuntimeError

If the interpolant has not been built yet.

TypeError

If dim_index is not an integer.

ValueError

If dim_index is out of range, duplicated, lo >= hi, or n_nodes < 2.

slice(params)

Fix one or more dimensions at given values, reducing dimensionality.

Contracts the tensor along each sliced dimension using the barycentric interpolation formula: for each sliced axis the normalized weight vector w_i / (x - x_i) / sum(w_j / (x - x_j)) is contracted with the tensor via np.tensordot. When the slice value coincides with a Chebyshev node (within 1e-14), the contraction reduces to an exact np.take (fast path).

Parameters:

Name Type Description Default
params tuple or list of tuples

Single (dim_index, value) or a list of such tuples. value must lie within the domain for that dimension.

required

Returns:

Type Description
ChebyshevApproximation

A new, lower-dimensional interpolant (already built). The result has function=None and build_time=0.0.

Raises:

Type Description
RuntimeError

If the interpolant has not been built yet.

TypeError

If dim_index is not an integer.

ValueError

If a slice value is outside the domain, if slicing all dimensions, or if dim_index is out of range or duplicated.

integrate(dims=None, bounds=None)

Integrate the interpolant over one or more dimensions.

Uses Fejér-1 quadrature weights (Waldvogel 2006) at Chebyshev Type I nodes, computed in O(n log n) via DCT-III. For multi-D tensors, each dimension is contracted via np.tensordot.

Parameters:

Name Type Description Default
dims int, list of int, or None

Dimensions to integrate out. If None, integrates over all dimensions and returns a scalar.

None
bounds tuple, list of tuple/None, or None

Sub-interval bounds for integration. None (default) integrates over the full domain of each dimension. A single tuple (lo, hi) applies to a single dims entry. A list of tuples/None provides per-dimension bounds with positional correspondence to dims.

None

Returns:

Type Description
float or ChebyshevApproximation

If all dimensions are integrated, returns the scalar integral. Otherwise returns a lower-dimensional interpolant.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If any dimension index is out of range or duplicated, or if bounds are outside the domain.

References

Waldvogel (2006), "Fast Construction of the Fejér and Clenshaw–Curtis Quadrature Rules", BIT Numer. Math. 46(2):195–202.

roots(dim=None, fixed=None)

Find all roots of the interpolant along a specified dimension.

Uses the colleague matrix eigenvalue method (Good 1961) via numpy.polynomial.chebyshev.chebroots. For multi-D interpolants, all dimensions except the target must be fixed at specific values (the interpolant is sliced to 1-D first).

Parameters:

Name Type Description Default
dim int or None

Dimension along which to find roots. For 1-D interpolants, defaults to 0.

None
fixed dict or None

For multi-D interpolants, a dict {dim_index: value} for all dimensions except dim.

None

Returns:

Type Description
ndarray

Sorted array of root locations in the physical domain.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If dim / fixed validation fails or values are out of domain.

References

Good (1961), "The colleague matrix", Quarterly J. Math. 12(1):61–68. Trefethen (2013), "Approximation Theory and Approximation Practice", SIAM, Chapter 18.

minimize(dim=None, fixed=None)

Find the minimum value of the interpolant along a dimension.

Computes derivative roots to locate critical points, then evaluates the interpolant at all critical points and domain endpoints.

Parameters:

Name Type Description Default
dim int or None

Dimension along which to minimize. Defaults to 0 for 1-D.

None
fixed dict or None

For multi-D, dict {dim_index: value} for all other dims.

None

Returns:

Type Description
(value, location) : (float, float)

The minimum value and its coordinate in the target dimension.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If dim / fixed validation fails.

References

Trefethen (2013), "Approximation Theory and Approximation Practice", SIAM, Chapter 18.

maximize(dim=None, fixed=None)

Find the maximum value of the interpolant along a dimension.

Computes derivative roots to locate critical points, then evaluates the interpolant at all critical points and domain endpoints.

Parameters:

Name Type Description Default
dim int or None

Dimension along which to maximize. Defaults to 0 for 1-D.

None
fixed dict or None

For multi-D, dict {dim_index: value} for all other dims.

None

Returns:

Type Description
(value, location) : (float, float)

The maximum value and its coordinate in the target dimension.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If dim / fixed validation fails.

References

Trefethen (2013), "Approximation Theory and Approximation Practice", SIAM, Chapter 18.

ChebyshevSlider

Chebyshev Sliding approximation for high-dimensional functions.

Decomposes f(x_1, ..., x_n) into a sum of low-dimensional Chebyshev interpolants (slides) around a pivot point z:

f(x) ≈ f(z) + Σ_i [s_i(x_group_i) - f(z)]

where each slide s_i is a ChebyshevApproximation built on a subset of dimensions with the remaining dimensions fixed at z.

This trades accuracy for dramatically reduced build cost: instead of evaluating f at n_1 × n_2 × ... × n_d grid points (exponential), the slider evaluates at n_1 × n_2 + n_3 × n_4 + ... (sum of products within each group).

Parameters:

Name Type Description Default
function callable

Function to approximate. Signature: f(point, data) -> float where point is a list of floats and data is arbitrary additional data (can be None).

required
num_dimensions int

Total number of input dimensions.

required
domain list of (float, float)

Bounds [lo, hi] for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension.

required
partition list of list of int

Grouping of dimension indices into slides. Each dimension must appear in exactly one group. E.g. [[0,1,2], [3,4]] creates a 3D slide for dims 0,1,2 and a 2D slide for dims 3,4.

required
pivot_point list of float

Reference point z around which slides are built.

required
max_derivative_order int

Maximum derivative order to pre-compute (default 2).

2

Examples:

>>> import math
>>> def f(x, _):
...     return math.sin(x[0]) + math.sin(x[1]) + math.sin(x[2])
>>> slider = ChebyshevSlider(
...     f, 3, [[-1,1], [-1,1], [-1,1]], [11,11,11],
...     partition=[[0], [1], [2]],
...     pivot_point=[0.0, 0.0, 0.0],
... )
>>> slider.build(verbose=False)
>>> round(slider.eval([0.5, 0.3, 0.1], [0,0,0]), 4)
0.8764

total_build_evals property

Total number of function evaluations used during build.

build(verbose=True)

Build all slides by evaluating the function at slide-specific grids.

For each slide, dimensions outside the slide group are fixed at their pivot values.

Parameters:

Name Type Description Default
verbose bool

If True, print build progress. Default is True.

True

eval(point, derivative_order)

Evaluate the slider approximation at a point.

Uses Equation 7.5 from Ruiz & Zeron (2021): f(x) ≈ f(z) + Σ_i [s_i(x_i) - f(z)]

For derivatives, only the slide containing that dimension contributes.

Parameters:

Name Type Description Default
point list of float

Evaluation point in the full n-dimensional space.

required
derivative_order list of int

Derivative order for each dimension (0 = function value).

required

Returns:

Type Description
float

Approximated function value or derivative.

eval_multi(point, derivative_orders)

Evaluate slider at multiple derivative orders for the same point.

Parameters:

Name Type Description Default
point list of float

Evaluation point in the full n-dimensional space.

required
derivative_orders list of list of int

Each inner list specifies derivative order per dimension.

required

Returns:

Type Description
list of float

Results for each derivative order.

error_estimate()

Estimate the sliding approximation error.

Returns the sum of per-slide Chebyshev error estimates. Each slide's error is estimated independently using the Chebyshev coefficient method from Ruiz & Zeron (2021), Section 3.4.

Note: This captures per-slide interpolation error only. Cross-group interaction error (inherent to the sliding decomposition) is not included.

Returns:

Type Description
float

Estimated interpolation error (per-slide sum).

Raises:

Type Description
RuntimeError

If build() has not been called.

__getstate__()

Return picklable state, excluding the original function.

__setstate__(state)

Restore state from a pickled dict.

save(path)

Save the built slider to a file.

The original function is not saved — only the numerical data needed for evaluation. The saved file can be loaded with :meth:load without access to the original function.

Parameters:

Name Type Description Default
path str or path - like

Destination file path.

required

Raises:

Type Description
RuntimeError

If the slider has not been built yet.

load(path) classmethod

Load a previously saved slider from a file.

The loaded object can evaluate immediately; no rebuild is needed. The function attribute will be None. Assign a new function before calling build() again if a rebuild is desired.

Parameters:

Name Type Description Default
path str or path - like

Path to the saved file.

required

Returns:

Type Description
ChebyshevSlider

The restored slider.

Warns:

Type Description
UserWarning

If the file was saved with a different PyChebyshev version.

.. warning::

This method uses :mod:pickle internally. Pickle can execute arbitrary code during deserialization. Only load files you trust.

extrude(params)

Add new dimensions where the function is constant.

Each new dimension becomes its own single-dim slide group with tensor_values = np.full(n, pivot_value), so that s_new(x) - pivot_value = 0 for all x (no contribution to the sliding sum). This is the partition-of-unity property: the barycentric weights sum to 1, so a constant tensor produces the same value for any coordinate.

Existing slide groups have their dimension indices remapped to account for the inserted dimensions.

Parameters:

Name Type Description Default
params tuple or list of tuples

Single (dim_index, (lo, hi), n_nodes) or a list of such tuples. dim_index is the position in the output space (0-indexed). n_nodes must be >= 2 and lo < hi.

required

Returns:

Type Description
ChebyshevSlider

A new, higher-dimensional slider (already built). The result has function=None.

Raises:

Type Description
RuntimeError

If the slider has not been built yet.

TypeError

If dim_index is not an integer.

ValueError

If dim_index is out of range, duplicated, lo >= hi, or n_nodes < 2.

slice(params)

Fix one or more dimensions at given values, reducing dimensionality.

Two cases per sliced dimension:

  • Multi-dim group: The slide's ChebyshevApproximation is sliced at the local dimension index via barycentric contraction. When the slice value coincides with a Chebyshev node (within 1e-14), the contraction reduces to an exact np.take (fast path). The dimension is removed from the group.
  • Single-dim group: The slide is evaluated at the value, giving a constant s_val. The shift delta = s_val - pivot_value is absorbed into pivot_value and each remaining slide's tensor_values, and the group is removed entirely.

Remaining dimension indices in all groups are remapped downward to stay contiguous.

Parameters:

Name Type Description Default
params tuple or list of tuples

Single (dim_index, value) or a list of such tuples. value must lie within the domain for that dimension.

required

Returns:

Type Description
ChebyshevSlider

A new, lower-dimensional slider (already built). The result has function=None.

Raises:

Type Description
RuntimeError

If the slider has not been built yet.

TypeError

If dim_index is not an integer.

ValueError

If a slice value is outside the domain, if slicing all dimensions, or if dim_index is out of range or duplicated.

ChebyshevSpline

Piecewise Chebyshev interpolation with user-specified knots.

Partitions the domain into sub-intervals at interior knots and builds an independent :class:ChebyshevApproximation on each piece. Query points are routed to the appropriate piece for evaluation.

This is the correct approach when the target function has known singularities (kinks, discontinuities) at specific locations: place knots at those locations so that each piece is smooth, restoring spectral convergence.

Parameters:

Name Type Description Default
function callable

Function to approximate. Signature: f(point, data) -> float where point is a list of floats and data is arbitrary additional data (can be None).

required
num_dimensions int

Number of input dimensions.

required
domain list of (float, float)

Bounds [lo, hi] for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension per piece.

required
knots list of list of float

Interior knots for each dimension. Each sub-list must be sorted and every knot must lie strictly inside the corresponding domain interval. Use an empty list [] for dimensions with no knots.

required
max_derivative_order int

Maximum derivative order to pre-compute (default 2).

2

Examples:

>>> import math
>>> def f(x, _):
...     return abs(x[0])
>>> sp = ChebyshevSpline(f, 1, [[-1, 1]], [15], [[0.0]])
>>> sp.build(verbose=False)
>>> round(sp.eval([0.5], [0]), 10)
0.5
>>> round(sp.eval([-0.3], [0]), 10)
0.3

num_pieces property

Total number of pieces (Cartesian product of per-dimension intervals).

total_build_evals property

Total number of function evaluations used during build.

build_time property

Wall-clock time (seconds) for the most recent build() call.

build(verbose=True)

Build all pieces by evaluating the function on each sub-domain.

Each piece is an independent :class:ChebyshevApproximation built on the Cartesian product of per-dimension sub-intervals.

Parameters:

Name Type Description Default
verbose bool

If True, print build progress. Default is True.

True

eval(point, derivative_order)

Evaluate the spline approximation at a point.

Routes the query to the piece whose sub-domain contains point and delegates to its :meth:~ChebyshevApproximation.vectorized_eval.

Parameters:

Name Type Description Default
point list of float

Evaluation point in the full domain.

required
derivative_order list of int

Derivative order for each dimension (0 = function value).

required

Returns:

Type Description
float

Approximated function value or derivative.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If the point is at a knot and a non-zero derivative is requested.

eval_multi(point, derivative_orders)

Evaluate multiple derivative orders at one point, sharing weights.

Routes to a single piece and delegates to its :meth:~ChebyshevApproximation.vectorized_eval_multi so that barycentric weight computation is shared across all requested derivative orders.

Parameters:

Name Type Description Default
point list of float

Evaluation point in the full domain.

required
derivative_orders list of list of int

Each inner list specifies derivative order per dimension.

required

Returns:

Type Description
list of float

One result per derivative order.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If the point is at a knot and a non-zero derivative is requested.

eval_batch(points, derivative_order)

Evaluate at multiple points, grouping by piece for efficiency.

Vectorises the piece-routing step using np.searchsorted and evaluates each piece's batch via :meth:~ChebyshevApproximation.vectorized_eval_batch.

Parameters:

Name Type Description Default
points ndarray of shape (N, num_dimensions)

Evaluation points.

required
derivative_order list of int

Derivative order for each dimension.

required

Returns:

Type Description
ndarray of shape (N,)

Approximated values or derivatives at each point.

Raises:

Type Description
RuntimeError

If build() has not been called.

error_estimate()

Estimate the supremum-norm interpolation error.

Returns the maximum error estimate across all pieces. Since pieces cover disjoint sub-domains, the interpolation error at any point is bounded by the error of the piece containing that point. The worst-case error is therefore the maximum over all pieces (not the sum, unlike :class:ChebyshevSlider where all slides contribute to every point).

Returns:

Type Description
float

Estimated maximum interpolation error (sup-norm).

Raises:

Type Description
RuntimeError

If build() has not been called.

__getstate__()

Return picklable state, excluding the original function.

__setstate__(state)

Restore state from a pickled dict.

save(path)

Save the built spline to a file.

The original function is not saved -- only the numerical data needed for evaluation. The saved file can be loaded with :meth:load without access to the original function.

Parameters:

Name Type Description Default
path str or path - like

Destination file path.

required

Raises:

Type Description
RuntimeError

If the spline has not been built yet.

load(path) classmethod

Load a previously saved spline from a file.

The loaded object can evaluate immediately; no rebuild is needed. The function attribute will be None. Assign a new function before calling build() again if a rebuild is desired.

Parameters:

Name Type Description Default
path str or path - like

Path to the saved file.

required

Returns:

Type Description
ChebyshevSpline

The restored spline.

Warns:

Type Description
UserWarning

If the file was saved with a different PyChebyshev version.

.. warning::

This method uses :mod:pickle internally. Pickle can execute arbitrary code during deserialization. Only load files you trust.

nodes(num_dimensions, domain, n_nodes, knots) staticmethod

Generate Chebyshev nodes for every piece without evaluating any function.

Use this to obtain the per-piece grid points, evaluate your function externally, then pass the results to :meth:from_values.

Parameters:

Name Type Description Default
num_dimensions int

Number of dimensions.

required
domain list of (float, float)

Lower and upper bounds for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension per piece.

required
knots list of list of float

Knot positions for each dimension (may be empty).

required

Returns:

Type Description
dict

'pieces' : list of dicts, one per piece in C-order (np.ndindex(*piece_shape)). Each dict contains:

  • 'piece_index' : tuple — multi-index of this piece
  • 'sub_domain' : list of (float, float) — bounds for this piece
  • 'nodes_per_dim' : list of 1-D arrays
  • 'full_grid' : 2-D array, shape (prod(n_nodes), num_dimensions)
  • 'shape' : tuple of int

'num_pieces' : int — total number of pieces.

'piece_shape' : tuple of int — per-dimension piece counts.

Examples:

>>> info = ChebyshevSpline.nodes(1, [[-1, 1]], [10], [[0.0]])
>>> info['num_pieces']
2
>>> info['pieces'][0]['sub_domain']
[(-1, 0.0)]

from_values(piece_values, num_dimensions, domain, n_nodes, knots, max_derivative_order=2) classmethod

Create a spline from pre-computed function values on each piece.

The resulting object is fully functional: evaluation, derivatives, integration, rootfinding, algebra, extrusion/slicing, and serialization all work exactly as if build() had been called.

Parameters:

Name Type Description Default
piece_values list of numpy.ndarray

Function values for each piece. Length must equal the total number of pieces (prod of per-dimension piece counts). Order follows np.ndindex(*piece_shape) (C-order), matching the 'pieces' list returned by :meth:nodes. Each array must have shape tuple(n_nodes).

required
num_dimensions int

Number of dimensions.

required
domain list of (float, float)

Lower and upper bounds for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension per piece.

required
knots list of list of float

Knot positions for each dimension (may be empty).

required
max_derivative_order int

Maximum derivative order (default 2).

2

Returns:

Type Description
ChebyshevSpline

A fully built spline with function=None.

Raises:

Type Description
ValueError

If the number of pieces does not match, or any piece has the wrong shape or contains NaN/Inf.

extrude(params)

Add new dimensions where the function is constant.

Each piece is extruded independently via :meth:ChebyshevApproximation.extrude. The extruded spline evaluates identically to the original regardless of the new coordinate(s), because Chebyshev basis functions form a partition of unity. The new dimension gets knots=[] and a single interval (lo, hi).

Parameters:

Name Type Description Default
params tuple or list of tuples

Single (dim_index, (lo, hi), n_nodes) or a list of such tuples. dim_index is the position in the output space (0-indexed). n_nodes must be >= 2 and lo < hi.

required

Returns:

Type Description
ChebyshevSpline

A new, higher-dimensional spline (already built). The result has function=None and build_time=0.0.

Raises:

Type Description
RuntimeError

If the spline has not been built yet.

TypeError

If dim_index is not an integer.

ValueError

If dim_index is out of range, duplicated, lo >= hi, or n_nodes < 2.

slice(params)

Fix one or more dimensions at given values, reducing dimensionality.

For each sliced dimension, only the pieces whose interval contains the slice value survive. Each surviving piece is then sliced via :meth:ChebyshevApproximation.slice, which contracts the tensor along that axis using the barycentric interpolation formula. When the slice value coincides with a Chebyshev node (within 1e-14), the contraction reduces to an exact np.take (fast path).

Parameters:

Name Type Description Default
params tuple or list of tuples

Single (dim_index, value) or a list of such tuples. value must lie within the domain for that dimension.

required

Returns:

Type Description
ChebyshevSpline

A new, lower-dimensional spline (already built). The result has function=None and build_time=0.0.

Raises:

Type Description
RuntimeError

If the spline has not been built yet.

TypeError

If dim_index is not an integer.

ValueError

If a slice value is outside the domain, if slicing all dimensions, or if dim_index is out of range or duplicated.

integrate(dims=None, bounds=None)

Integrate the spline over one or more dimensions.

For full integration, sums the integrals of each piece (pieces cover disjoint sub-domains). For partial integration, pieces along the integrated dimension are summed and the result is a lower-dimensional spline.

Parameters:

Name Type Description Default
dims int, list of int, or None

Dimensions to integrate out. If None, integrates over all dimensions and returns a scalar.

None
bounds tuple, list of tuple/None, or None

Sub-interval bounds for integration. None (default) integrates over the full domain of each dimension. A single tuple (lo, hi) applies to a single dims entry. A list of tuples/None provides per-dimension bounds with positional correspondence to dims.

None

Returns:

Type Description
float or ChebyshevSpline

Scalar for full integration; lower-dimensional spline for partial integration.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If any dimension index is out of range or duplicated, or if bounds are outside the domain.

roots(dim=None, fixed=None)

Find all roots of the spline along a specified dimension.

Slices the spline to 1-D, then finds roots in each piece and merges the results.

Parameters:

Name Type Description Default
dim int or None

Dimension along which to find roots.

None
fixed dict or None

For multi-D, dict {dim_index: value} for all other dims.

None

Returns:

Type Description
ndarray

Sorted array of root locations in the physical domain.

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If dim / fixed validation fails.

minimize(dim=None, fixed=None)

Find the minimum value of the spline along a dimension.

Parameters:

Name Type Description Default
dim int or None

Dimension along which to minimize.

None
fixed dict or None

For multi-D, dict {dim_index: value} for all other dims.

None

Returns:

Type Description
(value, location) : (float, float)

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If dim / fixed validation fails.

maximize(dim=None, fixed=None)

Find the maximum value of the spline along a dimension.

Parameters:

Name Type Description Default
dim int or None

Dimension along which to maximize.

None
fixed dict or None

For multi-D, dict {dim_index: value} for all other dims.

None

Returns:

Type Description
(value, location) : (float, float)

Raises:

Type Description
RuntimeError

If build() has not been called.

ValueError

If dim / fixed validation fails.

ChebyshevTT

Chebyshev interpolation in Tensor Train format.

For functions of 5+ dimensions where full tensor interpolation is infeasible. Uses TT-Cross to build from O(d * n * r^2) function evaluations instead of O(n^d), then evaluates via TT inner product.

Parameters:

Name Type Description Default
function callable

Function to approximate. Signature: f(point, data) -> float where point is a list of floats and data is arbitrary additional data (can be None).

required
num_dimensions int

Number of input dimensions.

required
domain list of (float, float)

Bounds [(lo, hi), ...] for each dimension.

required
n_nodes list of int

Number of Chebyshev nodes per dimension.

required
max_rank int

Maximum TT rank. Higher = more accurate, more expensive. Default is 10.

10
tolerance float

Convergence tolerance for TT-Cross. Default is 1e-6.

1e-06
max_sweeps int

Maximum number of TT-Cross sweeps. Default is 10.

10

Examples:

>>> import math
>>> def f(x, _):
...     return math.sin(x[0]) + math.sin(x[1]) + math.sin(x[2])
>>> tt = ChebyshevTT(f, 3, [[-1, 1], [-1, 1], [-1, 1]], [11, 11, 11])
>>> tt.build(verbose=False)
>>> tt.eval([0.5, 0.3, 0.1])
0.8764...

tt_ranks property

TT ranks [1, r_1, r_2, ..., r_{d-1}, 1].

Returns:

Type Description
list of int

The TT rank vector. Only available after :meth:build.

Raises:

Type Description
RuntimeError

If build() has not been called.

compression_ratio property

Ratio of full tensor elements to TT storage elements.

Returns:

Type Description
float

Compression ratio (> 1 means TT is more compact).

Raises:

Type Description
RuntimeError

If build() has not been called.

total_build_evals property

Total number of function evaluations used during build.

Returns:

Type Description
int

Number of function evaluations. Only meaningful after :meth:build.

build(verbose=True, seed=None, method='cross')

Build TT approximation and convert to Chebyshev coefficient cores.

The build process has three stages:

  1. Generate Chebyshev grids. Compute Type I Chebyshev nodes in each dimension, scaled to the specified domain.
  2. Build value cores. Either TT-Cross (evaluating at \(O(d \cdot n \cdot r^2)\) strategically selected points) or TT-SVD (evaluating the full \(O(n^d)\) tensor, then decomposing via sequential SVD).
  3. Convert to coefficient cores. Apply DCT-II along the node axis of each core to convert from function values at Chebyshev nodes to Chebyshev expansion coefficients. This enables evaluation at arbitrary (non-grid) points via the Chebyshev polynomial inner product.

Parameters:

Name Type Description Default
verbose bool

If True, print build progress. Default is True.

True
seed int or None

Random seed for TT-Cross initialization. Default is None. Ignored when method='svd'.

None
method ``'cross'`` or ``'svd'``

Build algorithm. 'cross' (default) uses TT-Cross to evaluate the function at \(O(d \cdot n \cdot r^2)\) strategically selected points. 'svd' builds the full tensor and decomposes via truncated SVD -- only feasible for moderate dimensions (\(d \leq 6\)) but useful for validation.

'cross'

eval(point)

Evaluate at a single point via TT inner product.

Computes the Chebyshev interpolant value at an arbitrary point by contracting the pre-computed coefficient cores with Chebyshev polynomial values. For each dimension \(k\):

  1. Scale the query coordinate to \([-1, 1]\).
  2. Evaluate all Chebyshev polynomials \(T_0, \ldots, T_{n_k-1}\).
  3. Contract with the coefficient core: \(v = \sum_j q_j \cdot \text{core}[:, j, :]\)

The chain of contractions reduces to a scalar. Cost: \(O(d \cdot n \cdot r^2)\) per point.

Parameters:

Name Type Description Default
point list of float

Query point, one coordinate per dimension.

required

Returns:

Type Description
float

Interpolated value at the query point.

Raises:

Type Description
RuntimeError

If build() has not been called.

eval_batch(points)

Evaluate at multiple points simultaneously.

Vectorizes the TT inner product over all N points using np.einsum for batched matrix contractions. For each dimension, all N polynomial vectors are contracted with the coefficient core in a single einsum call, then all N chain multiplications proceed in parallel. Typical speedup is 15--20x over calling :meth:eval in a loop.

Parameters:

Name Type Description Default
points ndarray of shape (N, num_dimensions)

Query points.

required

Returns:

Type Description
ndarray of shape (N,)

Interpolated values at each query point.

Raises:

Type Description
RuntimeError

If build() has not been called.

eval_multi(point, derivative_orders)

Evaluate with finite-difference derivatives at a single point.

Uses central finite differences. The first entry in derivative_orders is typically [0, 0, ..., 0] for the function value; subsequent entries specify derivative orders per dimension.

Parameters:

Name Type Description Default
point list of float

Evaluation point in the full n-dimensional space.

required
derivative_orders list of list of int

Each inner list specifies derivative order per dimension. Supports 0 (value), 1 (first derivative), and 2 (second derivative).

required

Returns:

Type Description
list of float

One result per derivative order specification.

Raises:

Type Description
RuntimeError

If build() has not been called.

error_estimate()

Estimate interpolation error from Chebyshev coefficient cores.

For each dimension d, takes the maximum magnitude of the last Chebyshev coefficient across all "rows" and "columns" of the core (i.e., max over left-rank and right-rank indices of |core[:, -1, :]|). Returns the sum across dimensions.

This is an approximate analog of the ex ante error estimation from Ruiz & Zeron (2021), Section 3.4, adapted for TT format.

Returns:

Type Description
float

Estimated interpolation error.

Raises:

Type Description
RuntimeError

If build() has not been called.

__getstate__()

Return picklable state, excluding the original function.

__setstate__(state)

Restore state from a pickled dict.

save(path)

Save the built TT interpolant to a file.

The original function is not saved -- only the numerical data needed for evaluation. The saved file can be loaded with :meth:load without access to the original function.

Parameters:

Name Type Description Default
path str or path - like

Destination file path.

required

Raises:

Type Description
RuntimeError

If build() has not been called.

load(path) classmethod

Load a previously saved TT interpolant from a file.

The loaded object can evaluate immediately; no rebuild is needed. The function attribute will be None. Assign a new function before calling build() again if a rebuild is desired.

Parameters:

Name Type Description Default
path str or path - like

Path to the saved file.

required

Returns:

Type Description
ChebyshevTT

The restored TT interpolant.

Warns:

Type Description
UserWarning

If the file was saved with a different PyChebyshev version.

.. warning::

This method uses :mod:pickle internally. Pickle can execute arbitrary code during deserialization. Only load files you trust.

Module Functions

Compute barycentric weights for given nodes.

Parameters:

Name Type Description Default
nodes ndarray

Interpolation nodes of shape (n,).

required

Returns:

Type Description
ndarray

Barycentric weights w_i = 1 / prod_{j!=i} (x_i - x_j).

Compute spectral differentiation matrix for barycentric interpolation.

Based on Berrut & Trefethen (2004), Section 9.3.

Parameters:

Name Type Description Default
nodes ndarray

Interpolation nodes of shape (n,).

required
weights ndarray

Barycentric weights of shape (n,).

required

Returns:

Type Description
ndarray

Differentiation matrix D of shape (n, n) such that D @ f gives derivative values at nodes.

Evaluate barycentric interpolation at a single point.

Parameters:

Name Type Description Default
x float

Evaluation point.

required
nodes ndarray

Interpolation nodes.

required
values ndarray

Function values at nodes.

required
weights ndarray

Barycentric weights.

required
skip_check bool

If True, skip node coincidence check (faster but may divide by zero).

False

Returns:

Type Description
float

Interpolated value p(x).