利用Python进行一维插值处理

今天给大家介绍几种插值方法:线性插值分段多项式插值,线性插值、多项式插值、样条插值、拉格朗日插值、牛顿插值,并提供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) 是唯一的,并且通过每个已知点。

拉格朗日插值多项式的形式为:

p=\sum_{i=0}^{n}yi*Li(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​∏n​xi​−xj​x−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​−x0​y1​−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],其中 nx0 的长度。

例如,对于 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)=an​xn+an−1​xn−1+...+a0​,则 p[a_n, a_{n-1}, ..., a_0]

其他方法近日会持续更新,记得关注

总结

插值方法主要用于数据拟合和函数值的推算,不同的插值方法适用于不同的应用场景:

  • 拉格朗日插值和牛顿插值:适合少量数据点的插值,多项式拟合较为精确。
  • 样条插值:适合处理大量数据点,生成平滑的曲线,广泛用于图形和信号处理。
  • 线性插值和最近邻插值:简单易用,适合快速估算或在精度要求不高的场景下使用。

选择合适的插值方法应根据数据分布、插值点数量、计算效率和结果光滑性等因素综合考虑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值