2-5、插值

版权声明:本文为博主原创文章,如需转载请联系博主。 https://blog.csdn.net/GregoryHanson/article/details/79608109

一、概述

  插值是最常用的数据处理方法之一。
  假设有一组已知数据,现缺失其中一个数据,或要求评估其中两个数据间的一个点的值,此时便可使用插值方法。
  一般而言,在做题时并不会直接对所有数据进行拟合、插值操作,而是需先结合一些其他的数据预处理知识,如去除数据噪声,再进行拟合、插值等操作。这样所得结果才会更加科学、准确。
  插值是一个大的概念,其中又分为许多种具体的插值方法。在具体问题中,应根据实际情况具体分析,选用合适的方法。

  本节省略了部分准确的数学定义与证明,建议结合相关书本学习。

二、一维插值

1、拉格朗日插值

(1)定义
  拉格朗日插值多项式公式为:

P n ( x ) = i = 0 n l i ( x ) y i

  其中 l i ( x ) n 次多项式(称为拉格朗日插值基函数):

l i ( x ) = i = 0 , i j k x x i x j x i = x x 0 x j x 0 x x j 1 x j x j 1 x x j + 1 x j x j + 1 x x k x j x k

  具体使用方法与分析可参考本文:https://www.cnblogs.com/ECJTUACM-873284962/p/6833391.html

(2)拉格朗日插值的matlab实现

  设 n 个节点数据以数组 x 0 , y 0 输入(注意Matlab的数组下标从1开始), m 个插值点以数组 x 输入,输出数组 y m 个插值。编写一个名为 l a g r a n g e . m 的函数文件:

%拉格朗日函数插值实现,输入x0,y0为已知数据,x为待插值点,输出y为待插点结果
function y=lagrange(x0,y0,x)
n=length(x0);
m=length(x);
for i=1:m
    z=x(i);
    s=0.0;
    for k=1:n
        p=1.0;
        for j=1:n
            if j~=k
                p=p*(z-x0(j))/(x0(k)-x0(j));
            end
        end
        s=p*y0(k)+s;
    end
    y(i)=s;
end

(3)关于插值次数的讨论
  在拟合、插值中,取较高的次数往往能使已知数据点范围内的误差减小,但并不是次数越高越好。如同拟合中次数过高容易出现过拟合问题,插值中取过高的次数也会出现相应问题。

高次插值的病体性质:
  在一定的区间内增加节点数能提高插值精度,但在某些情况下会出现很大偏差,一个突出的例子就是 C . R u n g e 1905年发现的函数:

f ( x ) = 1 1 + x 2

   f ( x ) [ 5 , 5 ] 上的各阶导数均存在,取 n + 1 个等距节点
x k = 5 + 10 k n ( k = 0 , 1 , , n )

  原函数图像和1次、5次以及10次 L a g r a n g e 插值函数图像如下所示:
这里写图片描述

  在 [ 5 , 5 ] 范围内,若节点取得较少,则精度很低。但节点数增加后,只在区间的中心部分精度提高,即在 L n ( x ) 只在 | x | 3.63 内收敛,而在此区域外产生严重的振荡。称这种高频振荡的病态现象为龙格( R u n g e )现象。

  因此使用高次多项式插值是危险的,在实际计算中不能使用高次插值。这反而启发我们使用分段插值方法,即将区间 [ a , b ] 分成一些小区间,在每一个小区间上用低次多项式进行插值。区间的剖份可以是任意的,各小区间上插值多项式的次数的选取也可按具体问题的要求而选择。分段低次多项式插值通常有较好的收敛性和稳定性,算法简单,但插值函数光滑性变差。常用的分段多项式插值法有两类:一类是下面将要介绍的分段线性插值法;另一类是三次样条插值法。

2、分段线性插值
  概括而言,分段线性插值即为只利用插值点左右的两个有效数据点,进行线性插值。
  实际上用数据点作插值计算时,分段线性插值就足够了,如数学、物理中用的特殊函数表,数理统计中用的概率分布表等。

  用Matlab实现分段线性插值不需要编制函数程序,Matlab中有现成的一维插值函数 i n t e r p 1

y=interp1(x0,y0,x,'method')
%method指定插值的方法:
%缺省时:分段线性插值
%'nearest' 最近项插值
%'linear' 线性插值
%'spline' 立方样条插值
%'cubic' 立方插值。

注:所有的插值方法要求 x 0 是单调的,并且 x i 不能够超过 x 的范围。
x 0 为等距时可以用快速插值法,使用快速插值法的格式为’*nearest’、’*linear’ 、’*spline’ 、’*cubic’。

三、二维插值

1、二维插值定义
  一维插值的特点是节点为一维实数组,插值函数是一元函数(曲线)。若节点是二维数组,则插值函数就是二元函数,即曲面。例如在某区域测量了若干点(节点)的高程(节点值),为了画出该区域较精确的等高线图,就要先插入更多的点(插值点),计算这些点的高程(插值),这就是一个二维插值问题。

2、二维插值方法
  常见的二维插值可分为网格节点插值和散乱节点插值。
  网格节点插值适用于节点比较规范的情况,即在包含所给节点的矩形区域内,节点由两族平行于坐标轴的直线的交点所组成。主要方法有:最邻近插值(选取待插值点最邻近已知数据点的函数值作为待插值节点的值)、分片线性插值和双线性插值。
  散乱节点插值适用于一般的节点,多用于节点不太规范(即节点为两族平行于坐标轴的直线的部分交点)的情况。

3、二维插值的Matlab实现
(1)网格节点数据的插值

z=interp2(x0,y0,z0,x,y,'method')

  其中 x 0 , y 0 分别为 m 维和 n 维向量,表示节点, z 0 n m 维矩阵,表示节点值, x , y 为一维数组,表示插值点, x y 应是方向不同的向量,即一个是行向量,另一个是列向量, z 为矩阵,表示得到的插值, m e t h o d 的用法同上面的一维插值(缺省时,为双线性插值)

(2)散点数据的插值

cz =griddata(x,y,z,cx,cy,‘method’)

  其中, x , y 为表示节点, c x , c y 表示插值点, m e t h o d 的用法同上面的一维插值。

三、例题

1、对函数 y = x s i n x 从0到10,步长为1 进行采样得到插值节点,利用线性插值给出步长为0.25的插值函数图像

x = 0:10;         % 节点
y = x.*sin(x);
xx = 1:0.25:10;   % 插值点
yy = interp1(x,y,xx);
plot(x,y,'kd',xx,yy)

这里写图片描述

2、在一天24小时内,从零点开始每隔2小时测得的环境温度数据分别为:
12, 9, 9, 1, 0, 18, 24, 28, 27, 25, 20, 18, 15, 13
推测中午13时的温度。

% 采用三次样条插值
x = 0:2:24;
y = [12 9 9 10 18 24 28 27 25 20 18 15 13];
a = 13;
y1 = interp1(x,y,a,'spline')
% 若要得到一天24小时的温度曲线
xi = 0:1/3600:24;
yi = interp1(x,y,xi,'spline');
plot(x,y,'o',xi,yi)

这里写图片描述

3、测得平板表面3*5网格点处的温度分别为:
82 81 80 82 84
79 63 61 65 81
84 84 82 85 86
试作出平板表面的温度分布曲面z=f(x,y)的图形。

% 先在三维坐标画出原始数据,画出粗糙的温度分布曲图.
x=1:5;
y=1:3;
temps=[82 81 80 82 84;79 63 61 65 81;84 84 82 85 86];
mesh(x,y,temps)
% 以平滑数据,在x、y方向上每隔0.2个单位的地方进行插值
xi=1:0.2:5;
yi=1:0.2:3;
zi=interp2(x,y,temps,xi',yi,'cubic');
mesh(xi,yi,zi)  

这里写图片描述

四、扩展阅读

关于三维以及n维插值方法http://www.cnblogs.com/aminxu/p/4643109.html

猜你喜欢

转载自blog.csdn.net/GregoryHanson/article/details/79608109
2-5