MATLAB GUI设计入门与实战
上QQ阅读APP看书,第一时间看更新

1.4 数据插值

我们接触的数据有时是存在缺失的,那么根据前后的数据,如何较精确地知道缺失的数据是什么?这就需要用到数据插值的方法。数据插值包括一维数据插值和二维数据插值,不同的插值方法得到的图形数据精度是不一样的。

1.4.1 一维数据插值

MATLAB提供的函数interp1(),用于进行一维插值,所谓一维插值就是根据二维平面散点图进行平滑插值,达到拟合和预测的目的。

函数interp1()可以有3种调用形式。

(1)yi=interp1(x, y, xi):根据数据[x, y],用分段线性插值算法得到xi各点上的函数近似值yi,yi为尽可能逼近的最小误差对应的因变量值。当y是向量时,则对y向量插值,得到结果yi是与xi同样大小的向量;当y是矩阵时,则对y的逐列向量插值,得到结果yi是一矩阵,它的列数与y的列数相同,行数与xi的大小相同。

(2)yi=interp1(y, yi):格式调用方法与yi=interp1(x, y, xi)相同,只是插值节点不同,此时用节点序号x=1:n,n=size(y)。

(3)yi=interp1(x, y, xi, method):函数调用与yi=interp1(x, y, xi)和yi=interp1(y, yi)相同,只是需要指定输入参数method的具体算法。在MATLAB中,method有6种形式如下:

    >> help interp1
        Vq = interp1(X,V,Xq,METHOD) specifies alternate methods.
    X:x
    V: y
    Xq: xi
    METHOD: Method,插值方法
     
          'nearest'  - 最近邻插值
          'linear'    - 线性插值
          'spline'   - 样条曲线插值
          'pchip'    - 分段立方插值
          'cubic'    - 立方插值
          'v5cubic'  - 如果X不是等距节点,不进行外插,采用样条插值

其中,最常用的是第5种插值方式,当然用户可以选择不同的插值方法去实现插值操作。

1)nearest:最近邻插值,即在插值节点的近邻区域内取函数值,该插值函数为一个阶梯函数,即:

具体的MATLAB最近邻插值程序如下:

    clc,clear,close all      % 清理命令区、清理工作区、关闭显示图形
    warning off               % 消除警告
    feature jit off          % 加速代码运行
    tic                      % 运算计时
    x = [1:10];                    % x
    y = [1, 1, 7, 4, 0, 6, 3, 0, 8, 7];   % y
    figure('color',[1,1,1])              % 先建一个图形窗口
    hold on                                  % 图像保持画图句柄
    plot(x,y,'o--','linewidth',2)        % 原数图形
    xi = 1:0.1:10;                           % x
    yi = interp1(x,y,xi,'nearest');    % 最近邻插值
    hold on                               % 图形保持画图
    grid on                               % 网格化
    plot(xi,yi,'r*--','linewidth',2)     % 原数图形
    xlabel('x');  ylabel('y');  
    legend('原始数据','nearest插值')
    toc  % 计时结束

运行程序输出结果如图1-25所示。

图1-25 nearest插值

2)linear:分段线性插值,当不指定插值方法时,默认采用线性插值方法。

分段线性插值是在每个小区间上采用简单的线性插值。在区间上的子插值多项式为:

分段线性插值方法较为常用,在实际计算中,处理速度较快,但是对海量数据本身而言,以及非线性问题,处理误差较大,线性插值方法获得的曲线不是平滑的,因此,应根据实际情况要求选择。

表1-6所示为待插值数据。

表1-6 源数据

具体的MATLAB线性插值程序如下:

    % Designed by Yu Shengwei From SWJTU University
    % 2014年12月29日
    clc,clear,close all                      % 清理命令区、清理工作区、关闭显示图形
    warning off                               % 消除警告
    feature jit off                          % 加速代码运行
    tic                                      % 运算计时
    x = [1:10];
    y = [1, 1, 7, 4, 0, 6, 3, 0, 8, 7];      % y值
    figure('color',[1,1,1])                  % 先建图形窗口
    hold on
    plot(x,y,'o--','linewidth',2)            % 原数图形
    xi = 1:0.1:10;
    yi = interp1(x,y,xi);                   % 默认情况下为线性插值
    hold on                                   % 图形保持画图
    grid on                                   % 网格化
    plot(xi,yi,'r*--','linewidth',2)          % 原数图形
    xlabel('x');  ylabel('y');                 % xy轴标记
    legend('原始数据','linear插值')
    toc  % 计时结束

运行程序输出图形如图1-26所示。

图1-26 linear插值

3)spline:三次样条插值,即在每个分段(子区间)内构造一个三次多项式,使其插值函数满足差值条件外,还要求在各个节点处具有光滑的条件(导数存在)。

三次样条函数sx)在每个子区间上可由4个系数唯一确定。因此,sx)在[ab]上有4n个待定系数。

由于,则有:

为了确定sx),通常还需要补充边界条件,常用的边界条件分为三类。

第一种边界条件:给定两边界节点处的一阶导数,并要求sx)满足

第二种边界条件:给定两边界节点处的二阶导数,并要求sx)满足

特别地,若,则所得的样条称为自然样条。

第三种边界条件:被插函数fx)是以为周期的周期函数,要求sx)满足

具体的三次样条插值程序如下:

    clc,clear,close all                      % 清理命令区、清理工作区、关闭显示图形
    warning off                               % 消除警告
    feature jit off                          % 加速代码运行
    tic  % 运算计时
    x = [1:10];
    y = [1, 1, 7, 4, 0, 6, 3, 0, 8, 7];    % y轴
    figure('color',[1,1,1])
    hold on
    plot(x,y,'o--','linewidth',2)            % 原数图形
    xi = 1:0.1:10;
    yi = interp1(x,y,xi,'spline');            % 样条插值
    hold on                                   % 图形保持画图
    grid on                                   % 网格化
    plot(xi,yi,'r*--','linewidth',2)          % 原数图形
    xlabel('x');  ylabel('y');  
    legend('原始数据','spline插值')
    toc  % 计时结束

运行程序输出图形如图1-27所示。

图1-27 spline插值

4)pchip:分段立方插值。分段立方插值的思想就是将插值的数据分段,针对每一段采用立方插值的方法进行拟合逼近,具体的MATLAB代码如下:

    x = [1:10];
    y = [1, 1, 7, 4, 0, 6, 3, 0, 8, 7];
    figure('color',[1,1,1])
    hold on
    plot(x,y,'o--','linewidth',2)          % 原数图形
    xi = 1:0.1:10;
    yi = interp1(x,y,xi,'pchip');         % 分段立方插值
    hold on                                % 图形保持画图
    grid on                                 % 网格化
    plot(xi,yi,'r*--','linewidth',2)      % 原数图形
    xlabel('x');  ylabel('y');  
    legend('原始数据','pchip插值')

运行程序输出图形如图1-28所示。

图1-28 pchip插值

5)cubic:立方插值。cubic插值法插值精度较高,插值曲线较平滑。

具体的MALTAB cubic插值程序如下:

    tic                                  % 运算计时
    x = [1:10];
    y = [1, 1, 7, 4, 0, 6, 3, 0, 8, 7];
    figure('color',[1,1,1])
    hold on
    plot(x,y,'o--','linewidth',2)          % 原数图形
    xi = 1:0.1:10;
    yi = interp1(x,y,xi,'cubic');         % 双立方插值
    hold on                                % 图形保持画图
    grid on                                 % 网格化
    plot(xi,yi,'r*--','linewidth',2)     % 原数图形
    xlabel('x');  ylabel('y');  
    legend('原始数据','cubic插值')
    toc                                  % 计时结束

运行程序得到如图1-29所示图形。

图1-29 cubic插值

6)v5cubic:MATLABv5版本cubic插值方法。v5cubic是一种旧MATLAB版本下的cubic插值方法,类似于三次样条插值方法,该插值方法要求插值点为均匀间隔的插值点。这种v5cubic方法逐渐被cubic取代。

具体的MALTAB v5cubic插值程序如下:

    clc,clear,close all                 % 清理命令区、清理工作区、关闭显示图形
    warning off                           % 消除警告
    feature jit off                         % 加速代码运行
    tic                                  % 运算计时
    x = [1:10];
    y = [1, 1, 7, 4, 0, 6, 3, 0, 8, 7];
    figure('color',[1,1,1])
    hold on
    plot(x,y,'o--','linewidth',2)        % 原数图形
    xi = 1:0.1:10;
    yi = interp1(x,y,xi,'v5cubic');
    hold on                                % 图形保持画图
    grid on                                 % 网格化
    plot(xi,yi,'r*--','linewidth',2)     % 原数图形
    xlabel('x');  ylabel('y');  
    legend('原始数据','v5cubic插值')
    toc  % 计时结束

运行程序得到如图1-30所示图形。

图1-30 v5cubic插值

1.4.2 二维数据插值

二维数据插值是构造一个二元插值函数去近似,即曲面插值。与interp1类似,指令griddata可以根据数据表[x, y, z],用各种不同的算法计算[xi, yi]各点上的函数近似值zi。

(1)zi = griddata(x, y, z, xi, yi):本指令格式根据数据表[x, y, z],用双线性差值算法计算坐标平面x-y上[xi, yi]各点的二元函数近似值zi,这里x可以是一个行向量,它与矩阵z的各列向量相对应;y可以为一个列向量,它与z的各行向量相对应。对于[xi, yi]与zi间的对应关系,则和[x, y]与z的关系相同。

(2)zi =griddata (x, y, z, xi, yi, method):本指令格式的调用方法与griddata(x, y, z, xi, yi)格式相同,只是规定在格式中指定具体的算法。

在MATLAB中,method有如下4种形式。

        Vq = griddata(...,METHOD) specifies alternate methods. The default
        is linear interpolation. Available methods are:
    
    METHOD: Method,插值方法
          'nearest'     - 最近邻插值
          'linear'     - 线性插值
          'cubic'      - 立方插值

表1-7所示为待插值数据。

表1-7 源数据

绘制表1-7所示数据的三维曲面,程序如下:

    % Designed by Yu Shengwei From SWJTU University
    % 2014年12月29日
    clc,clear,close all      % 清理命令区、清理工作区、关闭显示图形
    warning off               % 消除警告
    feature jit off           % 加速代码运行
    tic  % 运算计时
    x = [1:10];
    y = [0, 0, 1, 1, 3, 4, 6, 7, 7, 8];
    z = [8, 2, 8, 0, 3, 7, 8, 2, 4, 1];
    [X,Y] = meshgrid(x,y);    % 栅格
    Z = z'*ones(1,length(x));
    mesh(X,Y,Z)
    toc  % 计时结束

运行程序输出图形如图1-31所示。

图1-31 原始数据图

1)采用最近邻插值nearest。

具体的MALTAB nearest插值程序如下:

    clc,clear,close all                      % 清理命令区、清理工作区、关闭显示图形
    warning off                               % 消除警告
    feature jit off                          % 加速代码运行
    tic  % 运算计时
    x = [1:10];
    y = [0, 0, 1, 1, 3, 4, 6, 7, 7, 8];    % y值
    z = [8, 2, 8, 0, 3, 7, 8, 2, 4, 1];      % z值
    Z = z'*ones(1,length(x));
    figure('color',[1,1,1])                    % 先建一个图形窗口
    xi = min(x):(max(x)-min(x))/50:max(x);    % 插值数据
    yi = min(y):(max(y)-min(y))/50:max(y);    % 插值数据
    yi = yi'; % 转置
    Zi = griddata(x,y,Z,xi,yi,'nearest');    % 插值
    mesh(xi,yi,Zi)                           % 画图
    grid on                                     % 网格化
    xlabel('x'); ylabel('y'); zlabel('z')    % xyz轴标记
    title('nearest插值')
    toc  % 计时结束

运行程序得到如图1-32所示图形。

图1-32 nearest插值

2)采用线性插值linear。

具体的MALTAB linear插值程序如下:

    clc,clear,close all                      % 清理命令区、清理工作区、关闭显示图形
    warning off                               % 消除警告
    feature jit off                          % 加速代码运行
    tic  % 运算计时
    x = [1:10];
    y = [0, 0, 1, 1, 3, 4, 6, 7, 7, 8];      % y值
    z = [8, 2, 8, 0, 3, 7, 8, 2, 4, 1];      % z值
    Z = z'*ones(1,length(x));
    figure('color',[1,1,1])                   % 先建一个图形窗口
    xi = min(x):(max(x)-min(x))/50:max(x);    % 插值数据
    yi = min(y):(max(y)-min(y))/50:max(y);    % 插值数据
    yi = yi';                                     % 转置
    Zi = griddata(x,y,Z,xi,yi,'linear');    % 插值
    mesh(xi,yi,Zi)                           % 画图
    grid on                                     % 网格化
    xlabel('x'); ylabel('y'); zlabel('z')  
    title('linear插值')
    toc  % 计时结束

运行程序得到如图1-33所示图形。

图1-33 linear插值

3)采用cubic插值。

具体的MALTAB cubic插值程序如下:

    clc,clear,close all          % 清理命令区、清理工作区、关闭显示图形
    warning off                   % 消除警告
    feature jit off              % 加速代码运行
    tic  % 运算计时
    x = [1:10];
    y = [0, 0, 1, 1, 3, 4, 6, 7, 7, 8];
    z = [8, 2, 8, 0, 3, 7, 8, 2, 4, 1];
    Z = z'*ones(1,length(x));
    figure('color',[1,1,1])
    xi = min(x):(max(x)-min(x))/50:max(x);      % 插值数据
    yi = min(y):(max(y)-min(y))/50:max(y);      % 插值数据
    yi = yi';                                     % 转置
    Zi = griddata(x,y,Z,xi,yi,'cubic');           % 插值
    mesh(xi,yi,Zi)                                % 画图
    grid on                                          % 网格化
    xlabel('x'); ylabel('y'); zlabel('z')  
    title(' cubic插值')
    toc  % 计时结束

运行程序得到如图1-34所示图形。

图1-34 cubic插值