欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

拉格朗日插值法 【python】

程序员文章站 2022-06-07 11:44:10
...

一、插值

   设函数y=f(x)在区间[a,b]上连续,给定n+1个点

               a≤x0<x1<....<xn≤b

   已知,f(xk)=yk(k=0,1....n),在函数类P中寻找一个函数Φ(x)。作为f(x)的近似表达式,使满足:

             Φ(xk)=f(xk)=yk, k=0,1,2,3,4....n                (2)

  f(x)为被插值函数,Φ(x)为插值函数,x0,x1....xn为插值节点。(2)为插值节点。

二、拉格朗日插值法

   线性插值:拉格朗日插值法中最简单的是线性插值,我们先来了解线性插值函数的构成。在此基础上了解多次插值,

   已知两点(x0,y0)和(x1,y1),这里f(x0)=y0,f(x1)=y1,通过这两个点的插值多项式是一条直线,如下:

   (x-x1)/(x0-x1)*y0+(x-x0)/(x1-x0)*y1    可以看出当x=x0的时候,函数值y0,当x=x1的时候,函数值为y1.

  多项插值

     在线性插值中,仅仅用到了两个点,为了提高精度,我们希望用更多的点来提高精度。为此我们用三个点来做插值

    已知点(x0,y0),(x1,y1),(x2,y2).如下图所示,式1是两次的拉格朗日插值函数。式2是拉格朗日函数的一般形式。

          当x=x0的时候,l0(x)的值为1,l1(x)的值为0,l2(x)的值为0.最后函数值为y0.

    拉格朗日插值的函数的形式都是如式二所示。假设有n个点进行拉格朗日插值。则插值函数一共有n项,每一项都是ln(x)*yn (n的取值为1到n),当x=m的时候(m为1到n中的数时),相应的ln(x)为一,其他项为0。函数值为ym.

    但是,我们应该如何求解ln(x)呢。以上面的三个点为例,在求l0的时候,分子为x减去除了x0的点的连乘,分母为x0减去除x0点的连乘。其他的项也是这样计算的。

  拉格朗日插值法 【python】

三、拉格朗日插值法的python应用

下面的程序是求点(100,10),(121,11),(144,12),可以看出函数为根号x,现在用拉格朗日插值法求三个点的插值函数,并绘制出函数图像,并求将根号115对应的函数值画在同一坐标系中,观察拉格朗日插值法的精确度。

import matplotlib.pyplot as plt
from pylab import mpl
"""
用拉格朗日插值法拟合数据。
"""

"""
功能:计算插值多项式的系数。
参数:data_x为数据的x坐标,data_y为数据的y坐标,size为插值基函数的个数。
返回值:插值函数的系数。
"""
x = [100, 121,  144]
y = [10,11, 12]

def ParametersOfLagrangeInterpolation(data_x,data_y,size):
    parameters=[]
    #i用来控制参数的个数
    i=0;
    while i < size:
        #j用来控制循环的变量做累乘
        j = 0;
        temp = 1;
        while j < size:
            if(i != j):
                temp*=data_x[i]-data_x[j]
            j+=1;
        parameters.append(data_y[i]/temp)
        i += 1;
    return parameters

"""
功能:计算拉格朗日插值法公式的值。
参数:data_x为原始数据的横坐标,x为要用拉格朗日插值函数计算数据,parameters为拉格朗日插值函数的系数。
返回值:经拉格朗日插值公式计算后的值。
"""

def CalculateTheValueOfLarangeInterpolation(data_x,parameters,x):
    returnValue=0
    i = 0;
    while i < len(parameters):
        temp = 1
        j = 0;
        while j< len(parameters):
            if(i!=j):
                temp *=x-data_x[j]
            j+=1
        returnValue += temp * parameters[i]
        i += 1
    return returnValue


"""
功能:将函数绘制成图像
参数:data_x,data_y为离散的点.new_data_x,new_data_y为由拉格朗日插值函数计算的值。x为函数的预测值。
返回值:空
"""
def  Draw(data_x,data_y,new_data_x,new_data_y):
        plt.plot(new_data_x, new_data_y, label="拟合曲线", color="black")
        plt.scatter(data_x,data_y, label="离散数据",color="red")
        plt.scatter(115, 10.723805294764, label="真实数据", color="green")
        mpl.rcParams['font.sans-serif'] = ['SimHei']
        mpl.rcParams['axes.unicode_minus'] = False
        plt.title("拉格朗日插值拟合数据")
        plt.legend(loc="upper left")
        plt.show()

"""
由于三个点绘制的拟合曲线效果太差,所以采用这样的方法来进行数据拟合。
1>利用原数据计算出拉格朗日插值多项式的函数,分别在10-150区间内,每10个数取一个点,计算相应的值,绘制函数图像。
2>将源数据以点的形式画在图像上,
3>将115代入拉格朗日函数计算出相应的值,绘制在图像上。点为红色。并将真实的值也绘制在图像上点为绿色。看红色的点和绿色的点是否重合。
4>结果证明红色的点和绿色的点重合,说明拉格朗日函数插值效果较好。
"""
parameters=ParametersOfLagrangeInterpolation(x,y,3)
datax=[10,20,30,40,50,60,70,80,90,100,110,120,130,140,150]
datay=[]
for temp in datax:
    datay.append(CalculateTheValueOfLarangeInterpolation(x,parameters,temp))
x.append(115)
y.append(CalculateTheValueOfLarangeInterpolation(x,parameters,115))
Draw(x,y,datax,datay)
   下面是拉格朗日插值法的效果图,可以看出,插值函数基本能和根号115重合。

   拉格朗日插值法 【python】