scijit.interpolate.UnivariateSpline

scijit.interpolate.UnivariateSpline(x, y, w=array([], dtype=float64), bbox=None, k=3, s=None, ext=0, check_finite=False)

Build a univariate smoothing spline.

Parameters:
x1-D float64 ndarray, length m

Abscissae, strictly increasing.

y1-D float64 ndarray, length m

Ordinates.

w1-D array_like of float, optional

Positive weights, length m. None and a ZERO-LENGTH array both mean unit weights. Passing w does NOT change the default s, unlike splrep.

bbox(2,) array_like of float, optional

Boundary of the approximation interval. None, in place of the pair or in one slot, means x[0] / x[-1], and is the default. It may only WIDEN the data interval. The literal default [None, None] is accepted, from Python and from inside @njit.

kint, optional

Spline degree, 1 <= k <= 5. Default 3.

sfloat, optional

Smoothing factor: the fit satisfies sum(w[i]*(y[i]-spl(x[i])))**2 <= s. None, the default, means s = m. s = 0 gives the interpolating spline. A negative or NaN s raises ValueError.

extint or str, optional

Extrapolation mode outside [t[k], t[n-k-1]], four codes and their names: 0 or 'extrapolate', 1 or 'zeros', 2 or 'raise', 3 or 'const'. Default 0.

check_finitebool, optional

Raise if x, y or w contains a NaN or an inf. Default False.

Attributes:
t1-D float64 ndarray

Full knot vector, including the repeated boundary knots.

c1-D float64 ndarray

Coefficients in FITPACK’s padded form.

kint

Spline degree.

fpfloat

Weighted sum of squared residuals.

ierint

FITPACK status: 0 = smoothing achieved, -1 = interpolating spline, -2 = least-squares polynomial, positive = failure. Kept as an attribute rather than raised – CHECK IT after constructing.

extint

The resolved extrapolation code, 0..3.

Methods

ev(x), ev_one(x), __getitem__(x), derivative_ev(x, nu), derivatives(x),

integral(a, b), roots(), get_knots(), get_coeffs(), get_residual()

Returns:
spl_UnivariateSpline

A jitclass instance carrying the attributes and methods below.

Raises:
ValueError

Non-finite input under check_finite, non-monotone x, mismatched lengths, a bbox that is not length 2, k outside 1..5, a supplied s below 0, an unknown ext, or m <= k.

See also

scipy.interpolate.UnivariateSpline

The scipy class this mirrors.

Notes

  • spl(x) runs .ev for an array and .ev_one for a scalar. .ev(x), .ev_one(x) and spl[x] reach the same methods. spl(x, nu) and spl(x, nu, ext) carry scipy’s second and third positional parameters, and spl(x, nu=1) and spl(x, ext=1) carry them by keyword. .ev(x, nu=1) takes the keyword inside @njit and not from the interpreter, where the jitclass method raises TypeError; the call spelling works from both.

  • scipy RE-CLASSES the instance by ier (_reset_class), so a UnivariateSpline with ier == -1 becomes an InterpolatedUnivariateSpline. A jitclass cannot change its own type; ier is returned as an attribute instead.

  • .derivative() / .antiderivative() returning new spline objects are not implemented. Use derivative_ev(x, nu), or splder for the tck.

  • set_smoothing_factor is absent: it resumes FITPACK’s search from the stored fpcurf1 continuation state, which is not reachable through the curfit wrapper. Refit with the new s.

  • ier = 10 RAISES here. scipy warns and returns an object whose knot vector was never filled; a status that means “no approximation returned” is not carried into a usable object. ier of 1, 2 or 3 warns.

  • A complex y raises TypeError. scipy 1.18 accepts it, emits a ComplexWarning and discards the imaginary part, returning a float64 spline.

Defaults work in both worlds. UnivariateSpline is a plain @njit factory, not the jitclass itself, so UnivariateSpline(x, y) compiles and runs inside @njit as well as from Python. The class it returns, _UnivariateSpline, takes every argument explicitly, because a jitclass constructor’s defaults are Python-only.

A SMOOTHING FIT MAY WARN THAT IT IS RANK DEFICIENT. With a small s on noisy data, FITPACK’s knot search can place knots so that one B-spline coefficient is not determined by the data at all. The curve still passes through the data as asked, and fp reports success, but between the data points it carries an arbitrary component. A UserWarning naming the number of undetermined coefficients is issued when this happens, and a larger s is the fix. scipy issues no warning for it.

Accuracy against scipy.interpolate.UnivariateSpline on scipy 1.18.0, max absolute difference: knots, coefficients and values all 0.0 at s = 0, 1e-8, 0.5, 1.0 and at the default, and 0.0 for the four nest-retry-sensitive sizes m = 150, 300, 500, 1000. On scipy 1.15.3 the s=1e-8 case differed by 510.33, because 1.15.3’s _reset_nest resumed a search that 1.18’s no longer does.

prange-safe: yes.

Examples

>>> import numpy as np
>>> from numba import njit
>>> from scijit.interpolate import UnivariateSpline
>>> x = np.linspace(0, 4, 40)
>>> y = np.sin(x)
>>> spl = UnivariateSpline(x, y, s=0.5)     # smoothing spline, fit once
>>> float(np.round(spl(1.5), 6))
0.971964

Inside compiled code, integrating the fitted spline over its domain:

>>> @njit
... def area(spl):
...     return spl.integral(0.0, 4.0)
>>> float(np.round(area(spl), 6))
1.664201