插值是一种通过已知的、离散的数据点推算一定范围内的新数据点的方法。
插值法常用于函数拟合中,也就是给定函数
f(x) 的图像上的一些点,来拟合
f(x) 的表达式。
通常我们尝试用多项式去拟合
f(x),即多项式插值。
多项式插值的一般形式是对于已知的
n+1 个点
(x0,y0),…,(xn,yn),求形如
f(x)=i=0∑naixi 且对于
∀i=0,1,…,n 满足
f(xi)=yi 的多项式
f(x)。
常见的多项式插值算法有 Lagrange 插值与 Newton 插值。
Lagrange 插值法
对
∀i=0,1,…,n,构造
Li(x)=j=0,j=i∏nxi−xjx−xj。
容易看出,
Li(xi)=1,Li(xj)=0。
于是所求的多项式
f(x)=i=0∑nyiLi(x)。
朴素实现的时间复杂度是
O(n2)。可以利用
一些技巧优化到
O(nlog2n)。
特别地,如果已知点的横坐标是连续整数,可以做到
O(n)。
Newton 插值法
不同于 Lagrange 插值法一次性构造整个函数,Newton 插值法一项一项构造,支持
O(n) 插入新数据点。
具体地,Newton 插值多项式写成
f(x)=a0+a1(x−x0)+a2(x−x0)(x−x1)+…+an(x−x0)…(x−xn−1)。
每增加一个新点,只需要多增加一项,无需重算整个多项式,这也是它支持
O(n) 插入的原因。
系数
a0,a1,…,an 用对应阶差商进行表示。
从
x0 开始的一阶差商
f[x0,x1]=x1−x0y1−y0。
从
x0 开始的二阶差商
f[x0,x1,x2]=x2−x0f[x1,x2]−f[x0,x1]。
以此类推,从
x0 开始的
n 阶差商
f[x0,…,xn]=xn−x0f[x1,…,xn]−f[x0,…,xn−1]。
对于
∀k=0,1,…,n,
ak 即为从
x0 开始的
k 阶差商。
那么所求的多项式
f(x)=i=0∑naij=0∏i−1(x−xj)。
显然,为了计算从
x0 开始的
k 阶差商,必须先计算出从
x0,…,xj 开始的
k−j 阶的差商
(j=0,…,k−1),因此时间复杂度是
O(n2)。
更好理解的方式是构建差商表,非常直观。
从
xj 开始的
k 阶差商的计算方法为
f[xj,…,xj+k]=xj+k−xjf[xj+1,…,xj+k]−f[xj,…,xj+k−1]
误差分析
两种插值方式的误差是相同的。
考虑对于未知函数
f(x) 上的
n+1 个已知点进行多项式插值得到的拟合函数
Pn(x),设截断误差为
Rn(x),则有
Rn(x)=f(x)−Pn(x)=(n+1)!f(n+1)(ξ)i=0∏n(x−xi)
其中
ξ 为所有插值节点
xi 和求值点
x 的某个区间内,但不能确定具体值。
通常采用如下估计:
∣Rn(x)∣≤(n+1)!maxξ∈[a,b]∣f(n+1)(ξ)∣∣∏i=0n(x−xi)∣,其中
[a,b] 为插值区间。
于是只需要求出
f(n+1)(x) 在
[a,b] 上的最大值即可。
如何计算求出的近似值
Pn(x) 精确到小数点后几位:若
∣Rn(x)∣<0.5×10−k,则小数点后
k 位是精确的。
例题
已知函数
f(x)=sinx,f(0.7)=0.6442,f(0.9)=0.7833,f(1.1)=0.8912,计算
f(1.0) 的近似值,并进行误差分析。
Lagrange 插值法
Lagrange 插值多项式为:
L(x)=f(x0)L0(x)+f(x1)L1(x)+f(x2)L2(x)
其中基函数为:
L0(x)=(x0−x1)(x0−x2)(x−x1)(x−x2)=(0.7−0.9)(0.7−1.1)(1.0−0.9)(1.0−1.1)=−0.125
L1(x)=(x1−x0)(x1−x2)(x−x0)(x−x2)=(0.9−0.7)(0.9−1.1)(1.0−0.7)(1.0−1.1)=0.75
L2(x)=(x2−x0)(x2−x1)(x−x0)(x−x1)=(1.1−0.7)(1.1−0.9)(1.0−0.7)(1.0−0.9)=0.375
综上有
L(1.0)=0.6442×(−0.125)+0.7833×0.75+0.8912×0.375=0.84115。
Newton 插值法
构造差商表:
| x | f(x) | 一阶差商 | 二阶差商 |
|---|
| 0.7 | 0.6442 | 0.6955 | -0.39 |
| 0.9 | 0.7833 | 0.5395 | - |
| 1.1 | 0.8912 | - | - |
从
x0 开始的一阶差商
f[x0,x1]=x1−x0f(x1)−f(x0)=0.6955
从
x1 开始的一阶差商
f[x1,x2]=x2−x1f(x2)−f(x1)=0.5395
从
x0 开始的二阶差商
f[x0,x1,x2]=x2−x0f[x1,x2]−f[x0,x1]=−0.39
近似值
P2(x)=f(x0)+f[x0,x1](x−x0)+f[x0,x1,x2](x−x0)(x−x1)=0.6442+0.6955×(x−0.7)−0.39×(x−0.7)(x−0.9)。
代入
x=1.0 可知
P2(1.0)=0.84115,故计算出
sin(1.0) 的近似值为
0.84115。
误差分析
计算截断误差
R(x)=f(x)−P2(x)=3!f(3)(ξ)(x−x0)(x−x1)(x−x2)。
又
f(3)(x)=−cosx,∣f(3)(x)∣≤1,故
∣R2(x)∣≤3!1∣(x−x0)(x−x1)(x−x2)∣,代入
x=1.0,x0=0.7,x1=0.9,x2=1.1 可知
∣R2(1.0)∣≤0.5×10−3。
故计算结果精确到小数点后三位。