scijit.interpolate.RectSphereBivariateSpline¶
- scijit.interpolate.RectSphereBivariateSpline(u, v, r, s=0.0, pole_continuity=False, pole_values=None, pole_exact=False, pole_flat=False, r0=nan, r1=nan, ider0=-9, ider1=-9, ider2=-9, ider3=-9, iopt2=-9, iopt3=-9, validate=True)¶
Build a spline on a spherical grid.
- Parameters:
- u1-D float64 ndarray, length mu
Colatitudes of the grid, strictly increasing, strictly inside
(0, pi).- v1-D float64 ndarray, length mv
Longitudes, strictly increasing, with
v[0]in[-pi, pi)andv[-1] <= v[0] + 2*pi.- r2-D float64 ndarray, shape (mu, mv)
Grid values.
- sfloat, optional
Smoothing factor. Default 0.0.
- pole_continuitybool or (bool, bool), optional
Continuity at the south and north pole. Default False.
- pole_valuesfloat or (float, float), optional
Data value at the poles.
None(the default) means unknown at both; a scalar is broadcast to both.(None, 0.0)is accepted. A NaN in a slot is a literal pole value.- pole_exactbool or (bool, bool), optional
Whether pole_values is exact or a data value to be smoothed. Default False. Ignored where pole_values is unknown.
- pole_flatbool or (bool, bool), optional
Whether the surface should be flat at the poles. Default False.
- r0, r1float, optional
RAW FITPACK pole values, overriding pole_values. NaN, the default, means “not overridden”.
- ider0, ider1, ider2, ider3int, optional
RAW FITPACK
idercodes, overriding pole_exact and pole_flat. -9, the default, means “not overridden”.- iopt2, iopt3int, optional
RAW FITPACK
iopt(2)/iopt(3), overriding pole_continuity. -9, the default, means “not overridden”.- validatebool, optional
Raise when FITPACK returns NaN coefficients under a success status, rather than handing back a spline that evaluates to NaN everywhere. Default True. One
np.isnanover the coefficient array, run once at construction. See the note onpole_continuity=Truebelow for what produces that state. Set False to receive the spline and testnp.isnan(spl.c).any()directly.
- Attributes:
- tx, ty1-D float64 ndarray
Knot vectors in colatitude and longitude.
- c1-D float64 ndarray
Coefficients in FITPACK’s flat bivariate layout.
- kx, kyint
Both 3. BICUBIC ONLY.
- fpfloat
Sum of squared residuals, also returned by
get_residual().- ierint
FITPACK status. Any value outside {0, -1, -2} has already raised.
Methods
eval_grid(u, v, dtheta, dphi)
Grid evaluation, the equivalent of
spl(theta, phi).ev(ui, vi, dtheta, dphi), ev_one(u, v, dtheta, dphi),
partial_derivative(u, v, dtheta, dphi), get_knots(), get_coeffs(),
get_residual()
- Returns:
- spl_RectSphereBivariateSpline
A jitclass instance carrying the attributes and methods below.
- Raises:
- ValueError
u not strictly inside
(0, pi),v[0]outside[-pi, pi),v[-1] > v[0] + 2*pi, non-increasing u or v, an r whose dimensions do not match,pole_continuityFalse withpole_flatTrue,s < 0, and every FITPACK status outside {0, -1, -2}. Also NaN coefficients under a success status, unlessvalidate=False, which skips the check and returns the NaN spline.- TypeError
A scalar pole_continuity, pole_exact or pole_flat that is not a bool, and a scalar pole_values that is not a float. The scalar reaches a subscript or an unpack:
pole_continuity=1is'int' object is not subscriptableandpole_flat=1iscannot unpack non-iterable int object. A pair of ints is accepted.
See also
scipy.interpolate.RectSphereBivariateSplineThe scipy class this mirrors.
Notes
spl(u, v)runseval_grid, scipy’sgrid=Truedefault, for every pair of scalars and arrays, so two scalars give a(1, 1)grid.ev(ui, vi)is scipy’sgrid=Falseandev_one(u, v)the single-point scalar spelling, both reached by name..partial_derivativereturns a new object in scipy; here it evaluates on a grid directly.ev_onereturns a SCALAR where scipy’s.evon scalars returns a length-1 array.pole_values=(None, 0.0)is accepted;(np.nan, 0.0)means the same thing.r0, r1 and the six raw codes are extra arguments scipy does not have. A scipy-shaped call never passes them; they reach FITPACK options scipy’s four booleans cannot express.
scipy’s
.v0attribute is absent.
Defaults work in both worlds.
RectSphereBivariateSplineis a plain@njitfactory, not the jitclass itself, soRectSphereBivariateSpline(u, v, r)compiles and runs inside@njitas well as from Python. The class it returns,_RectSphereBivariateSpline, takes every argument explicitly, because a jitclass constructor’s defaults are Python-only.pole_continuity=TrueREACHES A NONDETERMINISTIC PATH IN FITPACK, on this library and on scipy alike. The same input, in a fresh process, gives different answers from run to run. At least three outcomes occur on a 12x14 grid ats = 0.5:nt = (20, 21) fp = 0.0 NaN coefficients, status -1 nt = (8, 11) fp = 0.5000435091 finite, status 0 nt = (9, 11) fp = 0.4995522302 finite, status 0
nt is
(len(tu), len(tv)), the two knot counts, and fp is the weighted sum of squared residuals.The two finite outcomes are both correct.
spgridstops whenabs(fp - s) <= tol * swithtol = 0.001fixed in the source, so ats = 0.5any fp within 5.0e-04 of 0.5 is accepted. The two differ from s by 4.35e-05 and 4.48e-04, both inside that band, and from each other by 4.91e-04, which is 0.98 of the band width. They are two knot placements that satisfy the same smoothing request, not a right and a wrong answer.The NaN outcome is the defect.
fp = 0.0againsts = 0.5means the fit fell through to interpolation, and its coefficients are not finite.The proportions are not stable between samples, so no single ratio describes it. Measured as the first call in a fresh process, 8 runs each: this library 3 NaN and 5 finite, scipy 4 NaN and 4 finite, scipy’s values identical to this library’s. An earlier 9-run sample of this library gave 9 NaN, which is why an earlier version of this note reported the path as always returning NaN here; that was a small sample, not determinism.
Nothing distinguishes the outcomes from the status code, and status -1 means “interpolating spline”, not an error. validate, on by default, detects the NaN outcome and issues a
RuntimeWarning; the spline is returned either way, as scipy returns it.validate=Falsesilences the warning and leavesnp.isnan(spl.c).any()to the caller.The cause is upstream, not in this wrapper: scipy 1.18 reaches FITPACK through its own C translation, sharing no code with this package, and reproduces the same outcomes with the same numbers. Every workspace array here is zero-filled and sized by the documented
spgridformula.scipy.interpolate.RectSphereBivariateSpline’s own documentation does not mention it.pole_continuity=False, the default, is stable.Accuracy against
scipy.interpolate.RectSphereBivariateSplineon scipy 1.18.0, 12x14 grid, default pole arguments, in knots, coefficients, fp and grid values: exactly 0.0 ats= 0, 0.5 and 10.0. Ats = 1e-6the two choose a different number of longitude knots, 20 against 21, which is a structurally different spline that no tolerance expresses.Which s values land in which régime is a property of the DATA, not of s: a second 12x14 fixture put the mismatch at
s = 0.01instead (11 latitude knots against 12). Treat the knot counts above as an example, and compare knot counts before comparing values.prange-safe: yes.
Examples
>>> import numpy as np >>> from numba import njit >>> from scijit.interpolate import RectSphereBivariateSpline >>> u = np.linspace(0.1, np.pi - 0.1, 12) >>> v = np.linspace(0, 2 * np.pi, 15)[:-1] >>> r = np.outer(np.sin(u), np.cos(v)) + 2.0 >>> spl = RectSphereBivariateSpline(u, v, r, s=0.5) # fit once >>> spl.ier 0 >>> float(np.round(spl(1.5, 1.0)[0, 0], 6)) # spl(u, v) is the grid form; [0, 0] takes the point 2.442246
Inside compiled code, the largest value over a coarse query grid:
>>> @njit ... def gridmax(spl): ... return np.max(spl(np.linspace(0.5, 2.5, 5), np.linspace(0.5, 5.5, 5))) >>> float(np.round(gridmax(spl), 6)) 2.781747