scijit.interpolate.interpn

scijit.interpolate.interpn(points, values, xi, method='linear', bounds_error=True, fill_value=nan, extrapolate=False)

Interpolate on a regular grid.

A one-shot wrapper: builds a RegularGridInterpolator and evaluates it at xi.

Parameters:
pointstuple or list of 1-D float array_like

Axis coordinates, as for RegularGridInterpolator.

valuesarray_like

Grid data, as for RegularGridInterpolator: its leading shape is the grid shape, a complex values is held as complex128 and anything else as float64, and up to 2 trailing axes give a block of numbers at each node.

xiarray_like, or tuple or list of array_like

Query points of shape (..., ndim), any rank. A rank-1 xi is read as reshape(-1, ndim), so one coordinate per axis is a single point and a 1-D grid reads a run of points. A tuple or list of coordinate arrays is broadcast together and stacked on a new trailing axis, which is what lets a meshgrid be passed straight in; arrays that do not broadcast raise ValueError.

methodstr, optional

'linear' multilinear, 'nearest' nearest-neighbour, 'pchip' a shape-preserving cubic along each axis in turn, 'splinef2d' a bicubic RectBivariateSpline over a 2-D grid. Default 'linear'. 'pchip' needs at least four nodes on every axis and a real values.

bounds_errorbool, optional

Raise on out-of-bounds query points. Default True.

fill_valuescalar, array_like or None, optional

Out-of-bounds value when bounds_error is False; None extrapolates linearly off the edge cell. A sequence is one value per component. A value that cannot be cast to the stored dtype, or whose shape does not broadcast, raises ValueError. Default NaN. 'splinef2d' takes a scalar and refuses None.

extrapolatebool, optional

Continue the interpolant off the edge cell for an out-of-bounds query, ignoring fill_value. The same thing fill_value=None does. Default False. 'splinef2d' refuses it.

Returns:
outndarray of shape xi.shape[:-1] + values.shape[ndim:]

Interpolated values, one per query point, in the dtype values are stored in. 'splinef2d' returns float64.

See also

scipy.interpolate.interpn

The scipy routine this mirrors.

Notes

It builds a RegularGridInterpolator and evaluates it, both in compiled code. Rebuilding the interpolator on every call is wasteful, so for repeated queries against one grid build it once and call it, rgi(xi).

Only 'linear', 'nearest', 'pchip' and 'splinef2d' are implemented. scipy’s 'slinear', 'cubic' and 'quintic' are not, and raise.

extrapolate has no scipy counterpart. It is fill_value=None under a boolean spelling; a scipy-shaped call never passes it.

method='splinef2d' differs from the other methods in three ways: values must be a 2-D grid, extrapolation is refused with bounds_error off, and the spline is built from points as given, so a descending axis raises ValueError("x must be strictly increasing") where the other methods flip it and interpolate.

`method=’splinef2d’` inside ``@njit``. The arm is selected while the call compiles, since a 2-D grid and an N-D grid cannot be evaluated by the same compiled code. The name has to be written at the call site; method read from a variable raises ValueError.

A complex `values` with ``method=’splinef2d’``. It raises ValueError. scipy interpolates the real part and discards the imaginary one, with a ComplexWarning.

A 1-D grid with ``method=’splinef2d’``. It raises ValueError("The method splinef2d can only be used for 2-dimensional input data"). scipy raises IndexError: tuple index out of range, from indexing the second axis of a grid that has one.

Accuracy: see the module docstring.

Examples

>>> import numpy as np
>>> from numba import njit
>>> from scijit.interpolate import interpn
>>> x = np.linspace(0.0, 1.0, 5)
>>> y = np.linspace(0.0, 1.0, 6)
>>> vals = np.exp(x[:, None] + y[None, :])
>>> @njit
... def one_shot(x, y, vals, xi):
...     return interpn((x, y), vals, xi)
>>> float(one_shot(x, y, vals, np.array([[0.25, 0.4]]))[0])
1.9155408290138962