多项式插值的缺陷+Runge现象
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
def runge_function(x):
"""
计算Runge函数的值
参数:
x (float or array-like): 输入的x值或x值数组
返回:
float or array-like: 对应的Runge函数值
"""
return 1 / (1 + 25 * x**2)
def lagrange_interpolation(x, nodes, func):
"""
计算拉格朗日插值多项式在点x处的值
参数:
x (float or array-like): 输入的x值或x值数组
nodes (array-like): 插值节点
func (function): 被插值函数
返回:
float or array-like: 拉格朗日插值多项式在点x处的值
"""
n = len(nodes) # 插值节点的数量
L = np.zeros_like(x) # 初始化插值结果数组
for i in range(n):
# 计算拉格朗日基函数Li
Li = np.ones_like(x)
for j in range(n):
if j != i:
Li *= (x - nodes[j]) / (nodes[i] - nodes[j])
L += func(nodes[i]) * Li # 累加每个基函数的贡献
return L
# 设置插值区间和点数
a, b = -1, 1 # 插值区间为[-1, 1]
num_points = 15 # 插值节点数量
# 生成等距节点
x_equidistant = np.linspace(a, b, num_points) # 在区间[a, b]内均匀生成num_points个节点
y_equidistant = runge_function(x_equidistant) # 计算这些节点对应的Runge函数值
# 生成Chebyshev节点
k = np.arange(num_points) # 生成从0到num_points-1的整数数组
x_chebyshev = np.cos((2 * k + 1) * np.pi / (2 * num_points + 2)) # 计算内部Chebyshev节点
x_chebyshev = (x_chebyshev + 1) / 2 * (b - a) + a # 将内部Chebyshev节点映射到区间[a, b]
y_chebyshev = runge_function(x_chebyshev) # 计算这些节点对应的Runge函数值
# 生成密集的测试点用于绘图
x_test = np.linspace(a, b, 1000) # 在区间[a, b]内均匀生成1000个测试点
y_true = runge_function(x_test) # 计算这些测试点对应的Runge函数值
# 计算插值结果
y_interp_equidistant = lagrange_interpolation(x_test, x_equidistant, runge_function) # 使用等距节点进行插值
y_interp_chebyshev = lagrange_interpolation(x_test, x_chebyshev, runge_function) # 使用Chebyshev节点进行插值
# 绘制图形
plt.figure(figsize=(14, 6)) # 创建一个大小为14x6的图形
# 等距节点插值
plt.subplot(1, 2, 1) # 创建1行2列的子图,选择第一个子图
plt.plot(x_test, y_true, label='真实函数 $f(x)$', color='black') # 绘制真实函数曲线
plt.plot(x_test, y_interp_equidistant, label=f'{num_points}阶等距节点插值', color='red') # 绘制等距节点插值曲线
plt.scatter(x_equidistant, y_equidistant, color='red', label='插值节点') # 绘制等距节点
plt.title('Runge现象:等距节点高阶插值') # 设置子图标题
plt.xlabel('x') # 设置x轴标签
plt.ylabel('f(x)') # 设置y轴标签
plt.legend() # 显示图例
plt.grid(True) # 显示网格
# Chebyshev节点插值
plt.subplot(1, 2, 2) # 选择第二个子图
plt.plot(x_test, y_true, label='真实函数 $f(x)$', color='black') # 绘制真实函数曲线
plt.plot(x_test, y_interp_chebyshev, label=f'{num_points}阶Chebyshev节点插值', color='green') # 绘制Chebyshev节点插值曲线
plt.scatter(x_chebyshev, y_chebyshev, color='green', label='插值节点') # 绘制Chebyshev节点
plt.title('使用Chebyshev节点的高阶插值') # 设置子图标题
plt.xlabel('x') # 设置x轴标签
plt.ylabel('f(x)') # 设置y轴标签
plt.legend() # 显示图例
plt.grid(True) # 显示网格
plt.tight_layout() # 自动调整子图参数,使其填充整个图像区域
plt.show() # 显示图形
posted on 2025-03-12 13:03 Indian_Mysore 阅读(19) 评论(0) 收藏 举报
浙公网安备 33010602011771号