scijit.interpolate.splder

scijit.interpolate.splder(t, c=None, k=None, n=1)

Spline representation of the n-th derivative of a spline.

Two argument spellings: splder(t, c, k, n) passes the three components of the spline, splder(tck, n) passes the (t, c, k) tuple.

Parameters:
t1-D float64 ndarray, tuple (t, c, k), or a BSpline

Knot vector of the input spline, the whole spline representation, or a spline object. A tuple selects the tck spelling and a BSpline the object spelling; under both, k is not passed and the second positional argument is the derivative order. A BSpline in gives a BSpline out, carrying extrapolate and periodic through.

cfloat64 ndarray, optional

B-spline coefficients. A FITPACK-style c (padded to len(t)) or a bare length-len(t)-k-1 array both work; it is padded internally. Any OTHER length raises ValueError. A rank-2 c holds one column per curve and every column is differentiated at once. Under the tck and object spellings this slot carries n.

kint, optional

Degree of the input spline. Not passed under the tck spelling.

nint, optional

Derivative order. A NEGATIVE order gives the antiderivative of the opposite order, so splder(tck, -1) is splantider(tck, 1). n > k raises ValueError. Default 1.

Returns:
t21-D float64 ndarray, length len(t) - 2*n

Knot vector of the derivative spline (the input’s, with n knots stripped from each end).

c2float64 ndarray, first axis len(t2)

Coefficients of the derivative spline, zero-padded to len(t2), and carrying a rank-2 c’s columns.

k2int

Degree of the derivative spline, k - n.

See also

scipy.interpolate.splder

The scipy routine this mirrors.

Notes

  • Also exported under the name splder. scijit.interpolate.evaluators.splder is a DIFFERENT function, the raw FITPACK routine with Dierckx’s own calling convention.

  • scipy.interpolate.splder is marked legacy in scipy’s own documentation, which points at BSpline.derivative for new code.

  • A BSpline argument returns a BSpline rather than the triple, as it does in scipy.

  • The two spellings share one implementation, _splder_core, and reach it from a Python body and from an @overload. The first argument’s TYPE selects, so they cannot be mixed: a tuple followed by c and k raises ValueError from Python and TypingError inside @njit, and so does a two-argument call whose first argument is an array. The return (t2, c2, k2) is a tck triple under either spelling, and feeds splev unchanged.

  • Inside @njit the tck spelling takes a TUPLE. Measured on numba 0.66: a heterogeneous list [t, c, k] has no numba type, as an argument or as a construction, so scipy’s list spelling reaches only the Python entry, which accepts it.

  • Raises ValueError if an interior knot is repeated enough to make the spline non-differentiable that many times.

  • A c whose length is neither len(t) - k - 1 nor len(t) raises ValueError. scipy.interpolate.splder validates nothing and reaches a numpy broadcast whose outcome depends on how wrong the length was, so this is a deliberate deviation; the text is scipy’s own, raised by BSpline.__init__ for the same fault.

  • A c of rank 3 or more raises ValueError, where scipy carries any number of trailing dimensions.

  • A PARAMETRIC c, one coefficient array per dimension, which is what splprep returns, raises ValueError naming the two spellings that work: one dimension at a time, splder(t, c[j], k, n), or a rank-2 c with one column per dimension, differentiated in one call. scipy.interpolate.splder raises AttributeError: 'list' object has no attribute 'shape' on its own splprep output, and refuses the rank-2 spelling with a broadcast error.

  • A c given as a flat list or tuple of numbers raises ValueError. scipy.interpolate.splder raises AttributeError: 'list' object has no attribute 'shape' for it.

Accuracy vs scipy.interpolate.splder on a random k=3 spline with 12 knots: knots, coefficients and degree all match exactly (0.0) for n = 1, 2, 3, including the returned array lengths, and the two spellings return the same bytes.

prange-safe: yes.

Examples

>>> import numpy as np
>>> from numba import njit
>>> from scijit.interpolate import splrep, splev, splder
>>> x = np.linspace(0.0, 3.0, 40)
>>> tck = splrep(x, np.sin(x))
>>> @njit
... def slope_at(tck, q):
...     return splev(q, splder(tck, 1))
>>> np.round(slope_at(tck, np.array([0.0, 1.5])), 6)
array([1.000006, 0.070737])
>>> t2, c2, k2 = splder(tck[0], tck[1], tck[2], 1)
>>> k2, bool(np.array_equal(t2, splder(tck, 1)[0]))
(2, True)