Spline Interpolation#
The TensorSpline class is the core spline-based interpolator.
Users can construct a spline model for their N-dimensional data (with custom boundary extension modes, spline degrees, etc.)
and then evaluate the model at arbitrary coordinates.
TensorSpline is also available as the stable convenience import
from splineops import TensorSpline. Construction grids must be uniform;
“arbitrary coordinates” describes evaluation locations, not nonuniform input
sampling.
Construction templates can refit compatible sample arrays with with_data
or consume explicit cardinal coefficients with with_coefficients. Query
plans retain only fixed-coordinate geometry and can therefore evaluate either
kind of compatible spline without merging TensorSpline into another
module. Keys cubic convolution and cubic O-MOMS also have independent
published-formula references in the stability-soak suite.
- class splineops.spline_interpolation.tensor_spline.TensorSpline(data: NDArray, coordinates: NDArray | Sequence[NDArray], bases: SplineBasis | str | Sequence[SplineBasis | str], modes: ExtensionMode | str | Sequence[ExtensionMode | str])#
Bases:
objectA class to handle a tensor spline for multi-dimensional interpolation and approximation.
This class handles N-dimensional data and allows interpolation with a variety of spline bases and extension modes. It supports different bases/modes along each axis.
- Parameters:
data (ndarray) – The input N-dimensional array to be interpolated.
coordinates (ndarray) – The coordinates corresponding to the input data.
bases (str or sequence of str) –
The spline bases used for interpolation. It can be a single basis applied across all axes or a sequence of bases for each axis.
The following spline bases are available:
”bspline0”, “bspline0-sym”: Zero-degree or piecewise constant B-splines and symmetric zero-degree or piecewise constant B-splines.
”bspline1” to “bspline9”: First to ninth-degree B-splines.
”omoms0”, “omoms0-sym”: Zero-degree O-MOMS splines and symmetric zero-degree O-MOMS splines.
”omoms1” to “omoms5”: First to fifth-degree O-MOMS splines.
”omoms2-sym”, “omoms4-sym”: Symmetric second and fourth-degree O-MOMS splines.
”nearest”, “nearest-sym”: Nearest neighbor interpolation.
”linear”: Linear interpolation.
”keys”: Keys spline interpolation.
modes (str or sequence of str) –
Signal extension modes used to handle boundaries. It can be a single mode applied across all axes or a sequence of modes for each axis.
The following extension modes are available for handling boundaries:
”zero” (0 0 0 0 | a b c d | 0 0 0 0) The input is extended by filling all values beyond the boundary with zeroes.
”mirror” (d c b | a b c d | c b a) The input is extended by reflecting around the center of the data points adjacent to the border.
”periodic”(d c b | a b c d | a b c) The signal is wrapped around cyclically.
Example
1D Interpolation:
Here’s an example to illustrate 1-dimensional interpolation using the TensorSpline class.
>>> import numpy as np >>> from splineops import TensorSpline >>> data = np.array([1.0, 2.0, 3.0, 4.0]) >>> coordinates = np.linspace(0, data.size - 1, data.size) >>> bases = "linear" # Linear interpolation >>> modes = "mirror" # Mirror extension mode >>> tensor_spline = TensorSpline(data=data, coordinates=coordinates, bases=bases, modes=modes)
To interpolate the data at a new point:
>>> eval_coords = np.array([1.5]) >>> data_eval = tensor_spline(coordinates=eval_coords, grid=False) >>> print(data_eval) [2.5]
In this example, the interpolated value at x = 1.5 is 2.5, which is the midpoint between data[1] (2.0) and data[2] (3.0).
2D Interpolation:
Here’s a simple example to illustrate 2-dimensional interpolation using the TensorSpline class.
>>> a = np.arange(12.).reshape((4, 3)) >>> a array([[ 0., 1., 2.], [ 3., 4., 5.], [ 6., 7., 8.], [ 9., 10., 11.]]) >>> xx = np.linspace(0, a.shape[0] - 1, a.shape[0]) >>> yy = np.linspace(0, a.shape[1] - 1, a.shape[1]) >>> coordinates = xx, yy >>> bases = ["bspline1", "bspline1"] # Linear interpolation along both axes >>> modes = ["mirror", "mirror"] # Mirror extension mode handling along both axes >>> tensor_spline = TensorSpline(data=a, coordinates=coordinates, bases=bases, modes=modes)
To interpolate the array a at coordinates (0.5, 0.5) and (2, 1):
>>> eval_coords = np.array([[0.5, 2], [0.5, 1]]) >>> data_eval_pts = tensor_spline(coordinates=eval_coords, grid=False) >>> print(data_eval_pts) [2. 7.]
In this example, the interpolated value at (0.5, 0.5) is 2.0, and the value at (2, 1) is 7.0.
- __init__(data: NDArray, coordinates: NDArray | Sequence[NDArray], bases: SplineBasis | str | Sequence[SplineBasis | str], modes: ExtensionMode | str | Sequence[ExtensionMode | str]) None#
Initialize the TensorSpline object with the given data, coordinates, bases, and modes.
- Parameters:
data (ndarray) – The input N-dimensional array to be interpolated.
coordinates (ndarray) – The coordinates corresponding to the input data.
bases (str or sequence of str) – The spline bases used for interpolation. It can be a single basis applied across all axes or a sequence of bases for each axis.
modes (str or sequence of str) – Signal extension modes used to handle boundaries. It can be a single mode applied across all axes or a sequence of modes for each axis.
Example
>>> a = np.arange(12.).reshape((4, 3)) >>> xx = np.linspace(0, a.shape[0] - 1, a.shape[0]) >>> yy = np.linspace(0, a.shape[1] - 1, a.shape[1]) >>> coordinates = xx, yy >>> tensor_spline = TensorSpline(data=a, coordinates=coordinates, bases="bspline1", modes="mirror")
- property coordinates: Tuple[NDArray, ...]#
Copies of the uniform construction coordinates for every axis.
- coefficients_from_data(data: NDArray, *, out: NDArray | None = None) NDArray#
Prefilter new samples on this spline’s construction geometry.
This is the explicit boundary between samples and cardinal spline coefficients. It is useful when one coefficient field will be evaluated by several geometry plans. Changing samples still require prefiltering; this method avoids repeating construction-grid and basis validation, not the mathematically required filter itself.
- Parameters:
data (ndarray) – Floating or complex-floating samples with the template shape, dtype, and array backend.
out (ndarray, optional) – Exact-shape, exact-dtype destination for the coefficients.
- with_data(data: NDArray) TensorSpline#
Return a compatible spline fitted to new samples.
The construction coordinates, bases, and modes are shared as immutable geometry. The returned spline owns newly computed coefficients and the template remains unchanged.
- with_coefficients(coefficients: NDArray, *, copy: bool = True) TensorSpline#
Return a compatible spline from precomputed cardinal coefficients.
copy=Trueis the safe default. Withcopy=Falsethe caller must not mutate the coefficient array while the returned spline or any geometry plan is evaluating it. This method intentionally performs no interpolation prefilter.
- __call__(coordinates: NDArray | Sequence[NDArray], grid: bool = True, *, out: NDArray | None = None) NDArray#
Call self as a function.
- eval(coordinates: NDArray | Sequence[NDArray], grid: bool = True, *, out: NDArray | None = None) NDArray#
Evaluate the tensor spline at the given coordinates.
- Parameters:
coordinates (ndarray) – The coordinates at which to evaluate the tensor spline. If grid is True, must be a sequence of 1-D arrays representing the grid points along each axis. If grid is False, must be a sequence of N-D arrays of the same shape.
grid (bool, optional) – If True (default), assumes the input coordinates define a grid and evaluates the tensor spline over this grid. If False, treats the input coordinates as a list of points at which to evaluate the tensor spline.
- Returns:
data – The interpolated values at the specified coordinates.
- Return type:
ndarray
Example
>>> a = np.arange(12.).reshape((4, 3)) >>> xx = np.linspace(0, a.shape[0] - 1, a.shape[0]) >>> yy = np.linspace(0, a.shape[1] - 1, a.shape[1]) >>> coordinates = xx, yy >>> tensor_spline = TensorSpline(data=a, coordinates=coordinates, bases="bspline1", modes="mirror") >>> eval_coords = np.array([[0.5, 2], [0.5, 1]]) >>> data_eval_pts = tensor_spline.eval(coordinates=eval_coords, grid=False) >>> print(data_eval_pts) [2. 7.]
- query_plan(coordinates: NDArray | Sequence[NDArray], grid: bool = True, *, max_retained_bytes: int = 268435456)#
Precompute support geometry for repeated fixed-coordinate queries.
Query plans are experimental geometry objects compatible with any spline created through
with_data()orwith_coefficients(). They trade explicit, capped retained memory for faster repeated evaluation. Ordinary calls remain the right choice for coordinates that are evaluated only once.
Experimental query plans#
Reusable fixed-coordinate geometry plans for TensorSpline.
- class splineops.spline_interpolation.query_plan.TensorSplineGeometryPlan(spline: TensorSpline, coordinates, *, grid: bool, max_retained_bytes: int)#
Bases:
objectA memory-capped support/weight plan for compatible tensor splines.
Construct plans through
TensorSpline.query_plan(). A plan is useful when the same coordinates are evaluated against changing sample values, such as successive image or volume frames. Plan construction is extra work and retained memory, so one-shot calls should use the spline directly.The spline used at construction remains the default for backward compatibility. Pass another compatible spline to
apply()to obtain the useful geometry-reuse behavior.- incompatibility_reason(spline: TensorSpline) str | None#
Explain why
splinecannot use this geometry, or returnNone.
- is_compatible(spline: TensorSpline) bool#
Return whether
splinecan be evaluated by this geometry plan.
- __call__(spline: TensorSpline | None = None, *, out=None)#
Call self as a function.
- detach() TensorSplineGeometryPlan#
Drop the construction spline while retaining reusable geometry.
Detached plans must receive an explicit compatible spline in
apply(). This is useful for higher-level reusable operators that should not retain the samples used to define their geometry.
- apply(spline: TensorSpline | None = None, *, out=None)#
Evaluate a compatible spline using the precomputed geometry.
- Parameters:
spline (TensorSpline, optional) – Spline with the same construction grid, bases, modes, backend and real precision as the spline used to construct this plan. If omitted, the construction spline is evaluated for compatibility with the original experimental API.
out (ndarray, optional) – Exact-shape, exact-dtype output buffer on the same array backend.
- splineops.spline_interpolation.query_plan.TensorSplineQueryPlan#
alias of
TensorSplineGeometryPlan