You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python实现Hermite插值求解函数近似值的习题指导

Python实现Hermite插值数值计算习题

问题说明

已知函数 $f(x)=3xe{x}-e{2x}$,完成以下两项任务:

  • a) 基于节点 $x_0=1$、$x_1=1.05$ 构造三次Hermite插值多项式,近似计算 $f(1.03)$,并对比实际误差与理论误差界;
  • b) 基于节点 $x_0=1$、$x_1=1.05$、$x_2=1.07$ 构造五次Hermite插值多项式,重复(a)的操作。

实现步骤与代码

1. 定义函数及各阶导数

首先定义原函数、各阶导数(用于插值计算和误差界推导):

import numpy as np
from scipy.optimize import minimize_scalar

# 原函数
def f(x):
    return 3 * x * np.exp(x) - np.exp(2 * x)

# 一阶导数
def f1(x):
    return 3 * np.exp(x) + 3 * x * np.exp(x) - 2 * np.exp(2 * x)

# 二阶导数
def f2(x):
    return 6 * np.exp(x) + 3 * x * np.exp(x) - 4 * np.exp(2 * x)

# 四阶导数(用于三次Hermite误差界)
def f4(x):
    return 12 * np.exp(x) + 3 * x * np.exp(x) - 16 * np.exp(2 * x)

# 六阶导数(用于五次Hermite误差界)
def f6(x):
    return 18 * np.exp(x) + 3 * x * np.exp(x) - 64 * np.exp(2 * x)

2. 三次Hermite插值(两点)

插值计算实现

# 三次Hermite插值函数
def cubic_hermite(x, x0, x1, f0, f1, f0_prime, f1_prime):
    h = x1 - x0
    # 计算Hermite基函数
    alpha0 = (1 - 2*(x - x0)/(-h)) * ((x - x1)/(-h))**2
    alpha1 = (1 - 2*(x - x1)/h) * ((x - x0)/h)**2
    beta0 = (x - x0) * ((x - x1)/(-h))**2
    beta1 = (x - x1) * ((x - x0)/h)**2
    # 插值结果
    return f0*alpha0 + f1*alpha1 + f0_prime*beta0 + f1_prime*beta1

# 节点与目标计算点
x0, x1 = 1.0, 1.05
x_target = 1.03

# 计算节点的函数值和导数值
f0, f1 = f(x0), f(x1)
f0_prime, f1_prime = f1(x0), f1(x1)

# 执行插值计算
h3_val = cubic_hermite(x_target, x0, x1, f0, f1, f0_prime, f1_prime)
true_val = f(x_target)
actual_error_cubic = abs(true_val - h3_val)

误差界计算

需要找到四阶导数在区间$[1,1.05]$上的绝对值最大值,代入误差界公式:

# 定义四阶导数绝对值函数,用于求区间最大值
def abs_f4(x):
    return abs(f4(x))

# 求解区间内的最大值
res = minimize_scalar(lambda x: -abs_f4(x), bounds=(x0, x1), method='bounded')
M4 = -res.fun

# 计算理论误差界
error_bound_cubic = M4 / 24 * abs((x_target - x0)**2 * (x_target - x1)**2)

结果输出

print("=== 三次Hermite插值结果 ===")
print(f"f(1.03)实际值: {true_val:.8f}")
print(f"插值近似值: {h3_val:.8f}")
print(f"实际误差: {actual_error_cubic:.8e}")
print(f"理论误差界: {error_bound_cubic:.8e}")

3. 五次Hermite插值(三点)

五次Hermite插值需要每个节点的函数值、一阶导、二阶导(共6个条件),通过构造方程组求解五次多项式系数:

# 构造五次Hermite插值的系数方程组
def quintic_hermite_coeffs(x_nodes, f_vals, f1_vals, f2_vals):
    # 五次多项式有6个系数a0~a5
    A = np.zeros((6, 6))
    b = np.zeros(6)
    idx = 0
    for i in range(len(x_nodes)):
        x = x_nodes[i]
        # 函数值条件
        A[idx] = [x**k for k in range(6)]
        b[idx] = f_vals[i]
        idx +=1
        # 一阶导数条件
        A[idx] = [k * x**(k-1) if k>0 else 0 for k in range(6)]
        b[idx] = f1_vals[i]
        idx +=1
        # 二阶导数条件
        A[idx] = [k*(k-1)*x**(k-2) if k>=2 else 0 for k in range(6)]
        b[idx] = f2_vals[i]
        idx +=1
    # 求解系数
    coeffs = np.linalg.solve(A, b)
    return coeffs

# 节点与目标计算点
x_nodes = [1.0, 1.05, 1.07]
x_target = 1.03

# 计算节点的函数值、一阶导、二阶导
f_vals = [f(x) for x in x_nodes]
f1_vals = [f1(x) for x in x_nodes]
f2_vals = [f2(x) for x in x_nodes]

# 求解五次多项式系数
coeffs = quintic_hermite_coeffs(x_nodes, f_vals, f1_vals, f2_vals)

# 计算插值值
h5_val = sum(coeffs[k] * x_target**k for k in range(6))
actual_error_quintic = abs(true_val - h5_val)

误差界计算

找到六阶导数在区间$[1,1.07]$上的绝对值最大值,代入误差界公式:

# 定义六阶导数绝对值函数
def abs_f6(x):
    return abs(f6(x))

# 求解区间内的最大值
res_quintic = minimize_scalar(lambda x: -abs_f6(x), bounds=(min(x_nodes), max(x_nodes)), method='bounded')
M6 = -res_quintic.fun

# 计算理论误差界
error_bound_quintic = M6 / 720 * abs((x_target - x_nodes[0])**2 * (x_target - x_nodes[1])**2 * (x_target - x_nodes[2])**2)

结果输出

print("\n=== 五次Hermite插值结果 ===")
print(f"f(1.03)实际值: {true_val:.8f}")
print(f"插值近似值: {h5_val:.8f}")
print(f"实际误差: {actual_error_quintic:.8e}")
print(f"理论误差界: {error_bound_quintic:.8e}")

结果说明

  • 三次Hermite插值的实际误差远小于理论误差界,因为误差界是基于区间导数最大值的保守估计;
  • 五次Hermite插值引入了更多节点和高阶导数信息,误差会比三次插值更小,符合数值插值的收敛特性。

内容的提问来源于stack exchange,提问作者angelabayona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:07:47