拉格朗日插值多項式的原理介紹及其應用


  插值,不論在數學中的數值分析中,還是在我們實際生產生活中,都不難發現它的身影,比如造船業和飛機制造業中的三次樣條曲線。那么,什么是插值呢?我們可以先看一下插值的定義,如下:

  (定義)如果對於每個\(1 \leq i \leq n,P(x_{i})=y_{i}\),則稱函數\(y=P(x)\)插值數據點\((x_{1},y_{1}),...,(x_{n},y_{n})\).

   插值的定義無疑是清楚明了的,而在眾多的數學函數中,多項式無疑是最簡單,最常見的函數,關於它的理論研究也最為透徹。因此,我們可以不妨先考慮利用多項式來進行插值。那么,這樣的多項式是否總是存在呢?答案是肯定的,因為我們有如下定理:

  (多項式插值定理)令\((x_{1},y_{1}),...,(x_{n},y_{n})\)是平面中的\(n\)個點,各\(x_{i}\)互不相同。則有且僅有一個\(n-1\)次或者更低的多項式\(P\)滿足\(P(x_{i})=y_{i},i=1,2,...,n.\)

  證明:先用歸納法證明存在性,再證明唯一性。
  當\(n=1\)時,常函數(0次)\(P_{1}(x)=y_{1}\)即符合要求。假設當\(n-1\)時存在一個次數\(\leq n-2\)的多項式\(P_{n-1}\),使得\(P_{n-1}(x_{i})=y_{i},i=1,2,...,n-1.\)則令\(P_{n}(x)=P_{n-1}(x)+c(x-x_{1})(x-x_{2})...(x-x_{n-1})(x-x_{n})\),其中\(c\)為待定系數,利用\(P_{n}(x_{n})=y_{n}\)即可求出待定系數\(c\).此時,\(P_{n}(x_{i})=y_{i},i=1,2,...,n,\)\(P_{n}(x)\)的次數\(\leq n-1\).這樣就證明了存在性。
  其次證明唯一性。假設存在兩個這樣的多項式,設為\(P(x)\)\(Q(x)\),它們次數\(\leq n-1\)且都插值經過\(n\)個點,即\(P(x_{i})=Q(x_{i})=y_{i},i=1,2,...,n.\)\(H(x)=P(x)-Q(x)\),\(H\)的次數也\(\leq n-1\),且有\(n\)個不同的根\(x_{1},x_{2},...,x_{n}\).因此,由多項式基本定理可知,\(H(x)\)為0多項式,即恆等於0,故有\(P(x)=Q(x)\).這樣就證明了存在性。
  證畢。

  有了以上定理,我們可以放心地使用多項式進行插值,同時,通過上述定理,我們可以用歸納法來構造此多項式,但是,這樣的方法難免復雜麻煩。於是,天才的法國數學家拉格朗日(Lagrange)創造性地發明了一種實用的插值多項式方法來解決這個問題,那么,他的方法是怎么樣的?
  一般來說,如果我們有\(n\)個點\((x_{1},y_{1}),...,(x_{n},y_{n})\),各\(x_{i}\)互不相同。對於1到n之間的每個\(k\),定義\(n-1\)次多項式

\[L_{k}(x) = \frac{(x-x_{1})..(x-x_{k-1})(x-x_{k+1})...(x-x_{n})}{(x_{k}-x_{1})..(x_{k}-x_{k-1})(x_{k}-x_{k+1})...(x_{k}-x_{n})} \]

\(L_{k}(x)\)具有有趣的性質:\(L_{k}(x_{k})=1,L_{k}(x_{j})=0,j\neq k.\)然后定義一個\(n-1\)次多項式

\[P_{n-1}(x)=y_{1}L_{1}(x)+...+y_{n}L_{n}(x). \]

這樣的多項式\(P_{n-1}(x)\)滿足\(P_{n-1}(x_{i})=y_{i},i=1,2,...,n.\)這就是著名的拉格朗日插值多項式!
  以上就是拉格朗日插值多項式的理論介紹部分,接下來我們就要用Python中的Sympy模塊來實現拉格朗日插值多項式啦~~
  實現拉格朗日插值多項式的Python代碼如下:

from sympy import *

def Lagrange_interpolation(keys, values):
    x = symbols('x')
    t = len(keys)
    ploy = []
    for i in range(t):
        lst = ['((x-'+str(_)+')/('+str(keys[i])+'-'+str(_)+'))' for _ in keys if _ != keys[i]]
        item = '*'.join(lst)
        ploy.append(str(values[i])+'*'+item)
    ploy = '+'.join(ploy)
    
    return factor(expand(ploy))

def main():
    #example 1, interpolate a line 
    x_1 = [1,2]
    y_1 = [3,5]
    if len(x_1) != len(y_1):
        print('The lengths of two list are not equal!')
    else:
        print('Lagrange_interpolation polynomials is:')
        print(Lagrange_interpolation(x_1,y_1))
    
    #example 2, interpolate a parabola
    x_2 = [0,2,3]
    y_2 = [1,2,4]
    if len(x_2) != len(y_2):
        print('The lengths of two list are not equal!')
    else:
        print('Lagrange_interpolation polynomials is:')
        print(Lagrange_interpolation(x_2,y_2))
    
    #example 3
    x_3 = [0,1,2,3]
    y_3 = [2,1,0,-1]
    if len(x_3) != len(y_3):
        print('The lengths of two list are not equal!')
    else:
        print('Lagrange_interpolation polynomials is:')
        print(Lagrange_interpolation(x_3,y_3))
        
main()

函數Lagrange_interpolation()具體實現了拉格朗日插值多項式,參數(keys, values)為list形式的點對,在main()函數中舉了三個Lagrange_interpolation()函數的應用實例,一個是插值兩個點,即直線,一個是插值三個點,即拋物線,一個是插值四個點,但結果卻是一次多項式。該程序的運行結果如下:

![程序運行結果](http://img.blog.csdn.net/20180108220343531?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  接下來,我們將介紹一個拉格朗日插值多項式的應用,即求 $$1^{k}+2^{k}+...+x^{k}$$ 的求和公式,其中$x,k$為正整數。分析如下:   首先,該求和公式應當是一個至多為k+1次的關於$x$的多項式。然后,我們可以通過取k+2個不同的點,利用拉格朗日插值多項式的辦法來求解,這k+2個不同的點的橫坐標可以取$x=1,2,...,k+2$,在求出其對應的縱坐標的值。   以下代碼分別求出$k=1,2,...,50$的求和公式,並將其插入到Redis中。 ```python from sympy import * import redis

def Lagrange_interpolation(keys, values):
x = symbols('x')
t = len(keys)
ploy = []
for i in range(t):
lst = ['((x-'+str()+')/('+str(keys[i])+'-'+str()+'))' for _ in keys if _ != keys[i]]
item = ''.join(lst)
ploy.append(str(values[i])+'
'+item)
ploy = '+'.join(ploy)

return factor(expand(ploy))

def degree_of_sum(k):
x_list, y_list = [], []
degree = k # degree=k in expression of 1^k+2^k+...+x^{k}
cul_sum = 0
for i in range(1,degree+3):
x_list.append(i)
cul_sum += i**degree
y_list.append(cul_sum)
return Lagrange_interpolation(x_list,y_list)

def main():
r = redis.Redis(host='localhost', port=6379,db=0)
for k in range(1,51):
expression = str(degree_of_sum(k))
r.hset('sum_%s'%k,'degree',str(k))
r.hset('sum_%s'%k,'expression',expression)
print('Degree of %d inserted!'%k)

main()

運行以上程序,結果如下:
<center>
![程序運行結果](http://img.blog.csdn.net/20180108221925388?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
</center>
在Redis中的儲存結果如下:
<center>
![Redis中儲存結果](http://img.blog.csdn.net/20180108221948384?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
</center>
我們可以具體查看當$k=2$時的求和公式,如下:
<center>
![k=2時的求和公式](http://img.blog.csdn.net/20180108222038385?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamNsaWFuOTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
</center>
&emsp;&emsp;這樣我們就介紹完了一個拉格朗日插值多項式的應用了。看了上面的介紹,聰明又機智的你是否能想到更多拉格朗日插值多項式的應用呢?歡迎大家交流哦~~
&emsp;&emsp;新的一年,新的氣象,就從這一篇開始~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM