.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/01_spline_interpolation/02_spline_bases.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via Binder. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_01_spline_interpolation_02_spline_bases.py: Spline Bases ============ Plotting the spline bases of the library and several transformations and operations. .. GENERATED FROM PYTHON SOURCE LINES 13-17 Imports and Utilities --------------------- Define helper functions to visualize the spline bases and derived splines. .. GENERATED FROM PYTHON SOURCE LINES 17-94 .. code-block:: Python import numpy as np import matplotlib.pyplot as plt from splineops.spline_interpolation.bases.utils import create_basis # Common x-grid for basis functions x_values = np.linspace(-3, 3, 1000) def plot_lines_1d( x, ys, title, labels=None, xlabel="x", ylabel="y", figsize=(8, 4), xlim=None, ylim=None, show_legend=False, tight_layout=False, ): """Generic helper to plot one or several 1D curves.""" plt.figure(figsize=figsize) # Accept a single array or a list/tuple if not isinstance(ys, (list, tuple)): ys = [ys] for i, y in enumerate(ys): kwargs = {} if labels is not None and i < len(labels): kwargs["label"] = labels[i] plt.plot(x, y, **kwargs) if xlim is not None: plt.xlim(*xlim) if ylim is not None: plt.ylim(*ylim) plt.grid(True) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.title(title) if show_legend and labels is not None: plt.legend() if tight_layout: plt.tight_layout() plt.show() def plot_bases(names, x_values, title, show_legend=True): """Plot several spline bases using the generic 1D plotting helper.""" ys = [] labels = [] for name in names: if name == "keys": readable_name = "Keys Spline" else: name_parts = name.split("-") readable_name = f"{name_parts[0][:-1]} degree {name_parts[0][-1]}" ys.append(create_basis(name).eval(x_values)) labels.append(readable_name) plot_lines_1d( x=x_values, ys=ys, labels=labels, title=title, figsize=(12, 6), show_legend=show_legend, ) .. GENERATED FROM PYTHON SOURCE LINES 95-97 Bases ----- .. GENERATED FROM PYTHON SOURCE LINES 99-103 B-Spline Bases ~~~~~~~~~~~~~~ Plot B-spline basis functions for degree 0 to 9. .. GENERATED FROM PYTHON SOURCE LINES 103-110 .. code-block:: Python plot_bases( names=[f"bspline{i}" for i in range(10)], x_values=x_values, title="B-Spline Basis Functions: Degrees 0 to 9", ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_001.png :alt: B-Spline Basis Functions: Degrees 0 to 9 :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 111-115 OMOMS Bases ~~~~~~~~~~~ Plot OMOMS basis functions for degree 0 to 5. .. GENERATED FROM PYTHON SOURCE LINES 115-122 .. code-block:: Python plot_bases( names=[f"omoms{i}" for i in range(6)], x_values=x_values, title="OMOMS Basis Functions: Degrees 0 to 5", ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_002.png :alt: OMOMS Basis Functions: Degrees 0 to 5 :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 123-127 Keys Basis ~~~~~~~~~~ Plot the Keys basis function (legend omitted, title is enough). .. GENERATED FROM PYTHON SOURCE LINES 127-135 .. code-block:: Python plot_bases( names=["keys"], x_values=x_values, title="Keys Basis Function", show_legend=False, ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_003.png :alt: Keys Basis Function :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 136-138 Transforming Cubic B-Splines ---------------------------- .. GENERATED FROM PYTHON SOURCE LINES 140-142 Helper for Cubic B-Spline ~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 142-151 .. code-block:: Python beta3_basis = create_basis("bspline3") def beta3(x): """Centered cubic B-spline β(x, 3).""" return beta3_basis.eval(x) .. GENERATED FROM PYTHON SOURCE LINES 152-157 Single Cubic B-Spline ~~~~~~~~~~~~~~~~~~~~~ Start from the centered cubic B-spline β(x, 3), which is the basic building block for the following plots. .. GENERATED FROM PYTHON SOURCE LINES 157-167 .. code-block:: Python plot_lines_1d( x=x_values, ys=beta3(x_values), title="Cubic B-spline β(x, 3)", xlim=(-3, 3), ylim=(-0.2, 0.7), ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_004.png :alt: Cubic B-spline β(x, 3) :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 168-173 Shifted Cubic B-Spline ~~~~~~~~~~~~~~~~~~~~~~ Shift the cubic B-spline horizontally by one third. This only affects the argument of β, not its shape. .. GENERATED FROM PYTHON SOURCE LINES 173-185 .. code-block:: Python shift = 1.0 / 3.0 plot_lines_1d( x=x_values, ys=beta3(x_values - shift), title="Shifted cubic B-spline β(x - 1/3, 3)", xlim=(-3, 3), ylim=(-0.2, 0.7), ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_005.png :alt: Shifted cubic B-spline β(x - 1/3, 3) :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_005.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 186-191 Shrunk Cubic B-Spline ~~~~~~~~~~~~~~~~~~~~~ Shrink the spline horizontally by 60%. This is done by scaling the argument of β, which changes the effective width of its support. .. GENERATED FROM PYTHON SOURCE LINES 191-204 .. code-block:: Python shift = 1.0 / 3.0 scale = 0.5 # same as "/ 0.5" in the text plot_lines_1d( x=x_values, ys=beta3((x_values - shift) / scale), title="Horizontally scaled β((x - 1/3)/0.5, 3)", xlim=(-3, 3), ylim=(-0.2, 0.7), ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_006.png :alt: Horizontally scaled β((x - 1/3)/0.5, 3) :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_006.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 205-210 Weighted Cubic B-Spline ~~~~~~~~~~~~~~~~~~~~~~~ Multiply the shrunk and shifted spline by a constant factor. This operation is called weighting. .. GENERATED FROM PYTHON SOURCE LINES 210-224 .. code-block:: Python shift = 1.0 / 3.0 scale = 0.5 amp = 0.25 plot_lines_1d( x=x_values, ys=amp * beta3((x_values - shift) / scale), title="Vertically scaled 0.25 · β((x - 1/3)/0.5, 3)", xlim=(-3, 3), ylim=(-0.2, 0.7), ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_007.png :alt: Vertically scaled 0.25 · β((x - 1/3)/0.5, 3) :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_007.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 225-230 Several Transformed B-Splines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use several combinations of (shift, shrink, weight) to obtain different functions, all of which are still cubic B-splines up to their parameters. .. GENERATED FROM PYTHON SOURCE LINES 230-259 .. code-block:: Python def beta3_shift_scale(x, shift, scale, amp=1.0): """Shift, scale, and weight the cubic B-spline.""" return amp * beta3((x + shift) / scale) curves = [ ("0.25 β((x - 1/3)/0.5, 3)", lambda x: beta3_shift_scale(x, shift=-1.0/3.0, scale=0.5, amp=0.25)), ("0.8 β((x + 5/3)/1.2, 3)", lambda x: beta3_shift_scale(x, shift=+5.0/3.0, scale=1.2, amp=0.8)), ("-0.25 β((x + 4/5)/0.2, 3)", lambda x: beta3_shift_scale(x, shift=+4.0/5.0, scale=0.2, amp=-0.25)), ("-0.2 β((x - 1)/1, 3)", lambda x: beta3_shift_scale(x, shift=-1.0, scale=1.0, amp=-0.2)), ] plot_lines_1d( x=x_values, ys=[f(x_values) for _, f in curves], labels=[label for label, _ in curves], title="Four weighted & shifted cubic B-splines", figsize=(10, 5), xlim=(-3, 3), ylim=(-0.2, 0.7), show_legend=True, ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_008.png :alt: Four weighted & shifted cubic B-splines :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_008.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 260-265 Sum of B-Splines ~~~~~~~~~~~~~~~~ Sum these functions together to obtain a new combined function. It is built from cubic B-splines but is itself no longer a basis function. .. GENERATED FROM PYTHON SOURCE LINES 265-277 .. code-block:: Python def combined_spline(x): return sum(f(x) for _, f in curves) plot_lines_1d( x=x_values, ys=combined_spline(x_values), title="Sum of weighted cubic B-splines", xlim=(-3, 3), ylim=(-0.2, 0.7), ) .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_009.png :alt: Sum of weighted cubic B-splines :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_009.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 278-280 Building Splines ---------------- .. GENERATED FROM PYTHON SOURCE LINES 282-287 Helpers for Spline Decomposition ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These helpers are used for the uniform spline, its samples, and their decomposition into shifted and weighted cubic B-splines. .. GENERATED FROM PYTHON SOURCE LINES 287-315 .. code-block:: Python # Integer shifts k = -4, ..., 4 k_vals = np.arange(-4, 5) # Same coefficients as in the original notebook: coeffs = np.array([-2, -3, 4, 1, -5, -1, 2, 6, -4], dtype=float) def spline_from_coeffs(x): """Uniform spline f(x) = Σ_k c[k] β³(x - k).""" x = np.asarray(x) y = np.zeros_like(x, dtype=float) for k, ck in zip(k_vals, coeffs): y += ck * beta3(x - k) return y def spline_term(k, x): """Single term c[k] β³(x - k) for integer k in [-4, 4].""" return coeffs[k + 4] * beta3(x - k) # Common grids for these examples x_plot = np.linspace(-3.1, 3.1, 2000) x_samples = np.arange(-3, 4) # integer sample positions def spline_samples(): """Return integer sample positions and corresponding spline values.""" return x_samples, spline_from_coeffs(x_samples) .. GENERATED FROM PYTHON SOURCE LINES 316-325 Sum of Shifted Cubic B-Splines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Build a regular (uniform) spline as f(x) = Σ_k c[k] β³(x - k), using integer shifts and fixed coefficients c[k]. The thick curve is the full spline; the thin curves are the individual terms c[k] β³(x - k). .. GENERATED FROM PYTHON SOURCE LINES 325-353 .. code-block:: Python plt.figure(figsize=(8, 4)) # Thick combined spline plt.plot( x_plot, spline_from_coeffs(x_plot), linewidth=5, ) # Thin constituent terms c[k] β³(x - k) for k in k_vals: plt.plot( x_plot, spline_term(k, x_plot), linewidth=2, alpha=0.8, ) plt.xlim(-3.1, 3.1) plt.grid(True) plt.xlabel("x") plt.ylabel("y") plt.title("Uniform spline and constituent cubic B-splines") plt.tight_layout() plt.show() .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_010.png :alt: Uniform spline and constituent cubic B-splines :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_010.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 354-360 Sampling a Spline ~~~~~~~~~~~~~~~~~ Sample the spline at integer locations x = k. These samples define a discrete sequence f[k] that we may want to reconstruct from a spline interpolant. .. GENERATED FROM PYTHON SOURCE LINES 360-387 .. code-block:: Python x_samp, y_samp = spline_samples() plt.figure(figsize=(8, 4)) # Thick spline plt.plot( x_plot, spline_from_coeffs(x_plot), linewidth=5, ) # Stems + markers for samples markerline, stemlines, baseline = plt.stem(x_samp, y_samp) plt.setp(markerline, markersize=9) plt.setp(stemlines, linewidth=1.5) plt.setp(baseline, linewidth=1.0) plt.xlim(-3.1, 3.1) plt.grid(True) plt.xlabel("x") plt.ylabel("y") plt.title("Uniform spline with samples at integer positions") plt.tight_layout() plt.show() .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_011.png :alt: Uniform spline with samples at integer positions :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_011.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 388-396 From Samples to Splines ~~~~~~~~~~~~~~~~~~~~~~~ Illustrate the relationship between: - the discrete samples f[k] (left), - the shifted and weighted basis functions c[k] β³(x - k) (middle), - and the resulting spline f(x) that interpolates the samples (right). .. GENERATED FROM PYTHON SOURCE LINES 396-464 .. code-block:: Python x_samp, y_samp = spline_samples() fig, axes = plt.subplots(1, 3, figsize=(12, 4), sharey=True) # Left panel: samples only ax = axes[0] markerline, stemlines, baseline = ax.stem(x_samp, y_samp) plt.setp(markerline, markersize=9) plt.setp(stemlines, linewidth=1.5) plt.setp(baseline, linewidth=1.0) ax.set_xlim(-3.1, 3.1) ax.grid(True) ax.set_xlabel("x") ax.set_ylabel("y") ax.set_title("Samples f[k]") # Middle panel: basis terms + samples ax = axes[1] for k in k_vals: ax.plot( x_plot, spline_term(k, x_plot), linewidth=2, alpha=0.8, ) markerline, stemlines, baseline = ax.stem(x_samp, y_samp) plt.setp(markerline, markersize=9) plt.setp(stemlines, linewidth=1.5) plt.setp(baseline, linewidth=1.0) ax.set_xlim(-3.1, 3.1) ax.grid(True) ax.set_xlabel("x") ax.set_title(r"Weighted terms $c[k]\beta^3(x-k)$") # Right panel: full spline + terms + samples ax = axes[2] ax.plot( x_plot, spline_from_coeffs(x_plot), linewidth=5, ) for k in k_vals: ax.plot( x_plot, spline_term(k, x_plot), linewidth=2, alpha=0.8, ) markerline, stemlines, baseline = ax.stem(x_samp, y_samp) plt.setp(markerline, markersize=9) plt.setp(stemlines, linewidth=1.5) plt.setp(baseline, linewidth=1.0) ax.set_xlim(-3.1, 3.1) ax.grid(True) ax.set_xlabel("x") ax.set_title("Resulting spline f(x)") plt.tight_layout() plt.show() .. image-sg:: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_012.png :alt: Samples f[k], Weighted terms $c[k]\beta^3(x-k)$, Resulting spline f(x) :srcset: /auto_examples/01_spline_interpolation/images/sphx_glr_02_spline_bases_012.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.152 seconds) .. _sphx_glr_download_auto_examples_01_spline_interpolation_02_spline_bases.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/splineops/splineops.github.io/main?urlpath=lab/tree/notebooks_binder/auto_examples/01_spline_interpolation/02_spline_bases.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 02_spline_bases.ipynb <02_spline_bases.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 02_spline_bases.py <02_spline_bases.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 02_spline_bases.zip <02_spline_bases.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_