scijit.interpolate.RectBivariateSpline¶
- scijit.interpolate.RectBivariateSpline(x, y, z, bbox=None, kx=3, ky=3, s=0.0, maxit=20)¶
Build a bivariate spline over gridded data.
- Parameters:
- x1-D float64 ndarray, length mx
Grid abscissae, strictly increasing.
- y1-D float64 ndarray, length my
Grid ordinates, strictly increasing.
- z2-D float64 ndarray, shape (mx, my)
Grid values. An F-ordered or strided array is copied first, so it is read correctly.
- bbox(4,) array_like of float, optional
The rectangle the fit is made over,
[xb, xe, yb, ye].None, in place of the four or in one slot, meansmin(x),max(x),min(y),max(y), and is the default. It may only WIDEN the data rectangle; a narrower one gives FITPACK’sier = 10, and raises. The literal default[None, None, None, None]is accepted, from Python and from inside@njit.- kxint, optional
Degree in x, 1 <= kx <= 5. Default 3.
- kyint, optional
Degree in y, 1 <= ky <= 5. Default 3.
- sfloat, optional
Smoothing factor; 0 gives the interpolating surface. Default 0.0.
NoneraisesTypeError.- maxitint, optional
Cap on FITPACK’s knot-search iterations; reaching it is
ier = 3, which raises. Default 20. Any value below 1 means “run no iterations” and is accepted; withs = 0no iteration is needed and the surface is unaffected. See the Notes for the one case where it still raises.
- Attributes:
- tx, ty1-D float64 ndarray
Knot vectors in x and y. Together with c these are the tck.
- c1-D float64 ndarray
Coefficients in FITPACK’s flat bivariate layout.
- kx, kyint
The two degrees.
- fpfloat
Sum of squared residuals, also returned by
get_residual().- ierint
FITPACK status: 0 = smoothing achieved, -1 = interpolating surface, -2 = least-squares polynomial. Any other value has already raised, so this is 0, -1 or -2 on every instance that exists.
Methods
eval_grid(x, y, dx, dy)
Grid evaluation, the equivalent of
spl(x, y).ev(xi, yi, dx, dy), ev_one(x, y, dx, dy),
partial_derivative(x, y, dx, dy), integral(xa, xb, ya, yb),
get_knots(), get_coeffs(), get_residual()
- Returns:
- spl_RectBivariateSpline
A jitclass instance carrying the attributes and methods below.
- Raises:
- ValueError
Non-increasing x or y, a z whose two dimensions do not match x and y, a bbox that is not length 4,
s < 0,mx <= kx,my <= ky, kx or ky outside 1..5, and every FITPACK status outside {0, -1, -2}.- TypeError
s = None, with the messagemust be real number, not NoneType.
See also
scipy.interpolate.RectBivariateSplineThe scipy class this mirrors.
Notes
spl(x, y)runseval_grid, scipy’sgrid=Truedefault, for every pair of scalars and arrays, so two scalars give a(1, 1)grid.ev(xi, yi)is scipy’sgrid=Falseandev_one(x, y)the single-point scalar spelling, both reached by name.A complex z raises
TypeError. scipy 1.18 accepts it, emits aComplexWarningand discards the imaginary part, returning a float64 spline.maxitis honoured as the knot-search iteration cap.maxit=5on a smoothing fit turns a converged answer intoier = 3, which raises, and a larger cap converges where 20 does not.maxit < 1means “run no knot-search iterations”, scipy’s reading, and is accepted. Where the fit needs no iteration the result is scipy’s, measured over four grids from 6x7 to 20x18: withs = 0(statusier = -1, interpolating) 4 of 4 cases agree with scipy at0.000e+00on knots, coefficients andfp, and with a larges(ier = -2, least-squares polynomial) 3 of 3 do.WHERE IT STILL RAISES. If the knot search was needed and the cap stopped it, FITPACK reports
ier = 3and the fit raises, as it does for any other iteration cap. The surface FITPACK has at that point is unconverged. Raise the cap, or call fitters.regrid directly and readier.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 surface still passes through the data as asked, and
fpandierreport success, but between the data points it carries an arbitrary component and can swing far outside the range of the data.A
UserWarningnaming the number of undetermined coefficients is issued when this happens. The fix is a LARGER s: the condition appears when s is small enough to drive the knot count to its maximum, and disappears once the fit has room. scipy issues no warning for it..partial_derivative(dx, dy)returns a new_DerivedBivariateSplinein scipy; here it evaluates on a grid directly. A jitclass cannot construct one of itself.ev_onereturns a SCALAR where scipy’sspl.ev(0.5, 0.5)returns a length-1 array.z as a list of lists is rejected: numba cannot reflect a list of lists. A 2-D array, including F-ordered and strided, is accepted.
Defaults work in both worlds.
RectBivariateSplineis a plain@njitfactory, not the jitclass itself, soRectBivariateSpline(x, y, z)compiles and runs inside@njitas well as from Python. The class it returns,_RectBivariateSpline, takes every argument explicitly, because a jitclass constructor’s defaults are Python-only.Accuracy against
scipy.interpolate.RectBivariateSplineon scipy 1.18.0. INTERPOLATING fits (s = 0) are exactly 0.0 in knots, coefficients, fp, grid values,.ev,.integral, everydx/dypair and bothget_*methods, forkx,ky= 1..5 and with bbox widened.A SMOOTHING fit is a different matter. scipy 1.18 reaches FITPACK through a C translation whose smoothing iteration rounds differently, so on data where the knot search is sensitive the two libraries place knots in DIFFERENT POSITIONS. The surface gap is then set by the data rather than by floating point: measured up to 1.8e-02 on a 13x14 noisy grid at
s = 0.01, with both sides reportingier = 0and both inside FITPACK’s own|fp-s|/s <= 1e-3test. Two valid smoothing splines, not one right and one wrong. Where the knot search agrees the surfaces agree. Compare knot counts before comparing values.prange-safe: yes.
Examples
>>> import numpy as np >>> from numba import njit >>> from scijit.interpolate import RectBivariateSpline >>> x = np.linspace(0, 1, 12) >>> y = np.linspace(0, 1, 15) >>> z = np.outer(np.sin(3 * x), np.cos(2 * y)) >>> spl = RectBivariateSpline(x, y, z) # fit once >>> float(np.round(spl(0.5, 0.5)[0, 0], 8)) # spl(x, y) is the grid form; [0, 0] takes the point 0.53894085
Inside compiled code, the largest value over a coarse query grid:
>>> @njit ... def gridmax(spl): ... return np.max(spl(np.linspace(0.0, 1.0, 5), np.linspace(0.0, 1.0, 5))) >>> float(np.round(gridmax(spl), 6)) 0.99748