首页 > 编程语言 >【Python】拉格朗日Lagrange插值与牛顿Newton插值求解

【Python】拉格朗日Lagrange插值与牛顿Newton插值求解

时间:2024-03-15 11:01:53浏览次数:18  
标签:plt 插值 Newton interp Python xi 节点 coefficients

实验原理

  1. 熟悉并掌握Lagrange插值的构造原理;会计算在给定点的函数值

    Lagrange插值是一种基于Lagrange基函数的插值方法。给定一组数据节点(x,y),其中x是自变量,y是因变量,其插值的目标是构造一个多项式函数,通过这个多项式函数来拟合已知的数据节点,并用于对其他未知点进行插值预测。具体构造原理如下:

    1. 对于给定的数据节点 ( x k , y k ) (x_k, y_k) (xk​,yk​),构造基函数 l k ( x ) l_k(x) lk​(x),其中 i i i表示数据节点的索引。基函数 l k ( x ) l_k(x) lk​(x)的计算方式为:

      l k ( x ) = ∏ j = 0 , j ≠ k n x − x j x k − x j l_k(x) = \prod_{j=0, j\neq k}^n \frac{x - x_j}{x_k - x_j} lk​(x)=j=0,j=k∏n​xk​−xj​x−xj​​

      这里, n n n表示数据节点的总数, x j x_j xj​表示第 j j j个数据节点的 x x x值。

    2. 使用基函数 l k ( x ) l_k(x) lk​(x)来构造Lagrange插值多项式 L ( x ) L(x) L(x)。 L ( x ) L(x) L(x)的计算方式为:

      L ( x ) = ∑ k = 0 n y k ⋅ l k ( x ) L(x) = \sum_{k=0}^n y_k \cdot l_k(x) L(x)=k=0∑n​yk​⋅lk​(x)

      这里, y k y_k yk​表示第 k k k个数据节点的 y y y值。

    3. 最终得到的Lagrange插值多项式 L ( x ) L(x) L(x)就是通过已知数据节点进行插值预测的函数。可以使用该函数计算其他未知点的预测值。

  2. 熟悉并掌握Newton插值的构造原理;会计算在给定点的函数值。

    Newton插值是一种基于差商的插值方法,它使用差商的概念来构造插值多项式。具体来说,Newton插值法首先选择一组数据节点,然后,通过差商的计算来逐步构造插值多项式。对于给定的数据节点,可以通过以下递归公式计算差商:

    f [ x i ] = f ( x i ) f[x_i] = f(x_i) f[xi​]=f(xi​)

    f [ x i , x i + 1 , . . . , x i + k ] = f [ x i + 1 , x i + 2 , . . . , x i + k ] − f [ x i , x i + 1 , . . . , x i + k − 1 ] x i + k − x i f[x_i, x_{i+1}, ..., x_{i+k}] = \frac{f[x_{i+1}, x_{i+2}, ..., x_{i+k}] - f[x_i, x_{i+1}, ..., x_{i+k-1}]}{x_{i+k} - x_i} f[xi​,xi+1​,...,xi+k​]=xi+k​−xi​f[xi+1​,xi+2​,...,xi+k​]−f[xi​,xi+1​,...,xi+k−1​]​

    其中, f [ x i , x i + 1 , . . . , x i + k ] f[x_i, x_{i+1}, ..., x_{i+k}] f[xi​,xi+1​,...,xi+k​]表示在节点 x i , x i + 1 , . . . , x i + k x_i, x_{i+1}, ..., x_{i+k} xi​,xi+1​,...,xi+k​处的k阶差商, f [ x i ] f[x_i] f[xi​]表示在数据节点 x i x_i xi​处的函数值。

    通过递归计算差商,可以得到一个多项式的系数表,用于构造Newton插值多项式。最终,多项式的形式为:

    P ( x ) = f [ x 0 ] + f [ x 0 , x 1 ] ( x − x 0 ) + f [ x 0 , x 1 , x 2 ] ( x − x 0 ) ( x − x 1 ) + . . . P(x) = f[x_0] + f[x_0, x_1](x - x_0) + f[x_0, x_1, x_2](x - x_0)(x - x_1) + ... P(x)=f[x0​]+f[x0​,x1​](x−x0​)+f[x0​,x1​,x2​](x−x0​)(x−x1​)+...

    在给定的数据节点上,该多项式与原函数完全一致。最后,将待插值点的横坐标代入插值多项式中,即可得到相应的插值结果。

  3. 比较Lagrange插值与Newton插值的优缺点

    Lagrange插值在数据点附近具有高精度,适用于需要高精度插值的情况。Newton插值在节点附近具有高精度,同时具有较好的承继性,适用于需要稳定性和高精度插值的情况。在实际应用中,可以根据具体需求和限制选择合适的插值方法。

代码实现

分别用Lagrange和Newton插值计算深度为600、1000、1200处的水温

Lagrange插值

def lagrange_interpolation(x, y, value):
    # 判断输入的数据节点x和y是否数量一致
    if len(x) != len(y):
        print("数据节点数量不一致!")
        return None

    n = len(x)  # 数据节点的个数
    result = 0.0  # 待插值点处的水温

    for k in range(n):
        l_k = 1.0  # 基函数l_k(x)的初始值

        for i in range(n):
            if i != k:
                l_k *= (value - x[i]) / (x[k] - x[i])

        result += y[k] * l_k

    return result

# 测试数据
depth = [466, 741, 950, 1422, 1634]  # 深度数据节点
temperature = [7.04, 4.28, 3.40, 2.54, 2.13]  # 温度数据节点

# 待插值点的深度
depth_values = [600, 1000, 1200]

# 计算并输出水温
for value in depth_values:
    interpolated_temperature = lagrange_interpolation(depth, temperature, value)
    print(f"深度为{value}处的水温为:{interpolated_temperature}℃")
打印输出:

深度为600处的水温为:5.386310672253148℃
深度为1000处的水温为:3.2716309909438093℃
深度为1200处的水温为:2.900097926989794℃
Newton插值
import numpy as np

# 已知数据节点
depth = np.array([466, 741, 950, 1422, 1634])
temperature = np.array([7.04, 4.28, 3.40, 2.54, 2.13])

# 计算差商
def divided_differences(x, y):
    n = len(x)
    coefficients = np.zeros((n, n))
    coefficients[:, 0] = y

    for j in range(1, n):
        for i in range(n-j):
            coefficients[i, j] = (coefficients[i+1, j-1] - coefficients[i, j-1]) / (x[i+j] - x[i])

    return coefficients

# 计算插值多项式的系数表
coefficients = divided_differences(depth, temperature)

# 计算插值结果
def newton_interpolation(x, coefficients, data_points):
    n = len(data_points)
    result = 0

    for i in range(n):
        term = coefficients[0, i]
        for j in range(i):
            term *= (x - data_points[j])
        result += term

    return result

# 计算深度为600、1000和1200处的水温
depths_to_interpolate = np.array([600, 1000, 1200])
temperatures_interpolated = newton_interpolation(depths_to_interpolate, coefficients, depth)

print("插值结果:")
for i in range(len(depths_to_interpolate)):
    print("深度{}m的水温为{:}℃".format(depths_to_interpolate[i], temperatures_interpolated[i]))
打印输出:

深度为600处的水温为:5.386310672253148℃
深度为1000处的水温为:3.2716309909438093℃
深度为1200处的水温为:2.900097926989794℃

从实验结果来看,Lagrange插值和Newton插值在计算深度为600、1000和1200处的水温时,结果都非常接近真实的温度数据。这说明Lagrange插值和Newton插值方法在这组数据上具有一定的准确性和可靠性。

分别求相应的四次Lagrange和Newton插值多项式,画出插值函数与原函数的图形并做比较

Lagrange插值
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

def lagrange_interpolation(x, y, value):
    if len(x) != len(y):
        print("数据节点数量不一致!")
        return None

    n = len(x)
    result = 0.0

    for k in range(n):
        l_k = 1.0

        for i in range(n):
            if i != k:
                l_k *= (value - x[i]) / (x[k] - x[i])

        result += y[k] * l_k

    return result

# 设置中文字体
font = FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc", size=12)

# 数据节点
x = [0.4, 0.5, 0.6, 0.7, 0.8]
y = [0.6325, 0.7071, 0.7746, 0.8367, 0.8944]

# 生成插值函数的横坐标
x_interp = np.linspace(x[0], x[-1], 100)
# 计算插值函数的纵坐标
y_interp = [lagrange_interpolation(x, y, value) for value in x_interp]

# 绘制原函数和插值函数的图形
plt.plot(x_interp, y_interp, label='插值函数')
plt.scatter(x, y, color='red', label='原始数据')
plt.xlabel('x', fontproperties=font)
plt.ylabel('y', fontproperties=font)
plt.title('Lagrange插值', fontproperties=font)
plt.legend(prop=font)
plt.show()

在这里插入图片描述

Newton插值
import  numpy  as  np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

#  给定数据
x  =  np.array([0.4,  0.5,  0.6,  0.7,  0.8])
y  =  np.array([0.6325,  0.7071,  0.7746,  0.8367,  0.8944])

# 计算差商
def divided_differences(x, y):
    n = len(x)
    coefficients = np.zeros((n, n))
    coefficients[:, 0] = y

    for j in range(1, n):
        for i in range(n-j):
            coefficients[i, j] = (coefficients[i+1, j-1] - coefficients[i, j-1]) / (x[i+j] - x[i])

    return coefficients

#  计算插值多项式的系数
coefficients  =  divided_differences(x,  y)

# 计算插值结果
def newton_interpolation(x, coefficients, data_points):
    n = len(data_points)
    result = 0

    for i in range(n):
        term = coefficients[i]
        for j in range(i):
            term *= (x - data_points[j])
        result += term
    return result

#  计算插值函数在指定x值处的值
x_interp  =  np.linspace(x[0], x[-1], 100)
y_interp =  [newton_interpolation(x,  coefficients[0],  [0.4,  0.5,  0.6,  0.7,  0.8])  for  x  in  x_interp]

#  设置中文字体
font  =  FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc",  size=12)

#  绘制原函数和插值函数的图形
plt.plot(x_interp,  y_interp,  label='插值函数')
plt.scatter(x,  y,  color='red',  label='原始数据')
plt.xlabel('x',  fontproperties=font)
plt.ylabel('y',  fontproperties=font)
plt.title('Newton插值',  fontproperties=font)
plt.legend(prop=font)
plt.show()

在这里插入图片描述

由实验结果可以看出,Lagrange插值多项式和Newton插值多项式在给定的数据节点上都能很好地拟合原始数据。从图形上看,插值函数与原始数据点非常接近,表明插值方法能够较好地反映原始数据的趋势。

课外练习

为了观察多项式插值问题的Runge现象,使用函数f(x) = 1 / (1 + x^2) 在区间[-5, 5] 上进行Lagrange插值,并比较5次和10次插值多项式的结果。实现代码如下:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

def lagrange_interpolation(x, y, value):
    if len(x) != len(y):
        print("数据节点数量不一致!")
        return None

    n = len(x)
    result = 0.0

    for k in range(n):
        l_k = 1.0

        for i in range(n):
            if i != k:
                l_k *= (value - x[i]) / (x[k] - x[i])

        result += y[k] * l_k

    return result

# 定义函数 f(x) = 1 / (1 + x^2)
def f(x):
    return 1 / (1 + x**2)

# 生成等距节点
x = np.linspace(-5, 5, 100)
y = f(x)

# 生成5次插值多项式
x_interp_5 = np.linspace(-5, 5, 5)
y_interp_5 = f(x_interp_5)
interp_5 = lagrange_interpolation(x_interp_5, y_interp_5, x)

# 生成10次插值多项式
x_interp_10 = np.linspace(-5, 5, 10)
y_interp_10 = f(x_interp_10)
interp_10 = lagrange_interpolation(x_interp_10, y_interp_10, x)

#  设置中文字体
font  =  FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc",  size=12)

# 绘制原始函数和插值结果
plt.plot(x, y, label='原始函数')
plt.plot(x, interp_5, label='5次插值')
plt.plot(x, interp_10, label='10次插值')
plt.xlabel('x',fontproperties=font)
plt.ylabel('y',fontproperties=font)
plt.title('Lagrange插值结果',fontproperties=font)
plt.legend(prop=font)
plt.show()

在这里插入图片描述
由实验结果可以看出,在区间[-5, 5]上,随着插值多项式的阶数增加,插值结果在区间两端出现了明显的振荡现象,这就是Runge现象。这个现象表明,在某些情况下,使用更高阶的插值多项式并不一定能够得到更好的结果,反而可能导致不稳定的插值效果。

标签:plt,插值,Newton,interp,Python,xi,节点,coefficients
From: https://blog.csdn.net/xu1129005165/article/details/136733594

相关文章

  • Python爬虫入门
    什么是爬虫爬虫就是程序,一个能获取互联网上的资源(文字、图片、音视频)数据的程序。不用爬⾍,打开浏览器,输⼊百度的⽹址,就能在浏览器上看到百度的内容了。那换成爬⾍呢?道理是⼀样的。只不过,是⽤代码来模拟⼀个浏览器,然后同样的输⼊百度的⽹址。那么程序也能拿到百度的......
  • 使用Python开发桌面应用程序
    前言在本教程中,我们将使用Python编写一个功能强大的桌面应用程序,用于数据清洗、压缩、合并excel文件。该程序基于PySide6库和其他辅助库进行开发,提供了直观的用户界面和易于使用的功能。下面我们将对代码进行分块介绍。(底部附项目完整代码)导入所需库和模块在程序的开头,我们......
  • python+django在线网络小说分享系统flask毕业设计
    小说网站完善了对应的软体架设以及程序编码的工作,采取Mysql作为后台数据的主要存储单元,采用vue框架等技术进行业务系统的编码及其开发,实现了本系统的全部功能。同时完成小说网站的基本功能:小说的分类、信息查询浏览时间排行;用户的注册登录、创作小说、对阅读书架的管理;后台对用......
  • python+playwright 以非無痕模式打开chrome浏览器
    在使用python+playwright想从网页下载Excel数据,因为需要经过SSO,携带Tokey才可以访问数据,所以无痕模式下搞不好,使用非无痕模式打开浏览器,就可以获取cookie,成功达到效果。点击查看代码frommultiprocessing.sharedctypesimportValuefromplaywright.sync_apiimportsync_pla......
  • 5分钟上手Python爬虫:从干饭开始,轻松掌握技巧
    很多人都听说过爬虫,我也不例外。曾看到别人编写的爬虫代码,虽然没有深入研究,但感觉非常强大。因此,今天我决定从零开始,花费仅5分钟学习入门爬虫技术,以后只需轻轻一爬就能查看所有感兴趣的网站内容。广告?不存在的,因为我看不见。爬虫只会获取我感兴趣的信息,不需要的内容对我而言只是一......
  • 掌握Python库的Bokeh,就能让你的交互炫目可视化
    本文分享自华为云社区《Bokeh图形魔法:掌握绘图基础与高级技巧,定制炫目可视化》,作者:柠檬味拥抱。Bokeh是一个用于创建交互式可视化图形的强大Python库。它不仅易于使用,而且功能强大,适用于各种数据可视化需求。本文将介绍Bokeh库的绘图可视化基础入门,重点说明常用的参数,并通过实例......
  • python的字符串方法举例
    Python中的字符串对象提供了许多内置的方法,用于操作和处理字符串。以下是一些常用的字符串方法及其示例:1.split()将字符串分割为子字符串列表,并返回该列表。s="HelloWorld"words=s.split()#默认按空格分割print(words)#输出:['Hello','World']#也可以指定分......
  • Python爬虫实战系列3:今日BBNews编程新闻采集
    一、分析页面打开今日BBNews网址https://news.bicido.com,下拉选择【编程】栏目1.1、分析请求F12打开开发者模式,然后点击Network后点击任意一个请求,Ctrl+F开启搜索,输入标题ApacheDoris2.1.0版本发布,开始搜索搜索结果显示直接返回的json格式,那就soeasy了,直接copycurl,......
  • python的代码发布到服务器上需要注意的事项
    1、服务器的python运行环境配置。从官网上 https://www.python.org/ 下载服务器操作系统对应的版本。 然后配置 python和pip命令运行的环境变量,这是windows下的 检查是否正常:  2、开发时引用的第三方库要在服务器上安装。   a.首先获取需要的第三方库......
  • 【python】自动化工具Selenium与playwright去除webdriver检测
    对这个世界如果你有太多的抱怨跌倒了就不敢继续往前走为什么人要这么的脆弱堕落请你打开电视看看多少人为生命在努力勇敢的走下去我们是不是该知足珍惜一切就算没有拥有                     ......