一、算法原理
1、問題引入
上一篇博客我們介紹了拉格朗日插值法,我們現在來回顧其定義:
對於插值區間【a,b】上一系列插值節點x0,x1,x2,......xn及其函數值y0、y1、y2......yn;構造一個簡單的簡單易算的近似函數g(x)≈f(x),滿足條件g(xi)=f(xi) (i=0,1,2...,n)。
其拉格朗日插值多項式的形式爲:
g(x)=L0(x0)*y0+L1(x1)*y1+......+Ln(xn)*yn,
其中Li(xi)=[(x-x0)*(x-x1)*......*(x-x(i-1))*(x-x(i+1))*.....*(x-xn)] / [(xi-x0)*(xi-x1)*......*(xi-x(i-1))*(xi-x(i+1))*.....*(xi-xn)]。
優點:具有嚴格的規律性,便於記憶。
缺點:計算量大、不具有承襲性。
2、牛頓插值法
Lagrange 插值雖然易算,但若要增加一個節點時, 全部基函數Li(x) 都需要重新計算。能否改寫其形式,使其每增加一個點,只附加一項(重新計算一項)。
設Nn(x)=A0+A1*(X-X0)+A2*(X-X0)(X-X1)+......+An(X-X0)*(X-X1)......(X-X(n-1))
利用Nn(xi)=f(xi),寫成矩陣形式:
1 0 ...... 0 [A0 [f(x0) 1 x1-x0 ...... 0 A1 f(x1) 1 x2-x0 (x2-x0) (x2-x1) ...... 0 * ...... = ...... ... ... ...... ...... ... ... ... ...... ...... 1 xn-x0 (xn-x0) (xn-x1) ...... (xn-x0)*...(xn-x(n-1)) An] f(xn)] 根據該線形方程組可以求得:A0=f(x0),A1=[f(x1)-f(x0)]/[x1-x0], A2={[f(x2)-f(x0)]/[x2-x0]-f(x1)-f(x0)]/[x1-x0]} / (x2-x1)
|
3差商的定義
設已知函數f (x)在一系列互不相等的節點x0,x1,x2,......xn,(即在i≠j時,xi≠xj)上的函數值 f(xi) ,
f (x)在點xi , xj處的一階差商爲:
f (x)在點xi,xj,xk處的二階差商爲:
f(x)在點x0,x1,x2,......xk的k階差商爲:
規律總結:高階差商是兩個低一階差商的差商。
利用差商的定義,可得Nn(x)的係數Aj :
從而可得牛頓插值多項式:
這樣就實現了,每增加一個節點,多項式只增加一項,克服了拉格朗日插值多項式的缺點。
差商可以通過差商表計算。
4、牛頓插值多項式
瞭解了差商,我們就可以利用差商來表示牛頓插值多項式:
二、matlab程序
%% 牛頓插值 (創建函數腳本方可運行)
close
clc
clear
x=[2 3 5 6 9];
y=[4 8 12 15 23];
m=length(X);
c=cha(X,Y);
syms x
for i=1:m-1
D1=x-X(1:i);
D(i)=prod(D1);
end
N=sym2poly(expand(sum(D.*c)+Y(1)))
x=X(1):0.1:X(end);
y=polyval(N,x);
plot(x,y)
hold on
plot(X,Y,'o')
function C=cha(X,Y)
% C存儲差商結果
% X是橫座標
m=length(X);
d=diff(Y)./diff(X); %一階差商
C(1)=d(1); %取出第一個一階差商做係數
for i=2:m-1 %i階差商 依次算出C(2)、C(3)...C(m-1)階茶商 ,儲存在數組C中
X1=X(i+1:end);
n=length(X1);
X2=X(1:n);
d=diff(d)./(X1-X2);
C(i)=d(1);
end
end