计算方法(三)分段线性插值和Hermite插值

分段线性插值

1. 使用分段线性插值的目的

一些插值函数列可能产生Runge现象,也就是只能在某些区间内部收敛到被插函数,在这些区间外则根本无法收敛到被插函数。

为了使得我们的插值对于任何区间都有意义,选择将整个插值区间按照节点分成若干个小区间,在每个小区间上分别使用多项式插值,这样来近似代替被插函数。

一般使用次数小于或等于3的多项式来进行分段插值,当次数为1次是就是分段线性插值。

2. 方法

直观上,分段线性插值函数是连接各个节点的折线,采用Lagrange插值基函数的方法,在每个小区间上构造基函数,再作它们的线性组合。

以下的插值基函数可以作为选择

设在区间 [ a , b ] [a,b] [a,b]上给定 n + 1 n+1 n+1个插值节点和函数值
a = x 0 ≤ x 1 < x 2 < … < x n = b a=x_0\leq x_1 < x_2 <\ldotsa=x0x1<x2<<xn=b
y 0 , y 1 , … . y n y_0,y_1,\ldots.y_n y0,y1,.yn
构造以下插值基函数
l 0 ( x ) = { x − x 1 x 0 − x 1 x 0 ≤ x ≤ x 1 0 x 1 < x ≤ x n l_0(x)=\left\{ \begin{array}{lc} \frac{x-x_1}{x_0-x_1}&x_0\leq x \leq x_1\\ 0&x1 l0(x)={x0x1xx10x0xx1x1<xxn
l j ( x ) = { x − x j − 1 x j − x j − 1 x j − 1 ≤ x ≤ x j x − x j + 1 x j − x j + 1 x j ≤ x ≤ x j + 1 0 [ a , b ] − [ x j − 1 , x j + 1 ] l_j(x)=\left\{ \begin{array}{lc} \frac{x-x_{j-1}}{x_j-x_{j-1}}&x_{j-1}\leq x \leq x_j\\ \frac{x-x_{j+1}}{x_j-x_{j+1}}&x_{j}\leq x \leq x_{j+1}\\ 0&[a,b]-[x{j-1}, x_{j+1}] \end{array} \right. lj(x)=xjxj1xxj1xjxj+1xxj+10xj1xxjxjxxj+1[a,b][xj1,xj+1]
l n ( x ) = { x − x n − 1 x n − x n − 1 x n − 1 ≤ x ≤ x n 0 x 0 < x ≤ x n − 1 l_n(x)=\left\{ \begin{array}{lc} \frac{x-x_{n-1}}{x_n-x_{n-1}}&x_{n-1}\leq x \leq x_n\\ 0&x_0 ln(x)={xnxn1xxn10xn1xxnx0<xxn1
其中 j = 1 , 2 , … , n − 1 j=1,2,\ldots,n-1 j=1,2,,n1
然后用这些插值基函数就可以写出分段线性插值函数的表达式
φ ( x ) = ∑ j = 0 n y j l j ( x ) \varphi(x)=\sum_{j=0}^n y_jl_j(x) φ(x)=j=0nyjlj(x)

3. matlab方法

matlab的插值函数提供了线性插值的选项,y = interp1(x0,y0,x,‘linear’)返回插值节点为x0,函数值为y0,在区间x上的全部函数值。

x0 = 1:30;
y0 = 10*randn(1,30);
x = 1:0.5:30;

%分段线性插值
y2 = interp1(x0,y0,x,'linear');
plot(x0,y0,'+',x,y2,'r')
title('分段线性插值')

计算方法(三)分段线性插值和Hermite插值_第1张图片

Hermite插值

1. Hermite插值的好处

Hermite插值又称带指定微商值的插值,也就是说,除了给出了插值节点的函数值之外,还给出了指定插值节点的导数值。Hermite插值在插值节点处取相同的函数值和导数值。

2. 方法

给出n+1个插值节点和相应的函数值,微商值

x x x x 0 x_0 x0 x 1 x_1 x1 … \ldots x n x_n xn
y y y y 0 y_0 y0 y 1 y_1 y1 … \ldots y n y_n yn
y ′ y' y y 0 ′ y_0' y0 y 1 ′ y_1' y1 … \ldots y n ′ y_n' yn

可以构造2n+1次的Hermite插值多项式 H ( x ) H(x) H(x),并且

  • H ( x ) H(x) H(x)是次数不超过2n+1次的插值多项式
  • H ( x j ) = y j , H ′ ( x j ) = y j ′ , j = 0 , 1 , … , n H(x_j)=y_j,H'(x_j)=y_j',j=0,1,\ldots,n H(xj)=yj,H(xj)=yj,j=0,1,,n

采用插值基函数的办法,构造如下插值基函数
h i ( x ) = ( 1 + 2 ∑ j ≠ i x − x i x j − x i ) l i 2 ( x ) h_i(x)=(1+2\sum_{j\neq i}\frac{x-x_i}{x_j-x_i})l_i^2(x) hi(x)=(1+2j=ixjxixxi)li2(x)
H i ( x ) = l i 2 ( x ) ( x − x i ) H_i(x)=l^2_i(x)(x-x_i) Hi(x)=li2(x)(xxi)
其中 l i ( x ) l_i(x) li(x)是Largange插值基函数, i = 0 , 1 , … , n i=0,1,\ldots,n i=0,1,,n
并且, h i ( x ) , H i ( x ) h_i(x),H_i(x) hi(x),Hi(x)在对应下标插值节点处取值为1,在其他节点取取值为0.
这样可以写出Hermite插值的表达式
H ( x ) = ∑ i = 0 n ( y i h i ( x ) + y i ′ H i ( x ) ) H(x)=\sum_{i=0}^n(y_ih_i(x)+y_i'H_i(x)) H(x)=i=0n(yihi(x)+yiHi(x))

3. 分段三次Hermite插值

按照分段插值的方法,把区间 [ a , b ] [a,b] [a,b]分为若干个区间,在每个区间上使用三次Hermite插值。
在各个节点上的插值基函数如下
h 0 ( x ) = { ( 1 + 2 x − x 0 x 1 − x 0 ) ( x − x 1 x 0 − x 1 ) 2 x 0 ≤ x ≤ x 1 0 x 1 < x ≤ x n h_0(x)=\left\{ \begin{array}{lc} (1+2\frac{x-x_0}{x_1-x_0})(\frac{x-x_1}{x_0-x_1})^2&x_0\leq x \leq x_1\\ 0&x1 h0(x)={(1+2x1x0xx0)(x0x1xx1)20x0xx1x1<xxn
h j ( x ) = { ( 1 + 2 x − x j x j − 1 − x j ) ( x − x j − 1 x j − x j − 1 ) 2 x j − 1 ≤ x ≤ x j ( 1 + 2 x − x j x j + 1 − x j ) ( x − x j + 1 x j − x j + 1 ) 2 x j ≤ x ≤ x j + 1 0 [ a , b ] − [ x j − 1 , x j + 1 ] h_j(x)=\left\{ \begin{array}{lc} (1+2\frac{x-x_j}{x_{j-1}-x_j})(\frac{x-x_{j-1}}{x_j-x_{j-1}})^2&x_{j-1}\leq x \leq x_j\\ (1+2\frac{x-x_j}{x_{j+1}-x_j})(\frac{x-x_{j+1}}{x_j-x_{j+1}})^2&x_{j}\leq x \leq x_{j+1}\\ 0&[a,b]-[x{j-1}, x_{j+1}] \end{array} \right. hj(x)=(1+2xj1xjxxj)(xjxj1xxj1)2(1+2xj+1xjxxj)(xjxj+1xxj+1)20xj1xxjxjxxj+1[a,b][xj1,xj+1]
l n ( x ) = { ( 1 + 2 x − x n − 1 x n − 1 − x n ) ( x − x n − 1 x n − x n − 1 ) 2 x n − 1 ≤ x ≤ x n 0 x 0 < x ≤ x n − 1 l_n(x)=\left\{ \begin{array}{lc} (1+2\frac{x-x_{n-1}}{x_{n-1}-x_n})(\frac{x-x_{n-1}}{x_n-x_{n-1}})^2&x_{n-1}\leq x \leq x_n\\ 0&x_0 ln(x)={(1+2xn1xnxxn1)(xnxn1xxn1)20xn1xxnx0<xxn1
H 0 ( x ) = { ( x − x 0 ) ( x − x 1 x 0 − x 1 ) 2 x 0 ≤ x ≤ x 1 0 x 1 < x ≤ x n H_0(x)=\left\{ \begin{array}{lc} (x-x_0)(\frac{x-x_1}{x_0-x_1})^2&x_0\leq x \leq x_1\\ 0&x1 H0(x)={(xx0)(x0x1xx1)20x0xx1x1<xxn
H j ( x ) = { ( x − x j ) ( x − x j − 1 x j − x j − 1 ) 2 x j − 1 ≤ x ≤ x j ( x − x j ) ( x − x j + 1 x j − x j + 1 ) 2 x j ≤ x ≤ x j + 1 0 [ a , b ] − [ x j − 1 , x j + 1 ] H_j(x)=\left\{ \begin{array}{lc} (x-x_j)(\frac{x-x_{j-1}}{x_j-x_{j-1}})^2&x_{j-1}\leq x \leq x_j\\ (x-x_j)(\frac{x-x_{j+1}}{x_j-x_{j+1}})^2&x_{j}\leq x \leq x_{j+1}\\ 0&[a,b]-[x{j-1}, x_{j+1}] \end{array} \right. Hj(x)=(xxj)(xjxj1xxj1)2(xxj)(xjxj+1xxj+1)20xj1xxjxjxxj+1[a,b][xj1,xj+1]
H n ( x ) = { ( x − x n ) ( x − x n − 1 x n − x n − 1 ) 2 x n − 1 ≤ x ≤ x n 0 x 0 < x ≤ x n − 1 H_n(x)=\left\{ \begin{array}{lc} (x-x_n)(\frac{x-x_{n-1}}{x_n-x_{n-1}})^2&x_{n-1}\leq x \leq x_n\\ 0&x_0 Hn(x)={(xxn)(xnxn1xxn1)20xn1xxnx0<xxn1

matlab代码

function y=hermite(x0,y0,y1,x);
n=length(x0);m=length(x);
for k=1:m
    yy=0.0;
    for i=1:n
        h=1.0;
        a=0.0;
        for j=1:n
            if j~=i
                h=h*((x(k)-x0(j))/(x0(i)-x0(j)))^2;
                a=1/(x0(i)-x0(j))+a;
            end
        end
    yy=yy+h*((x0(i)-x(k))*(2*a*y0(i)-y1(i))+y0(i));
    end
y(k)=yy;
end

你可能感兴趣的:(数学建模,#,数值分析)