拉格朗日插值——基于scipy实现

python 实现
from scipy.interpolate  import lagrange
x = [3, 6, 9]
y = [10, 8, 4]
lagrange(x,y)
#poly1d([ -0.11111111,   0.33333333,  10.        ])
1
2
3
4
5
以上 lagrange(x,y) 的输出值 poly1d([−0.11111111,0.33333333,10.])   是多项式的三个系数 
即: a0=−0.11111,a1=0.3333333,a2=10. 
如果要进行插值操作,可以:

lagrange(x, y)(10)
# 2.222222

总结:根据输入的序列构造一个函数,然后可以输入新的数 ,获得在前面数据基础上的,当前数经过插值后的值应该是多少。

另外一个示例:
import pandas as pd
from scipy.interpolate import lagrange
inputfile =  "../data/missing_data.xls"
outfile = "../data/processed_data.xls"
data = pd.read_excel(inputfile,header=None)
print(data)
print(type(data))
# 自定义列向量插值函数
def ployinterp_column(s,n,k=5):
    y =  s[list(range(n-k,n)) + list(range(n+1,n+1+k))]
    y = y[y.notnull()]
    print("y.index:",y,type(y))
    return lagrange(y.index,list(y))(n)
#逐个元素判断是否需要插值
for i in data.columns:
    print("i:",i,data[i],type(data[i]))
    for j in range(len(data)):
        if (data[i].isnull())[j]: #如果为空即插值。
            data[i][j] = ployinterp_column(data[i], j)
print("data:",data)

下面是原理:
1、插值问题:在做实验的过程中,往往得到一堆离散的数据,现在想用数学公式模拟这堆离散数据。怎么办,数学家们提出了插值问题。插值问题的提法是这样的给定一堆数据点(x0, y0), (x1, y1), (x2, y2)...(xn, yn),要求一个函数 y = f(x) ,要求该函数经过上面所有的数据点。

 

2、多项式插值及其唯一性:在所有的函数中,多项式函数是最简单的函数,所以只要是人就会想到用多项式函数来作为插值函数,好,以上给定了n+1个点,现在要求一个n次多项式y = an * x^n + ... a1 * x + a0, 使它们经过这n+1个点;通过范德蒙行列式 和 克莱姆法则,可以判定如果这n+1个点的x值各不相同,那么这个多项式是唯一的。结果唯一,但是用直接法很不好求。现在用别的办法来求之。这就是:拉格朗日多项式

 

3、拉格朗日多项式的构造,以四个点为例子进行说明

 

由于函数经过4个点(x0, y0),(x1, y1),(x2, y2),(x3, y3),所以可以设函数为:

 

f(x) = b0(x) * y0 + b1(x) * y1 + b2(x) * y2 + b3(x) * y3

 

注意:b0(x),...,b3(x)都是x的3次多项式,称之为拉格朗日插值基函数。

 

由于要求当x为x0时候,f(x) = y0, 所以最简单的做法就是让b0(x0) = 1, b1(x0) = b2(x0) =  b3(x0) = 0;

 

同理可知,在x1,x2,x3点上,插值基函数的值构造如下:

 

                b0(x)        b1(x)        b2(x)        b3(x)

 

x=x0         1                0              0              0

 

x=x1         0                1              0              0

 

x=x2         0                0              1              0

 

x=x3         0                0              0               1

 

问题1、根据这些值来确定b0(x)的表达式,

 

由于b0(x1) = b0(x2) = b0(x3) = 0,所以x1, x2, x3是b0(x)的零点,由于b0(x)是三次多项式,所以设

 

b0(x) = c0 * (x-x1) * (x-x2) * (x-x3)

 

由于b0(x0) = 1,所以 1 = c0 * (x0-x1) * (x0-x2) * (x0-x3)  得到 c0 = 1/[(x0-x1)(x0-x2)(x0-x3)]

 

所以:b0(x) = (x-x1)*(x-x2)*(x-x3)/[(x0-x1)*(x0-x2)*(x0-x3)]

 

同理可求b1(x)、b2(x),略

 

问题2、根据上面的表格说明插值基函数的一个性质:无论x取和值,它们的和都为1.【这个叫做调和函数】

 

以3次为例子说明:将上述表格的每一行分别相加,得到的事函数:g(x) = b0(x) + b1(x) + b2(x) + b3(x)在x0, x1, x2, x3的值,都为1.

 

                     b0(x) + b1(x) + b2(x) + b3(x)

 

x=x0                    1+0+0+0 = 1

 

x=x1                    0+1+0+0 = 1

 

x=x2                    0+0+1+0 = 1

 

x=x3                    0+0+0+1 = 1

 

所以:方程g(x) - 1 = 0,应该有4个根x0, x1, x2, x3;但是,由于b0(x)、b1(x)、b2(x)、b3(x)都是3次多项式,所以,g(x)最多也是3次多项式,至多只有3个根,所以等式:g(x) = 1 应该是恒等式。得证。

 

问题3、基函数:b0(x)、b1(x)、b2(x)、b3(x) 是线性无关的。

 

设:数t0, t1, t2, t3使得:t0 * b0(x) + t1 * b1(x) + t2 * b2(x) + t3 * b3(x) = 0

 

x=x0时候:0 = t0 * b0(x0) + t1 * b1(x0) + t2 * b2(x0) + t3 * b3(x0) = t0 * 1 + t1 * 0 + t2 * 0 + t3 * 0 得到:t0 = 0;

 

同理有:t1 = t2 = t3 = 0,根据定义(所有系数为0)。所以插值基函数是线性无关的。

 
--------------------- 
版权声明:本文为CSDN博主「jiangnanyouzi」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jiangnanyouzi/article/details/5698122

你可能感兴趣的:(Python,机器学习,拉格朗日插值)