Basis polynomials

Basis polynomials#

Inputs#

This example evaluates five cubic B-spline basis functions, together with their first and second derivatives. n=4 is the highest index, so there are n+1=5 functions; p=3 is their degree. The knot vector has n+p+2=9 entries:

[0, 0, 0, 0, 0.5, 1, 1, 1, 1]

Four repeated knots at each end clamp the basis. The single interior knot at \(u=0.5\) gives two spans with \(C^2\) continuity. The equations are developed in B-spline theory.

Complete script#

Run python demos/documentation/basis_polynomials.py, or download the script.

"""Plot cubic B-spline basis functions and their first two derivatives."""
import numpy as np
import matplotlib.pyplot as plt
import nurbspy as nrb

nrb.set_plot_options()

n, p = 4, 3  # Five basis functions, each of degree three.
U = np.array([0., 0., 0., 0., 0.5, 1., 1., 1., 1.])
u = np.linspace(0., 1., 501)
N = nrb.compute_basis_polynomials(n, p, U, u)
dN = nrb.compute_basis_polynomials_derivatives(n, p, U, u, 1)
ddN = nrb.compute_basis_polynomials_derivatives(n, p, U, u, 2)

print("Basis array shape:", N.shape)
print("Basis at u=0.5:", N[:, 250])
print(f"Maximum partition-of-unity error: {np.max(np.abs(N.sum(axis=0) - 1)):.2e}")
print(f"Maximum first-derivative sum: {np.max(np.abs(dN.sum(axis=0))):.2e}")
print(f"Maximum second-derivative sum: {np.max(np.abs(ddN.sum(axis=0))):.2e}")

fig, axes = plt.subplots(1, 3, figsize=(12, 3.6), layout="constrained")
for ax, values, title in zip(axes, [N, dN, ddN],
                             ["Basis functions", "First derivatives", "Second derivatives"]):
    for i, row in enumerate(values):
        ax.plot(u, row, label=f"i={i}")
    ax.axvline(0.5, color="0.7", linestyle=":", linewidth=1)
    ax.set(xlabel="u", ylabel="Value", title=title)
    ax.grid(alpha=0.2)
axes[0].legend(fontsize=10)
plt.show()

Output#

N, dN, and ddN all have shape (5, 501). Each row holds one basis function over the parameter samples. At the middle sample:

Basis array shape: (5, 501)
Basis at u=0.5: [0.   0.25 0.5  0.25 0.  ]

The basis values sum to one. Their first and second derivatives sum to zero, up to floating-point roundoff, because they differentiate that constant sum.

Five cubic B-spline basis functions and their first two derivatives.

Values, slopes, and second derivatives across the two knot spans.#

The first and last bases interpolate the ends. At most four cubic bases are nonzero inside a span. To obtain Bernstein polynomials, set p=n and use n+1 zeros followed by n+1 ones.