scipy.interpolate.

BSpline#

class scipy.interpolate.BSpline(t, c, k, extrapolate=True, axis=0)[原始碼]#

B-spline 基底的單變數 spline。

\[S(x) = \sum_{j=0}^{n-1} c_j B_{j, k; t}(x)\]

其中 \(B_{j, k; t}\) 是次數為 k 和節點為 t 的 B-spline 基底函數。

參數:
tndarray,形狀 (n+k+1,)

節點

cndarray,形狀 (>=n, …)

spline 係數

kint

B-spline 次數

extrapolatebool 或 ‘periodic’,選用

是否要外插超出基本區間 t[k] .. t[n],或是回傳 nans。若為 True,則外插作用於基本區間上的 b-spline 函數的第一個和最後一個多項式片段。若為 ‘periodic’,則使用週期性外插。預設值為 True。

axisint,選用

內插軸。預設值為零。

註解

B-spline 基底元素透過以下方式定義

\[ \begin{align}\begin{aligned}B_{i, 0}(x) = 1, \textrm{if $t_i \le x < t_{i+1}$, otherwise $0$,}\\B_{i, k}(x) = \frac{x - t_i}{t_{i+k} - t_i} B_{i, k-1}(x) + \frac{t_{i+k+1} - x}{t_{i+k+1} - t_{i+1}} B_{i+1, k-1}(x)\end{aligned}\end{align} \]

實作細節

  • 次數為 k 的 spline 至少需要 k+1 個係數,因此 n >= k+1。額外的係數,c[j] 其中 j > n,會被忽略。

  • 次數為 k 的 B-spline 基底元素在基本區間 t[k] <= x <= t[n] 上形成單位劃分。

參考文獻

[2]

Carl de Boor, A practical guide to splines, Springer, 2001.

範例

將 B-spline 的遞迴定義翻譯成 Python 程式碼,我們得到

>>> def B(x, k, i, t):
...    if k == 0:
...       return 1.0 if t[i] <= x < t[i+1] else 0.0
...    if t[i+k] == t[i]:
...       c1 = 0.0
...    else:
...       c1 = (x - t[i])/(t[i+k] - t[i]) * B(x, k-1, i, t)
...    if t[i+k+1] == t[i+1]:
...       c2 = 0.0
...    else:
...       c2 = (t[i+k+1] - x)/(t[i+k+1] - t[i+1]) * B(x, k-1, i+1, t)
...    return c1 + c2
>>> def bspline(x, t, c, k):
...    n = len(t) - k - 1
...    assert (n >= k+1) and (len(c) >= n)
...    return sum(c[i] * B(x, k, i, t) for i in range(n))

請注意,這是一種低效率(如果簡單明瞭)的評估 B-spline 的方法 — 這個 spline 類別以等效但效率更高的方式執行。

在這裡,我們在基本區間 2 <= x <= 4 上建構一個二次 spline 函數,並與評估 spline 的樸素方法進行比較

>>> from scipy.interpolate import BSpline
>>> k = 2
>>> t = [0, 1, 2, 3, 4, 5, 6]
>>> c = [-1, 2, 0, -1]
>>> spl = BSpline(t, c, k)
>>> spl(2.5)
array(1.375)
>>> bspline(2.5, t, c, k)
1.375

請注意,在基本區間之外,結果會有所不同。這是因為 BSpline 外插作用於基本區間上的 B-spline 函數的第一個和最後一個多項式片段。

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> fig, ax = plt.subplots()
>>> xx = np.linspace(1.5, 4.5, 50)
>>> ax.plot(xx, [bspline(x, t, c ,k) for x in xx], 'r-', lw=3, label='naive')
>>> ax.plot(xx, spl(xx), 'b-', lw=4, alpha=0.7, label='BSpline')
>>> ax.grid(True)
>>> ax.legend(loc='best')
>>> plt.show()
../../_images/scipy-interpolate-BSpline-1.png
屬性:
tndarray

節點向量

cndarray

spline 係數

kint

spline 次數

extrapolatebool

若為 True,則外插作用於基本區間上的 b-spline 函數的第一個和最後一個多項式片段。

axisint

內插軸。

tcktuple

等同於 (self.t, self.c, self.k) (唯讀)。

方法

__call__(x[, nu, extrapolate])

評估 spline 函數。

basis_element(t[, extrapolate])

回傳 B-spline 基底元素 B(x | t[0], ..., t[k+1])

derivative([nu])

回傳代表導數的 B-spline。

antiderivative([nu])

回傳代表反導數的 B-spline。

integrate(a, b[, extrapolate])

計算 spline 的定積分。

insert_knot(x[, m])

x 插入一個新的節點,其重數為 m

construct_fast(t, c, k[, extrapolate, axis])

建構一個 spline,不進行檢查。

design_matrix(x, t, k[, extrapolate])

回傳設計矩陣作為 CSR 格式的稀疏陣列。

from_power_basis(pp[, bc_type])

從冪基底中的分段多項式建構 B-spline 基底中的多項式。