This is a pre-release version (latest).Go to latest (1.18.0)
{ } Raw JSON

bundles / scipy latest / scipy / interpolate / _fitpack_repro / generate_knots

function

scipy.interpolate._fitpack_repro:generate_knots

source: build-install/usr/lib/python3.14/site-packages/scipy/interpolate/_fitpack_repro.py:169

Signature

def generate_knots(x, y, *, w = None, xb = None, xe = None, k = 3, s = 0, nest = None, bc_type = None)

Summary

Generate knot vectors until the Least SQuares (LSQ) criterion is satisfied.

Parameters

x, y : array_like

The data points defining the curve y = f(x).

w : array_like, optional

Weights.

xb : float, optional

The boundary of the approximation interval. If None (default), is set to x[0].

xe : float, optional

The boundary of the approximation interval. If None (default), is set to x[-1].

k : int, optional

The spline degree. Must be >= 1. Default is cubic, k = 3.

s : float, optional

The smoothing factor. Default is s = 0.

nest : int, optional

Stop when at least this many knots are placed.

ends are equivalent.

bc_type : str, optional

Boundary conditions. Default is "not-a-knot". The following boundary conditions are recognized:

  • "not-a-knot" (default): The first and second segments are the same polynomial. This is equivalent to having bc_type=None.

  • "periodic": The values and the first k-1 derivatives at the ends are equivalent.

Yields

t : ndarray

Knot vectors with an increasing number of knots. The generator is finite: it stops when the smoothing critetion is satisfied, or when then number of knots exceeds the maximum value: the user-provided nest or x.size + k + 1 --- which is the knot vector for the interpolating spline.

Notes

The routine generates successive knots vectors of increasing length, starting from 2*(k+1) to len(x) + k + 1, trying to make knots more dense in the regions where the deviation of the LSQ spline from data is large.

When the maximum number of knots, len(x) + k + 1 is reached (this happens when s is small and nest is large), the generator stops, and the last output is the knots for the interpolation with the not-a-knot boundary condition.

Knots are located at data sites, unless k is even and the number of knots is len(x) + k + 1. In that case, the last output of the generator has internal knots at Greville sites, (x[1:] + x[:-1]) / 2.

Examples

Generate some noisy data and fit a sequence of LSQ splines:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import make_lsq_spline, generate_knots
rng = np.random.default_rng(12345)
x = np.linspace(-3, 3, 50)
y = np.exp(-x**2) + 0.1 * rng.standard_normal(size=50)
✓
knots = list(generate_knots(x, y, s=1e-10))
✓
for t in knots[::3]:
    spl = make_lsq_spline(x, y, t)
    xs = xs = np.linspace(-3, 3, 201)
    plt.plot(xs, spl(xs), '-', label=f'n = {len(t)}', lw=3, alpha=0.7)
plt.plot(x, y, 'o', label='data')
plt.plot(xs, np.exp(-xs**2), '--')
plt.legend()
✗
<matplotlib.legend.Legend object at 0x7f3f60b81550>
Note that increasing the number of knots make the result follow the data more and more closely. Also note that a step of the generator may add multiple knots:
[len(t) for t in knots]
✓
[8, 9, 10, 12, 16, 24, 40, 48, 52, 54]

Aliases

  • scipy.interpolate.generate_knots

Referenced by