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]
上形成單位劃分。
參考文獻
[1]Tom Lyche 和 Knut Morken, Spline methods, http://www.uio.no/studier/emner/matnat/ifi/INF-MAT5340/v05/undervisningsmateriale/
[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()
- 屬性:
- tndarray
節點向量
- cndarray
spline 係數
- kint
spline 次數
- extrapolatebool
若為 True,則外插作用於基本區間上的 b-spline 函數的第一個和最後一個多項式片段。
- axisint
內插軸。
tck
tuple等同於
(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 基底中的多項式。