今天给大家介绍几种插值方法:线性插值
分段多项式插值,线性插值、多项式插值、样条插值、拉格朗日插值、牛顿插值、
,并提供Python实现案例。
一维插值是指给定若干离散数据点,通过构造一个函数或多项式,使得这个函数在这些已知点上与数据完全吻合,并且在未知点上能够进行推算。这是数值分析中常用的技术,广泛应用于数据拟合、信号处理、图像处理等领域。
下面介绍一些常见的一维插值方法:
1. 拉格朗日插值
拉格朗日插值是一种经典的多项式插值方法。给定 n+1n + 1n+1 个已知点 (x0,y0),(x1,y1),…,(xn,yn)(x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)(x0,y0),(x1,y1),…,(xn,yn),拉格朗日插值多项式 P(x)P(x)P(x) 是唯一的,并且通过每个已知点。
拉格朗日插值多项式的形式为:
其中,基函数 Li(x)L_i(x)Li(x) 为:
Li(x)=∏j=0j≠inx−xjxi−xjL_i(x) = \prod_{\substack{j=0 \\ j \neq i}}^{n} \frac{x - x_j}{x_i - x_j}Li(x)=j=0j=i∏nxi−xjx−xj
这个多项式会在已知的插值点上精确地通过,并能够对其他位置进行插值计算。
优点:计算简单,适合较少的已知点。
缺点:对于较多的插值点,计算复杂度较高,可能产生震荡现象(Runge现象)。
2. 牛顿插值
牛顿插值也是一种多项式插值方法,区别在于其通过递推形式构造插值多项式。牛顿插值的优点在于,当新增数据点时,可以直接更新多项式而不必重新计算整个多项式。
牛顿插值多项式的形式为:
P(x)=a0+a1(x−x0)+a2(x−x0)(x−x1)+⋯+an(x−x0)(x−x1)…(x−xn−1)P(x) = a_0 + a_1(x - x_0) + a_2(x - x_0)(x - x_1) + \dots + a_n(x - x_0)(x - x_1)\dots(x - x_{n-1})P(x)=a0+a1(x−x0)+a2(x−x0)(x−x1)+⋯+an(x−x0)(x−x1)…(x−xn−1)
其中,系数 aia_iai 是通过已知数据点计算得到的“差商”。
优点:计算递推形式简单,增加数据点时可以增量计算。
缺点:如果数据点分布不均匀,可能产生数值不稳定的问题。
3. 样条插值
样条插值是一种分段插值方法。与多项式插值不同,样条插值通过拼接多个低次多项式来构造一个光滑的插值函数,尤其适合处理大量数据点且避免高次多项式产生的震荡问题。
最常用的是三次样条插值,即在每两个已知点之间构造一个三次多项式,同时保证多项式在拼接点处的连续性及其一阶和二阶导数的连续性。
样条插值的优点是:
- 光滑性好,尤其是三次样条,常常被用来生成平滑曲线。
- 避免了高次多项式插值可能产生的数值不稳定性和震荡问题。
4. 线性插值
线性插值是最简单的插值方法之一,它在每两个相邻的已知点之间使用一条直线来进行插值。
线性插值公式如下: 对于两个点 (x0,y0)(x_0, y_0)(x0,y0) 和 (x1,y1)(x_1, y_1)(x1,y1),当 xxx 在区间 [x0,x1][x_0, x_1][x0,x1] 内时,插值函数为:
f(x)=y0+y1−y0x1−x0(x−x0)f(x) = y_0 + \frac{y_1 - y_0}{x_1 - x_0}(x - x_0)f(x)=y0+x1−x0y1−y0(x−x0)
优点:简单,计算速度快。
缺点:插值结果不光滑,特别是在数据点间会产生折线。
5. 最近邻插值
最近邻插值是一种非常简单的方法,用来对给定点附近的值进行估计。具体做法是在已知数据点中选择与待插值点最接近的点,并直接使用该点的函数值作为插值结果。
优点:计算非常简单,适合快速估算。
缺点:不连续,插值结果不光滑,通常用于图像处理中的像素插值。
6. 分段多项式插值
分段多项式插值是介于拉格朗日插值和样条插值之间的一种方法。它在每两个相邻的数据点之间构造一个低次多项式(通常是二次或三次多项式),并在每个区间内独立拟合数据。
分段多项式插值适合处理在局部区域具有较强非线性行为的数据。
7.案例
代码如下:
import numpy as np
import pylab as plt
x0 = np.arange(1, 7); y0 = np.array([16, 18, 21, 17, 15, 12])
A = np.vander(x0)
p = np.linalg.inv(A) @ y0 #求插值多项式的系数
print('从高次幂到低次幂的系数为:', np.round(p,4))
yh = np.polyval(p, [1.5, 2.6]) #计算函数值
print('预测值为:', np.round(yh,4))
plt.plot(x0, y0, 'o') #画出已知数据点的散点
xt = np.linspace(1, 6, 100)
plt.plot(xt, np.polyval(p, xt)) #画插值曲线
plt.show()
x0 = np.arange(1, 7)
:生成已知数据的横坐标,x0
是一个从 1 到 6 的整数数组,代表自变量的值。y0 = np.array([16, 18, 21, 17, 15, 12])
:已知数据的纵坐标,y0
是对应于x0
的函数值(即y0[i]
对应x0[i]
的函数值)。
np.vander(x0)
:生成范德蒙德矩阵(Vandermonde matrix)。范德蒙德矩阵是插值多项式的一种标准矩阵,它根据x0
的值生成矩阵,每一行是对应x0
的升幂的排列。- 范德蒙德矩阵
A
的每一行的形式是[x0[i]**(n-1), x0[i]**(n-2), ..., x0[i]**1, x0[i]**0]
,其中n
是x0
的长度。
例如,对于 x0 = [1, 2, 3]
,范德蒙德矩阵可能是:
[[1, 1, 1],
[8, 4, 2, 1],
[27, 9, 3, 1]]
np.linalg.inv(A)
:求范德蒙德矩阵A
的逆矩阵。@ y0
:通过矩阵乘法将逆矩阵与已知的函数值y0
相乘,得到插值多项式的系数p
。这些系数表示多项式的各个幂次的系数,从高次幂到低次幂排列。
例如,如果多项式为 p(x)=anxn+an−1xn−1+...+a0p(x) = a_n x^n + a_{n-1} x^{n-1} + ... + a_0p(x)=anxn+an−1xn−1+...+a0,则 p
是 [a_n, a_{n-1}, ..., a_0]
。
其他方法近日会持续更新,记得关注
总结
插值方法主要用于数据拟合和函数值的推算,不同的插值方法适用于不同的应用场景:
- 拉格朗日插值和牛顿插值:适合少量数据点的插值,多项式拟合较为精确。
- 样条插值:适合处理大量数据点,生成平滑的曲线,广泛用于图形和信号处理。
- 线性插值和最近邻插值:简单易用,适合快速估算或在精度要求不高的场景下使用。
选择合适的插值方法应根据数据分布、插值点数量、计算效率和结果光滑性等因素综合考虑。