
4.2 数据插值
在工程测量与科学实验中,通常得到的数据都是离散的。如果要得到这些离散数据点以外的其他数据值,就需要根据这些已知数据进行插值。假设测量得到n个点数据,(x1,y1),(x2,y2),…,(xn,yn),满足某一个未知的函数关系y=f(x),数据插值的任务就是根据已知的n个数据,构造一个函数y=p(x),使得yi=p(xi)(i=1,2,…,n)成立,就称p(x)为f(x)关于点x1,x2,…,xn的插值函数。求插值函数p(x)的方法为插值法。插值函数p(x)一般可以用线性函数、多项式或样条函数实现。
根据插值函数的自变量的个数,数据插值可以分为一维插值、二维插值和多维插值等;根据插值函数的不同,可以分为线性插值、多项式插值和样条函数插值等。MATLAB提供了一维插值interp1、二维插值interp2、三维插值interp3和N维插值interpn函数,以及三次样条插值spline函数等。
4.2.1 一维插值
所谓一维插值是指被插值函数的自变量是一个单变量的函数。一维插值采用的方法一般有一维多项式插值、一维快速插值和三次样条插值。
1.一维多项式插值
MATLAB中提供了interp1函数进行一维多项式插值。interp1函数使用了多项式函数,通过已知数据点计算目标插值点的数据。interp1函数的调用格式如下:

其中,Y是在默认自变量x选为1:n的值。

其中,X和Y是长度一样的已知向量数据,xi可以是一个标量,也可以是向量。

其中,method是插值方法,其取值有下面几种:
(1)linear线性插值:这是默认插值方法,它是把与插值点靠近的两个数据点以直线连接,在直线上选取对应插值点的数据。这种插值方法兼顾速度和误差,插值函数具有连续性,但平滑性不好。
(2)nearest最邻近点插值:根据插值点和最接近已知数据点进行插值,这种插值方法速度快,占用内存小,但一般误差最大,插值结果最不平滑。
(3)next下一点插值:根据插值点和下一点的已知数据点插值,这种插值方法的优缺点和最邻近点插值一样。
(4)previous前一点插值:根据插值点和前一点的已知数据点插值,这种插值方法的优缺点和最邻近点插值一样。
(5)spline三次样条插值:采用三次样条函数获得插值点数据,要求在各点处具有光滑条件。这种插值方法连续性好,插值结果最光滑,缺点为运行时间长。
(6)cubic三次多项式插值:根据已知数据求出一个三次多项式进行插值。这种插值方法连续性好,光滑性较好,缺点是占用内存多,速度较慢。
需要注意,xi的取值如果超出已知数据X的范围,就会返回NaN错误信息。
MATLAB还提供interp1q函数用于一维插值。它与interp1函数的主要区别是,当已知数据不是等间距分布时,interp1q插值速度比interp1快。需要注意,interp1q执行的插值数据x必须是单调递增的。
【例4-9】 某气象台对当地气温进行测量,实测数据如表4-1所示,用不同的插值方法计算t=12时的气温。
表4-1 某地不同时间的气温

程序代码如下:

程序运行结果:

【例4-10】 假设测量的数据来自函数f(x)=e﹣0.5xsinx,试根据生成的数据,用不同的方法进行插值,比较插值结果。
程序代码如下:

程序运行结果如下,插值效果如图4-2所示。


图4-2 各种插值结果比较
由上面的结果可知,interp1q实现插值的速度比interp1要快;最接近点拟合误差大,直线拟合得到曲线不平滑;采用三次样条插值效果最好,曲线平滑,误差很小,基本逼近真实值。
2.一维快速傅里叶插值
在MATLAB中,一维快速傅里叶插值可以用interpft函数实现。该函数利用傅里叶变换将输入数据变换到频率域,然后用更多点实现傅里叶逆变换,实现对数据的插值。函数调用格式为

【例4-11】 假设测量的数据来自函数f(x)=sinx,试根据生成的数据,用一维快速傅里叶插值,比较插值结果。
程序代码如下:

程序运行结果如下,插值效果如图4-3所示。


图4-3 一维快速傅里叶插值及比较
由上述结果可知,一维快速傅里叶插值interpft实现插值的速度比较快,曲线平滑,误差很小,基本逼近真实值。
3.三次样条插值
三次样条插值利用多段多项式逼近插值,降低了插值多项式的阶数,使得曲线更为光滑。在MATLAB中,interp1插值函数的method选为spline样条插值选项,就可以实现三次样条插值。另外,MATLAB专门提供了三次样条插值函数spline,其格式如下:

【例4-12】 已知数据x=[﹣5﹣4﹣3﹣2﹣1 0 1 2 3 4 5],y=[26 16 9 4 1 0 1 4 9 16 25],对xi=﹣5:0.5:5,用spline进行三次样条插值,并比较用interp1实现三次样条插值的结果。
程序代码如下:

程序运行结果如下,插值效果如图4-4所示。


图4-4 三次样条插值及比较
由程序结果可知,三次样条插值spline函数实现插值的效果和interp1(x,y,xi,'spline')一样。
4.2.2 二维插值
二维插值是指已知一个二元函数的若干个采用数据点x、y和z(x,y),求插值点(x1,y2)处的z1的值。在MATLAB中,提供了interp2函数用于实现二维插值,其调用格式为

其中,X和Y是两个参数的采样点,一般是向量,Z是参数采样点对应的函数值。X1和Y1是插值点,可以是标量也可以是向量。Z1是根据选定的插值方法(method)得到的插值结果。插值方法method和一维插值函数相同,linear为线性插值(默认算法),nearest为最近点插值,spline为三次样条插值,cubic为三次多项式插值。需要注意,X1和Y1不能超出X和Y的取值范围,否则会得到NaN错误信息。
【例4-13】 某实验对计算机主板的温度分布做测试。用x表示主板的宽度(cm),y表示主板的深度(cm),用T表示测得的各点温度(℃),测量结果如表4-2所示。
表4-2 主板各点温度测量值

(1)分别用最近点二维插值和线性二维插值法求(12.6,7.2)点的温度。
(2)用三次多项式插值求主板宽度每1cm、深度每1cm处各点的温度,并用图形显示插值前后主板的温度分布图。
程序代码如下:

运行程序,结果如下,图4-5是插值前后主板温度分布图。由图4-5可知,用插值技术处理数据,可以使得温度分布图更加光滑。


图4-5 插值前后主板温度分布图
4.2.3 多维插值
1.三维插值
在MATLAB中,还提供了三维插值的函数interp3,其调用格式为

其中,X、Y、Z是三个参数的采样点,一般是向量,U是参数采样点对应的函数值。X1、Y1、Z1是插值点,可以是标量也可以是向量。U1是根据选定的插值方法(method)得到的插值结果。插值方法method和一维插值函数相同,linear为线性插值(默认算法),nearest为最近点插值,spline为三次样条插值,cubic为三次多项式插值。需要注意,X1、Y1和Z1不能超出X、Y和Z的取值范围,否则会得到NaN错误信息。
2.n维插值
在MATLAB中,还可以实现更高维的插值,interpn函数用于实现n维插值。其调用格式为

其中,X1,X2,…,Xn是n个参数的采用点,一般是向量,U是参数采样点对应的函数值。Y1,Y2,…,Yn是插值点,可以是标量也可以是向量。U1是根据选定的插值方法(method)得到的插值结果。插值方法method和一维插值函数相同,linear为线性插值(默认算法),nearest为最近点插值,spline为三次样条插值,cubic为三次多项式插值。需要注意,Y1,Y2,…,Yn不能超出X1,X2,…,Xn的取值范围,否则会得到NaN错误信息。