分段线性插值
全局插值的缺陷
高次多项式全局插值存在两个根本缺陷:
- Runge 现象:加密节点并不能保证插值多项式 φn(x) 收敛到原函数 f(x),在区间端点附近可能产生剧烈振荡。
- 凹凸性无法保证:实际测量数据中,相邻节点之间的函数凹凸性是确定的;但高次多项式插值无法保持这一物理合理性。
实际工程中大多采用分段低次插值,分段光滑的低次逼近效果一般优于任意光滑的高次多项式逼近。
分段线性插值定义
在区间 [a,b] 上给定节点
a=x0<x1<⋯<xn=b
以及各节点处的函数值 yi=f(xi),i=0,1,…,n。
分段线性插值函数 φn(x) 满足:
- 插值条件:φ(xi)=yi,i=0,1,…,n
- 线性条件:φ(x) 在每个小区间 [xi,xi+1] 上是一次多项式
也即依次连接数据点 (xi,yi) 形成的折线。
分段线性插值基函数构造
分段线性插值函数通过构造基函数 lj(x),j=0,1,…,n 来表达:
端点基函数:
l0(x)=⎩⎨⎧x0−x1x−x1,0,x∈[x0,x1]x∈(x1,xn]
ln(x)=⎩⎨⎧xn−xn−1x−xn−1,0,x∈[xn−1,xn]x∈[x0,xn−1)
内部节点基函数(1≤j≤n−1):
lj(x)=⎩⎨⎧xj−xj−1x−xj−1,xj−xj+1x−xj+1,0,x∈[xj−1,xj]x∈(xj,xj+1]x∈[x0,xj−1)∪(xj+1,xn]
注:每个 lj(x) 形如 hat,在 xj 处取值为 1,在相邻节点处为 0,支撑集仅为 [xj−1,xj+1],这是分段插值局部性的体现。
插值函数总表达式:
φn(x)=j=0∑nyjlj(x)
分段线性插值误差估计
定理:设 f(x)∈C2[a,b],则分段线性插值余项满足
∣Rn(x)∣≡∣f(x)−φn(x)∣≤8h2M2
其中 h=max0≤i≤n−1∣xi+1−xi∣ 为最大步长,M2=maxa≤x≤b∣f′′(x)∣。
显然当 h→0 时,误差趋于 0,确保收敛。
证明:
在每个子区间 [xi,xi+1] 上,φn(x) 即为线性插值 L1(x),故:
f(x)−φn(x)=2f′′(ξ)(x−xi)(x−xi+1),ξ∈(xi,xi+1)
令 hi=xi+1−xi,x=xi+thi (t∈[0,1]),则:
(x−xi)(x−xi+1)=hi2t(t−1)
而 t(t−1) 在 [0,1] 上的最大绝对值为 41。因此:
∣f(x)−φn(x)∣≤2M2⋅4hi2≤8M2h2
对所有子区间一致成立,即得证。
注:分段线性插值的局限是在节点处导数不连续,整体仅为 C0 光滑。
Hermite 插值
动机与思想
分段线性插值的导函数在节点处不连续,无法满足需要光滑曲线的工程应用。
Hermite 插值则是在给定节点上取已知函数值,而且同时取已知导数值,从而提升曲线整体光滑性。
两节点一阶 Hermite 插值
问题表述
给定 x0,x1 及对应的 y0,y1,y0′,y1′,构造次数不超过 3 次的多项式 H(x) 使得:
H(x0)=y0,H(x1)=y1,H′(x0)=y0′,H′(x1)=y1′
4 个约束条件显然能唯一确定 3 次多项式。
基函数构造
令 H(x)=y0α0(x)+y1α1(x)+y0′β0(x)+y1′β1(x),各基函数满足:
| 基函数 | 在 x0 | 在 x1 | 导数在 x0 | 导数在 x1 |
|---|
| α0(x) | 1 | 0 | 0 | 0 |
| α1(x) | 0 | 1 | 0 | 0 |
| β0(x) | 0 | 0 | 1 | 0 |
| β1(x) | 0 | 0 | 0 | 1 |
从而:
α0(x)=(1+2x1−x0x−x0)(x0−x1x−x1)2=(1+2t)s2
α1(x)=(1+2x0−x1x−x1)(x1−x0x−x0)2=(1+2s)t2
β0(x)=(x−x0)(x0−x1x−x1)2=hts2
β1(x)=(x−x1)(x1−x0x−x0)2=(−h)st2
其中不明所以的公式见 两节点多阶 Hermite 插值。
误差估计
R(x)=f(x)−H(x)=4!f(4)(ξ)(x−x0)2(x−x1)2
∣R(x)∣≤384h4M4,h=x1−x0,M4=a≤x≤bmax∣f(4)(x)∣
注:线性插值误差为 O(h2),Hermite 插值误差为 O(h4),精度大幅提升。
两节点多阶 Hermite 插值
问题表述
设插值区间 [x0,x1],记
h=x1−x0,t=hx−x0
则 x=x0↔t=0,x=x1↔t=1,且 dxd=h1dtd。
节点处给定条件数:
- x0 侧:m0 个(函数值及前 m0−1 阶导数)
- x1 侧:m1 个(函数值及前 m1−1 阶导数)
插值多项式总次数为 m0+m1−1。
负责 x0 处 k 阶导数(0≤k≤m0−1)的基函数记为 ϕ0,k(x),满足:
⎩⎨⎧ϕ0,k(j)(x0)=δjk,ϕ0,k(j)(x1)=0,0≤j≤m0−10≤j≤m1−1
负责 x1 处 k 阶导数(0≤k≤m1−1)的基函数记为 ϕ1,k(x),满足:
⎩⎨⎧ϕ1,k(j)(x0)=0,ϕ1,k(j)(x1)=δjk,0≤j≤m0−10≤j≤m1−1
基函数构造
x0 侧基函数:
ϕ0,k(x)=tk(1−t)m1Pm0−1−k(t)
其中
Pm0−1−k(t)=k!hki=0∑m0−1−k(m1−1m1+i−1)ti
x1 侧基函数:
ϕ1,k(x)=(1−t)ktm0Qm1−1−k(1−t)
其中
Qm1−1−k(s)=k!(−h)ki=0∑m1−1−k(m0−1m0+i−1)si
证明思路:
对 x0 侧基函数,由零点定理:
- x1 处 m1 个条件为 0 ⇒ 必含因子 (1−t)m1
- x0 处前 k−1 阶导数为 0 ⇒ 必含因子 tk
总次数 m0+m1−1 已用去 k+m1,剩余 m0−1−k 次由待定多项式 Pm0−1−k(t) 填补。因此设:
ϕ0,k(x)=tk(1−t)m1Pm0−1−k(t)
定义 G(t)=(1−t)m1Pm0−1−k(t),则 ϕ0,k=tkG(t)。
由 x0 处导数条件,对 0≤j≤m0−1 要求:
hj1dtjdj[tkG(t)]t=0=δjk
对 tkG(t) 用 Leibniz 法则。在 t=0 处,dtidi(tk)=0 仅当 i=k。因此:
- 若 j<k:和式中 i≤j<k,所有项为 0
- 若 j≥k:仅 i=k 项非零,值为
dtjdj[tkG(t)]t=0=(kj)k!G(j−k)(0)
代入归一化条件:
| j | 条件 | 结果 |
|---|
| j=k | hk1⋅k!G(0)=1 | G(0)=k!hk |
| j=k+1,…,m0−1 | hj1⋅(kj)k!G(j−k)(0)=0 | G(1)(0)=⋯=G(m0−1−k)(0)=0 |
等价于:
G(t)≡k!hk(modtm0−k)
由 G(t)=(1−t)m1P(t),得:
P(t)≡k!hk(1−t)−m1(modtm0−k)
广义二项式展开:
(1−t)−m1=i=0∑∞(m1−1m1+i−1)ti
截断至 tm0−1−k 次:
Pm0−1−k(t)=k!hki=0∑m0−1−k(m1−1m1+i−1)ti
对 x1 侧,作替换 s=1−t(即 x1↔s=0),问题完全对称。
互换 m0↔m1 并注意 dxd=−h1dsd 带来的 (−1)k。
归一化条件要求 Q(0)=k!(−h)k,即得 ϕ1,k(x) 的显式形式。
插值多项式:
给定 f(j)(x0)(0≤j≤m0−1) 和 f(j)(x1)(0≤j≤m1−1),则
H(x)=k=0∑m0−1f(k)(x0)ϕ0,k(x)+k=0∑m1−1f(k)(x1)ϕ1,k(x)
误差估计
若 f∈Cm0+m1[x0,x1],则
R(x)=f(x)−H(x)=(m0+m1)!f(m0+m1)(ξ)(x−x0)m0(x−x1)m1,ξ∈(x0,x1)
退化特例
| 情形 | 结果 |
|---|
| m1=1 | P(t)=k!hk⋅1−t1−tm0−k,代回得 ϕ0,k=k!hk(tk−tm0) |
| m0=m1=2,k=0 | P1(t)=1+2t,ϕ0,0=(1−t)2(1+2t),即标准 Hermite h0(0) |
| m0=m1=2,k=1 | P0(t)=h,ϕ0,1=ht(1−t)2,即标准 Hermite h0(1) |
多节点分段一阶 Hermite 插值
为防止插值多项式次数过高引入 Runge 现象,实际使用多节点分段一阶 Hermite 插值:
在每个小区间上用两节点 Hermite 公式,同时保证全局函数的一阶导数连续性(C1 光滑)。
问题表述
给定函数表:
| x | x0 | x1 | ⋯ | xn |
|---|
| y | y0 | y1 | ⋯ | yn |
| y′ | m0 | m1 | ⋯ | mn |
构造多节点分段一阶 Hermite 插值函数 H(x) 满足:
- H(xi)=yi,H′(xi)=mi(i=0,1,…,n)
- 在每个小区间 [xi,xi+1] 上是不超过三次的多项式
基函数构造
记步长 hi=xi+1−xi(i=0,1,…,n−1)。在区间 [xi,xi+1] 上定义局部变量
ti=hix−xi,si=hixi+1−x=1−ti,i=0,1,…,n−1.
全局插值函数写成
H(x)=i=0∑nyiαi(x)+i=0∑nmiβi(x),
其中 αi(x) 为函数值基函数,βi(x) 为导数值基函数。
端点基函数:
左端点 x0 的基函数仅在 [x0,x1] 上非零:
α0(x)=⎩⎨⎧(1+2t0)s02,0,x∈[x0,x1],otherwise,
β0(x)=⎩⎨⎧h0t0s02,0,x∈[x0,x1],otherwise.
右端点 xn 的基函数仅在 [xn−1,xn] 上非零:
αn(x)=⎩⎨⎧(1+2sn−1)tn−12,0,x∈[xn−1,xn],otherwise,
βn(x)=⎩⎨⎧−hn−1sn−1tn−12,0,x∈[xn−1,xn],otherwise.
内部节点基函数(i=1,2,…,n−1):
内部节点 xi 的基函数由左右两支拼接而成。左支位于 [xi−1,xi](以 xi 为区间右端点),右支位于 [xi,xi+1](以 xi 为区间左端点):
αi(x)=⎩⎨⎧(1+2si−1)ti−12,(1+2ti)si2,0,x∈[xi−1,xi],x∈[xi,xi+1],otherwise,
βi(x)=⎩⎨⎧−hi−1si−1ti−12,hitisi2,0,x∈[xi−1,xi],x∈[xi,xi+1],otherwise.
误差估计
∣R(x)∣=∣f(x)−H(x)∣≤384h4M4
其中 h=maxi∣xi+1−xi∣,M4=max∣f(4)(x)∣。
注:与两节点三次相同的误差阶 O(h4),但现在是分段的,分段步长 h 可以很小,精度更佳。
多节点全局一阶 Hermite 插值
问题表述
对 n+1 个互异节点 x0,x1,…,xn,已知各节点处的函数值 yi=f(xi) 及一阶导数值 yi′=f′(xi),构造次数不超过 2n+1 的多项式 H(x),满足
H(xi)=yi,H′(xi)=yi′,i=0,1,…,n.
基函数构造
定义 ωn(x)=∏i=0n(x−xi),Lagrange 基函数 li(x)=(x−xi)ωn′(xi)ωn(x),
则 Hermite 基函数为:
αi(x)=(1−ωn′(xi)ωn′′(xi)(x−xi))li2(x),
βi(x)=(x−xi)li2(x).
插值公式:
H(x)=i=0∑n(yiαi(x)+yi′βi(x)).
误差估计
若 f∈C2n+2[a,b],则余项为:
R(x)=f(x)−H(x)=(2n+2)!f(2n+2)(ξ)ωn2(x),ξ∈(a,b).
多节点全局多阶 Hermite 插值
问题表述
设 n+1 个互异节点 x0,x1,…,xn,在节点 xi 处给定 mi 个插值条件,即已知 f(j)(xi)(0≤j≤mi−1,i=0,1,…,n)。
构造次数不超过 N=(∑i=0nmi)−1 的插值多项式 H(x),满足
H(j)(xi)=f(j)(xi),0≤j≤mi−1,i=0,1,…,n.
基函数构造
负责 xi 处 k 阶导数(0≤k≤mi−1)的基函数记为 ϕi,k(x),满足
ϕi,k(j)(xp)=δipδjk,0≤j≤mp−1,p=0,1,…,n.
插值多项式:
H(x)=i=0∑nk=0∑mi−1f(k)(xi)ϕi,k(x).
误差估计
若 f∈CN+1[a,b],则
R(x)=f(x)−H(x)=(N+1)!f(N+1)(ξ)i=0∏n(x−xi)mi,ξ∈(a,b),
其中 N+1=∑i=0nmi。
样条插值
动机
多节点分段一阶 Hermite 插值只保证 C1,而样条插值在不需要提前给定导数值的情况下,通过方程组自动确定节点导数,实现 C2 光滑。
三次样条插值问题
在 [a,b] 上取节点 a=x0<x1<⋯<xn=b,给定 f(xi)=yi,构造三次样条插值函数 s(x) 满足:
- 插值条件:s(xi)=yi,i=0,1,…,n
- 不高于三次:s(x) 在每个小区间 [xi,xi+1] 上是不高于三次的多项式
- 二阶导连续:s(x)∈C[a,b]2
注:与分段三次 Hermite 插值相比,Hermite 需要预先知道各节点导数值 yi′,而样条插值的 yi′ 通过 C2 条件自动确定。
三次样条插值函数构造
第一步:局部 Hermite 表示
在每个子区间 [xi,xi+1](记 hi=xi+1−xi),用两节点 Hermite 公式表示 s(x),其中 yi′=s′(xi) 为待定量:
s(x)=(1+2xi+1−xix−xi)(xi−xi+1x−xi+1)2yi+(1+2xi−xi+1x−xi+1)(xi+1−xix−xi)2yi+1+(x−xi)(xi−xi+1x−xi+1)2yi′+(x−xi+1)(xi+1−xix−xi)2yi+1′
第二步:利用 C2 条件
对 s(x) 求二阶导,在内部节点 xi(i=1,…,n−1)处要求左右二阶导数相等:s′′(xi+)=s′′(xi−)。
计算得:
s′′(xi+)=−hi26yi+hi26yi+1−hi4yi′−hi2yi+1′
s′′(xi−)=hi−126yi−1−hi−126yi+hi−12yi−1′+hi−14yi′
令两者相等,整理后得到关于 yi−1′,yi′,yi+1′ 的三对角方程:
(1−αi)yi−1′+2yi′+αiyi+1′=βi,i=1,2,…,n−1
其中:
αi=hi−1+hihi−1,βi=3(hi−11−αi(yi−yi−1)+hiαi(yi+1−yi))
注:方程数为 n−1,未知数为 n+1 个,还需2个边界条件才能封闭方程组。
三类边界条件
| 边界类型 | 条件 | 补充方程 |
|---|
| 固支边界 | f′(x0)=y0′,f′(xn)=yn′ 已知 | 直接代入,方程数减为 n−1 |
| 自然边界 | s′′(x0)=0,s′′(xn)=0 | 2y0′+y1′=h03(y1−y0) 及对称式 |
| 周期边界 | f(x0)=f(xn),f′(x0)=f′(xn),f′′(x0)=f′′(xn) | y0′=yn′ 及额外方程 |
注:周期边界有用的条件是后两个,第一个条件应是数据已经满足的,否则不能使用周期边界条件。
自然边界条件下的完整线性方程组:
⎩⎨⎧2y0′+α0y1′=β0≡3(y1−y0)/h0(1−α1)y0′+2y1′+α1y2′=β1⋮(1−αn−1)yn−2′+2yn−1′+αn−1yn′=βn−1(1−αn)yn−1′+2yn′=βn≡3(yn−yn−1)/hn−1
这里约定 α0=1,αn=0。
追赶法求解
该三对角方程组通过追赶法高效求解:
前向消元(追)
由第一个方程得 y0′=A0y1′+B0,其中:
A0=−2α0,B0=2β0
递推关系(i=0,1,…,n−1):
yi′=Aiyi+1′+Bi
Ai=−2+(1−αi)Ai−1αi,Bi=2+(1−αi)Ai−1βi−(1−αi)Bi−1
后向回代(赶)
yn′=Bn=2+(1−αn)An−1βn−(1−αn)Bn−1
然后依次计算 yn−1′,yn−2′,…,y0′:
yi′=Aiyi+1′+Bi
算法实现
def cubic_spline_natural(x, y):
"""自然边界条件三次样条插值"""
n = len(x) - 1
h = [x[i+1] - x[i] for i in range(n)] # 子区间长度
# 计算 alpha, beta
alpha = [0.0] * (n + 1)
beta = [0.0] * (n + 1)
alpha[0] = 1.0 # 自然边界约定
beta[0] = 3.0 * (y[1] - y[0]) / h[0]
for i in range(1, n):
alpha[i] = h[i-1] / (h[i-1] + h[i])
beta[i] = 3.0 * ((1 - alpha[i]) * (y[i] - y[i-1]) / h[i-1]
+ alpha[i] * (y[i+1] - y[i]) / h[i])
alpha[n] = 0.0 # 自然边界约定
beta[n] = 3.0 * (y[n] - y[n-1]) / h[n-1]
# 前向消元(追)
A = [0.0] * n
B = [0.0] * (n + 1)
A[0] = -alpha[0] / 2.0
B[0] = beta[0] / 2.0
for i in range(1, n):
denom = 2.0 + (1 - alpha[i]) * A[i-1]
A[i] = -alpha[i] / denom
B[i] = (beta[i] - (1 - alpha[i]) * B[i-1]) / denom
# 后向回代(赶)
m = [0.0] * (n + 1) # 各节点处的一阶导数值
denom_n = 2.0 + (1 - alpha[n]) * A[n-1]
m[n] = (beta[n] - (1 - alpha[n]) * B[n-1]) / denom_n
for i in range(n-1, -1, -1):
m[i] = A[i] * m[i+1] + B[i]
return m
def eval_spline(x, y, m, t):
"""在 t 处求值"""
# 找到 t 所在子区间 [x_i, x_{i+1}]
i = max(0, min(len(x)-2, next((j for j in range(len(x)-1) if x[j+1] >= t), len(x)-2)))
h_i = x[i+1] - x[i]
u = (t - x[i]) / h_i
# Hermite 基函数
h00 = (1 + 2*u) * (1 - u)**2
h10 = u * (1 - u)**2
h01 = u**2 * (3 - 2*u)
h11 = u**2 * (u - 1)
return h00*y[i] + h10*h_i*m[i] + h01*y[i+1] + h11*h_i*m[i+1]
注:
- 追赶法时间复杂度为 O(n),远优于直接解三对角线性方程组的通用方法。
- 三对角矩阵严格对角占优(每行对角元素为 2,非对角元素之和 ≤1),故追赶法数值稳定。
误差估计
设 f(x)∈C[a,b]4,s(x) 为满足固支边界条件的三次样条,则:
∣f(k)(x)−s(k)(x)∣≤CkM4h4−k,k=0,1,2,3
| k | Ck | 物理含义 |
|---|
| 0 | 5/384 | 函数值误差,阶 O(h4) |
| 1 | 1/24 | 一阶导误差,阶 O(h3) |
| 2 | 3/8 | 二阶导误差,阶 O(h2) |
| 3 | (β+β−1)/2 | 三阶导误差,β=maxhi/minhi |
收敛性:当 h→0 时,s(k)(x)→f(k)(x)(k=0,1,2),当 β 有界时三阶导也收敛。
三种插值方法对比
| 方法 | 光滑阶 | 误差阶 | 需要 yi′ | 特点 |
|---|
| 分段线性插值 | C0 | O(h2) | 否 | 简单,导数不连续 |
| 分段三次 Hermite | C1 | O(h4) | 是 | 一阶导连续,精度高 |
| 三次样条插值 | C2 | O(h4) | 否 | 二阶导连续,最光滑 |
复杂度:
| 方法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|
| 分段线性插值(求值) | O(logn) | O(n) | 二分搜索定位区间 |
| 分段三次 Hermite(求值) | O(logn) | O(n) | 同上,系数已知 |
| 三次样条(建立) | O(n) | O(n) | 追赶法解三对角系统 |
| 三次样条(求值) | O(logn) | O(n) | 建立后同 Hermite |
注:Hermite 插值在已知导数信息时精度与样条相同,但样条通过光滑性条件自动确定导数,更适合只有函数值的情形。
Bézier 曲线与字体设计
Bézier 曲线定义
定义:给定控制点列 {Pi},i=0,1,…,n,n 次 Bézier 曲线定义为:
P(t)=i=0∑nPiBi,n(t),t∈[0,1]
其中基函数为 n 次 Bernstein 多项式:
Bi,n(t)=(in)ti(1−t)n−i
典型情形
| 次数 | 控制点数 | 曲线形状 | SVG 命令 |
|---|
| 1 次 | 2 | 直线段 | L x y |
| 2 次 | 3 | 抛物线弧 | Q x1 y1, x y |
| 3 次 | 4 | 三次曲线 | C x1 y1, x2 y2, x y |
注:SVG 中的 T x y 命令绘制二次 Bézier 曲线,控制点为前一控制点与当前起点的中心对称点,实现曲线的平滑连接。
与插值的关系
Bézier 曲线是逼近而非插值:曲线通过首末控制点,但一般不通过中间控制点。
现代字体(如 SVG、OpenType 格式)使用分段 Bézier 曲线描述字形轮廓,每段二次或三次曲线的拼接要求导数连续,这正是 Hermite 插值思想的工程应用。