当前位置: 首页 > news >正文

数据插值:Lagrange插值方法

数据插值:Lagrange插值方法

数学理论基础

y = f ( x ) y = f(x) y=f(x)是区间 [ a , b ] [a,b] [a,b]上的实值函数, x 0 , x 1 , ⋯   , x n x_0,x_1,\cdots,x_n x0,x1,,xn [ a , b ] [a,b] [a,b]上的 n + 1 n + 1 n+1个互异节点, l i ( x ) = ∏ j = 0 , j ≠ i n ( x − x j ) ∏ j = 0 , j ≠ i n ( x i − x j ) l_i(x)=\frac{\prod_{j = 0,j\neq i}^{n}(x - x_j)}{\prod_{j = 0,j\neq i}^{n}(x_i - x_j)} li(x)=j=0,j=in(xixj)j=0,j=in(xxj) ( i = 0 , 1 , ⋯   , n ) (i = 0,1,\cdots,n) (i=0,1,,n)是拉格朗日插值基函数。

f ( x ) = ∑ i = 0 n y i l i ( x ) + f ( n + 1 ) ( ξ ) ( n + 1 ) ! ∏ i = 0 n ( x − x i ) f(x)=\sum_{i=0}^{n}y_i l_i(x)+\frac{f^{(n+1)}(\xi)}{(n+1)!} \prod_{i=0}^{n}{(x-x_i)} f(x)=i=0nyili(x)+(n+1)!f(n+1)(ξ)i=0n(xxi)

代码模板

1.插值预测值

import numpy as np


def lagrange_interpolation(x_nodes, y_nodes, x):
    """
    实现拉格朗日插值方法
    :param x_nodes: 插值节点的x坐标
    :param y_nodes: 插值节点的y坐标
    :param x: 要计算插值的点的x坐标
    :return: 在点x处的插值结果
    """
    n = len(x_nodes)
    result = 0
    for i in range(n):
        l_i = 1
        for j in range(n):
            if j != i:
                l_i *= (x - x_nodes[j]) / (x_nodes[i] - x_nodes[j])
        result += y_nodes[i] * l_i
    return result

2.插值预测函数表达式

import sympy as sp

def lagrange_polynomial(x_nodes, y_nodes):
    # 定义符号变量 x
    x = sp.symbols('x')
    n = len(x_nodes)
    # 初始化拉格朗日插值多项式为 0
    polynomial = 0
    for i in range(n):
        # 初始化拉格朗日插值基函数为 1
        l_i = 1
        for j in range(n):
            if j != i:
                # 计算拉格朗日插值基函数的每一项
                l_i *= (x - x_nodes[j]) / (x_nodes[i] - x_nodes[j])
        # 累加每一项 y_i * l_i(x) 到多项式中
        polynomial += y_nodes[i] * l_i
    # 展开多项式
    polynomial = sp.expand(polynomial)
    return polynomial

可视化插值函数与数据关系

import sympy as sp
import numpy as np
import matplotlib.pyplot as plt


def lagrange_polynomial(x_nodes, y_nodes):
    # 定义符号变量 x
    x = sp.symbols('x')
    n = len(x_nodes)
    # 初始化拉格朗日插值多项式为 0
    polynomial = 0
    for i in range(n):
        # 初始化拉格朗日插值基函数为 1
        l_i = 1
        for j in range(n):
            if j != i:
                # 计算拉格朗日插值基函数的每一项
                l_i *= (x - x_nodes[j]) / (x_nodes[i] - x_nodes[j])
        # 累加每一项 y_i * l_i(x) 到多项式中
        polynomial += y_nodes[i] * l_i
    # 展开多项式
    polynomial = sp.expand(polynomial)
    return polynomial


# 示例数据
x_nodes = [1, 2, 3, 4]
y_nodes = [2, 4, 1, 5]

# 计算拉格朗日插值多项式的解析式
poly = lagrange_polynomial(x_nodes, y_nodes)
print("拉格朗日插值多项式的解析式为:", poly)

# 将符号表达式转换为可调用的函数
x = sp.symbols('x')
poly_func = sp.lambdify(x, poly, 'numpy')

# 生成用于绘制插值函数的 x 值
x_vals = np.linspace(min(x_nodes) - 1, max(x_nodes) + 1, 400)
y_vals = poly_func(x_vals)

# 绘制原始数据点
plt.scatter(x_nodes, y_nodes, color='red', label='Original Data')

# 绘制插值函数曲线
plt.plot(x_vals, y_vals, color='blue', label='Lagrange Interpolation')

# 设置图表标题和坐标轴标签
plt.title('Lagrange Interpolation Visualization')
plt.xlabel('x')
plt.ylabel('y')

# 显示图例
plt.legend()

# 显示网格线
plt.grid(True)

# 显示图形
plt.show()

不计算基插函数情况下的Neville算法

import numpy as np
import matplotlib.pyplot as plt


def neville_interpolation_optimized(x_nodes, y_nodes, x):
    n = len(x_nodes)
    # 只使用一维数组来存储中间结果
    P = y_nodes.copy()
    for j in range(1, n):
        for i in range(n - j):
            numerator = (x - x_nodes[i + j]) * P[i] - (x - x_nodes[i]) * P[i + 1]
            denominator = x_nodes[i] - x_nodes[i + j]
            P[i] = numerator / denominator
    return P[0]


# 示例数据
x_nodes = [1, 2, 3, 4]
y_nodes = [2, 4, 1, 5]

# 生成用于绘制插值函数的 x 值
x_vals = np.linspace(min(x_nodes) - 1, max(x_nodes) + 1, 400)
y_vals = []
for x in x_vals:
    y = neville_interpolation_optimized(x_nodes, y_nodes, x)
    y_vals.append(y)

# 绘制原始数据点
plt.scatter(x_nodes, y_nodes, color='red', label='Original Data')

# 绘制插值函数曲线
plt.plot(x_vals, y_vals, color='blue', label='Neville Interpolation')

# 设置图表标题和坐标轴标签
plt.title('Neville Interpolation Visualization')
plt.xlabel('x')
plt.ylabel('y')

# 显示图例
plt.legend()

# 显示网格线
plt.grid(True)

# 显示图形
plt.show()

相关文章:

  • 建站工具论坛百度本地推广
  • 衡水网站建手机百度正式版
  • 合肥网站推广电话排名公式
  • 加盟网站制作公司北京seo百科
  • 死链对网站的影响精准引流客源的方法可靠吗
  • 给客户做网站建设方案平面设计
  • 【从0做项目】Java音缘心动(1)———项目介绍设计
  • 知识库-查看知识详情接口
  • 请谈谈 Vue 中的响应式原理,如何实现?
  • Qt常用控件之标签QLabel
  • 【Content-Type详解、Postman中binary格式、json格式数据转原始二进制流等】
  • 避免踩雷!CUDA与Anaconda兼容性配置完全手册
  • 实验六 时序逻辑电路设计实验(设计分析)
  • ARM SOC 架构系统M系、R系、A系
  • 【前端小点】vue3项目内根据主题读取不同文件夹下的图片资源(图片文件)
  • 重磅来袭————YOLOv12:Attention-Centric Real-Time Object Detectors
  • AIGC视频生成明星——Emu Video模型
  • 5-循环语句
  • 【Linux-网络】初识计算机网络 Socket套接字 TCP/UDP协议(包含Socket编程实战)
  • 推荐系统-排序模型
  • 力扣-回溯-17 电话号码的字母组合
  • C++ 课程设计 汇总(含源码)
  • B+树作为数据库索引结构的优势对比
  • HC32F460_GPIO驱动库
  • 阿里云SLB负载均衡的ALB和NLB有啥区别?一个是7层一个是4层
  • Redis中哈希(Hash)常见命令详解