分段二次插值例题_计算方法(2)——插值法(附Python程序)

本文介绍了插值法中的拉格朗日、牛顿和Hermite插值,分别展示了它们的原理和Python实现。通过插值法,可以构建经过数据点的函数。拉格朗日插值涉及线性和二次插值,牛顿插值利用差分表和差商,Hermite插值则要求函数值和导数值相等。文章还探讨了龙格现象及其避免方法,预告了分段插值的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一些数据,生成函数的方式有两种:插值,回归。

插值而得到的函数通过数据点,回归得到的函数不一定通过数据点。

下面给出拉格朗日插值,牛顿插值Hermite插值的程序,

具体原理可参考课本,不再赘述。

拉格朗日插值法

线性插值 一次精度 需要2个节点

二次插值 二次精度 需要3个节点

n次插值 n次精度 需要n+1个节点

拉格朗日插值代码段(根据传入数据自动判断次数):

# 返回多项式
def p(x,a):
    """
    p(x,a)是x的函数,a是各幂次的系数
    """
    s = 0
    for i in range(len(a)):
        s += a[i]*x**i
    return s

# n次拉格朗日插值
def lagrange_interpolate(x_list,y_list,x): 
    """
    x_list 待插值的x元素列表
    y_list 待插值的y元素列表
    插值以后整个lagrange_interpolate是x的函数
    """
    if len(x_list) != len(y_list):
        raise ValueError("list x and list y is not of equal length!")
    # 系数矩阵
    A = []
    for i in range(len(x_list)):
        A.append([])
        for j in range(len(x_list)):
            A[i].append(pow(x_list[i],j))
    b = []
    for i in range(len(x_list)):
        b.append([y_list[i]])
    # 求得各阶次的系数
    a = lu_solve(A, b) # 用LU分解法解线性方程组,可以使用numpy的类似函数
    a = transpose(a)[0] # change col vec a into 1 dimension
    val = p(x,a)
    print(x,val)
    return val

其中lu_solve(A,b)是自己写的轮子,可以用numpy的numpy.linalg.sovle(A,b)来代替

到后面会有一期讲矩阵方程直接法,会有讲到如何写lu_solve()

看一看插值的效果如何

import numpy as np
import matplotlib.pyplot as plt
# 待插值的元素值
x_points = [0,1,2,3,4,5]
y_points = [1,5,4,8,7,12]
# 拉格朗日插值
x = np.linspace(0,5)
y = list(map(lambda t: lagrange_interpolate(x_points,y_points,t),x))
# 画图
plt.scatter(x_points,y_points,color = "orange")
p
### Hermite 插值法概述 Hermite 插值是一种特殊的多项式插值方法,它不仅要求在给定节点处函数值相等,还要求导数值也相等。这使得 Hermite 插值能够更好地逼近原函数的形状[^3]。 #### 数学定义 对于给定的一组互不相同的节点 \( x_0, x_1, \ldots, x_n \),以及对应的函数值 \( f(x_i) = y_i \) 和导数值 \( f'(x_i)=m_i\) ,存在唯一的次数不超过 \( 2n+1 \) 的多项式 \( H_{2n+1}(x) \),满足: \[ H_{2n+1}(x_k) = y_k,\quad k=0,1,...,n\] \[ H'_{2n+1}(x_k) = m_k ,\quad k=0,1,...,n\] 该多项式的表达形式可以写成如下拉格朗日型基函数的形式: \[ H_{2n+1}(x) = \sum^n_{i=0}y_i h_i (x)+\sum ^{n}_{j=0}m_j s_j (x)\] 其中, \[h_i (x)=(1-2l'_i (x)(x-x_i ))(l_i (x))^2\] \[s_i (x)=(x-x_i )(l_i (x))^2\] 这里 \( l_i (x) \) 是 Lagrange 基本多项式。 #### 实现方式 Matlab 提供了 `pchip` 函数用于分段三次 Hermite 插值,而更通用的方式可以通过编写自定义代码来实现上述公式的计算过程。下面是一个简单的 Python 版本的例子: ```python import numpy as np from scipy.interpolate import CubicHermiteSpline def hermite_interpolation(x_data, y_data, dydx_data, x_new): spline = CubicHermiteSpline(x=x_data, y=y_data, dydx=dydx_data) return spline(x_new) # Example usage: x_points = np.array([0, 1, 2]) y_values = np.sin(x_points) derivatives_at_x = np.cos(x_points) new_x = np.linspace(min(x_points), max(x_points)) interpolated_y = hermite_interpolation(x_points, y_values, derivatives_at_x, new_x) ``` 这段代码展示了如何利用 SciPy 库中的 `CubicHermiteSpline` 类来进行 Hermite 插值操作[^4]。 #### 示例 假设有一个已知的数据集 {(-π/2,-1),(0,0),(π/2,1)} 并且知道各点处的一阶导数分别为 {-√2/2,1, √2/2 } 。那么就可以通过上面提到的方法构建一个合适的 Hermite 多项式去近似原始数据并绘制图像比较两者之间的差异。 #### 用途 Hermite 插值广泛应用于工程领域内的各种问题求解当中,尤其是在那些需要保持光滑性和连续性的场合下特别有用。比如,在计算机图形学中用来创建平滑过渡的效果;或是当处理物理现象时,如果希望得到既符合实际又具有良好特性的数学模型,则可以选择这种方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值