(一)插值
在应用领域中,由有限个已知数据点,构造一个函数,由此计算数据点之间的函数值,称为插值。
一维插值
1.拉格朗日插值法
- 基本原理
构造一组基函数 - Lagrange插值函数
因为matlab没有提供Lagrange插值函数,故需要自己构造。
x0,y0为原始坐标点,维度必须相同。
x为待插值的点。
y是返回值,是最终插值结果。
function y=lagrange(x0,y0,x) %x0,y0为初始坐标,x为需要插值的点,返回的y为插值结果
n=length(x0);m=length(x);
for i=1:m
z=x(i);
s=0;
for j=1:n
p=1;
for k=1:n
if k~=j
p=p*((z-x0(j))/(x0(k)-x0(j)));
end
end
s=p*y0(k)+s;
end
y(i)=s;
end
2.分段线性插值法
- 基本原理
将每两个相邻的节点用直线连起来,如此形成的一条折线就是分段线性插值函数。计算x点的插值时,只用到x左右的两个节点,计算量与节点个数n(初始值x0,y0的长度,n=length(x0))无关,而拉格朗日插值与n值有关。分段线性插值中n越大,分段越多,插值误差越小。 - 分段线性插值函数
matlab有提供现成的函数:interp1
y = interp1(x,y,cx,'method')
- x,y分别表示数据点的横、纵向量
- cx表示需要插值的横坐标数据或数组
- method为可选参数,从以下四个值中任选一个:
- 'linear'——线性插值(默认)
- 'nearest'——最近邻近插值
- 'cubic'——三次插值
- 'spline'——三次样条插值(下面接着讲)
- 三次样条插值
方式一
y = interp1(x,y,cx,'spline')
方式二
pp=csape(x0,y0);
y=ppval(pp,x);
其中x0,y0,x与前面含义相同,返回值y即插值结果。
例题
在12h内,每隔1h测量一次温度,温度依次为:5,8,9,15,25,29,31,30,22,25,27,24.每隔1/10h估计一次温度值.
hours = 1:12;
temps = [5 12 9 15 25 29 31 30 22 25 27 24];
h = 1:0.1:12;
t = interp1(hours,temps,h,'spline');
plot(hours,temps,'+',h,t,hours,temps,'r:');%画图
xlabel('Hour'),ylabel('Degrees Celsius') %横纵坐标分别表示Hour和Degrees Celsius
小结
以上三种插值方法都是一维插值,它们有如下特点:
拉格朗日插值(高次多项式插值):其插值函数在整个区间上是一个解析表达式,便于再次开发利用;曲线光滑;误差估计有表达式;收敛不能保证(有振荡现象);用于理论分析,实际意义不大。
分段线性和三次样条插值(低次多项式插值):曲线不光滑(三次样条插值已有较大改进);收敛性有保证;简单实用,应用广泛。
二维差值
二维差值是基于一维插值同样的思想,但它是对两个变量的函数z = f(x,y)进行插值。
求解思路
构造一个二元函数z = f(x,y),通过全部已知结点,即f(xi,yj) = zij (i=0,1,…,m; j=0,1,…,n) 或 f(xi,yi) = zi(i=0,1,…,n),再利用f(x,y)插值,即z* = f(x*,y*)。
1.网络结点插值法
适用于数据点比较规范,即在所给数据点范围内,数据点要落在由一些平行直线组成的矩形网络的每个顶点上。
问题描述:已知m×n个结点,i = 1,2,…,n,且x1
2 3… m,y1 2 3… n。求点(x*,y*)(!=(xi,yi))处的插值z*。 matlab提供二维插值函数interp2
cz = interp2(x,y,z,cx,cy,'method')
- x,y是自变量。 x是m维向量,指明所给数据网格点的横坐标;y是n维向量,指明所给数据网格点的纵坐标。
- z是m×n阶矩阵,标明相应于所给数据网络点的函数值。
- cx,cy分别是给定的网格点的横、纵坐标。cx,cy应是方向不同的向量,即一个是横向量,一个是纵向量。
- method为可选参数,从以下四个值中任选一个:
- 'linear'——线性插值(默认)
- 'nearest'——最近邻近插值
- 'cubic'——三次插值
- 'spline'——三次样条插值
例题
测得平板表面5x3网格点出的温度分别为:82 81 80 82 84;79 63 61 65 81;84 84 82 85 86.以每间隔0.2个单位网格的地方警醒插值.
clear;clc;
x = 1:5;
y = 1:3;
[x1,y1] = meshgrid(x,y);%使坐标网格化
temps = [82 81 80 82 84;79 63 61 65 81;84 84 82 85 86];
cx = 1:0.2:5;
cy = 1:0.2:3;
[cx1,cy1] = meshgrid(cx,cy);
cz = interp2(x1,y1,temps,cx1,cy1,'cubic');
mesh(cx,cy,cz) %构造曲面的画图函数
2.散乱数据插值
使用于一般的数据点,多用于数据点不太规范的情况。
问题描述:已知n个结点(xi,yi,zi)(i=1,2,…,n),求点(x*,y*)(!=(xi,yi))处的插值z*。
matlab提供二维插值函数griddata
cz = griddata(x,y,z,cx,cy,'method')
- x,y,z均是n维函数,指明所给数据点的横坐标、纵坐标和竖坐标。
- cx,cy分别是给定的网格点的横、纵坐标。cx,cy应是方向不同的向量,即一个是横向量,一个是纵向量。
- method为可选参数,从以下四个值中任选一个:
- 'linear'——线性插值(默认)
- 'nearest'——最近邻近插值
- 'cubic'——三次插值
- 'spline'——三次样条插值
- 'v4'——MATLAB中所提供的插值方法
- 散乱基点的二维插值问题
针对此问题,MATLAB提供了基于修正的shepherd插值法的函数e01sef和e01sff。首先使用e01sef求出参数rnw和fnodes,再将它们用于函数e01sff中,求得插值点的坐标。
函数格式如下
[fnodes,minnq,rnw,rnq,ifail] = e01sef(x,y,z)
[cz(i,j),ifail] = e01sff(x,y,z,rnw,fnodes,cx(i),cy(j))
- x,y,z均是n维函数,指明所给数据点的横坐标、纵坐标和竖坐标。
- cx,cy分别是给定的网格点的横、纵坐标。
- cz是矩阵,其行数和列数分别等于cx和cy的维数
- 函数e01sff求出一个插值点(cx(i),cy(j))所对应的函数值cz(i,j)。
(二)拟合
寻求函数,使得函数在某种准则下与所有数据点最为接近
1.线性最小二乘拟合
命令为:A = polyfit(x,y,m)
其中,x = (x1,x2,…,xn),y = (y1,y2,…,yn),A = (a1,a2,…,am+1)
多项式在x处的值y可用以下命令计算:
y = polyval(A,x)
2.非线性最小二乘拟合
在最小二乘拟合中,若要寻找的函数f(x)是任意的非线性函数,则称为非线性最小二乘拟合。MATLAB提供了两个求非线性最小二乘拟合的函数:lsqcurvefit和lsqnonlin。使用这两个命令是,都要先建立-M文件fun.m,在其中定义函数f(x),但它们定义的方式不同。
lsqcurvefit函数
设一直xdata = (xdata1,xdata2,…,xdatan),ydata = (ydata1,ydata2,…,ydatan),lsqcurvefit用以求含参量x(向量)的向量值函数
F(x,xdata) = (F(x,xdata1),(x,xdata2),…(x,xdatan))T
中的参变量x(向量),使得
最小
输入格式为:
- x = lsqcurvefit('fun',x0,xdata,ydata);
- x = lsqcurvefit('fun',x0,xdata,ydata,options);
- x = lsqcurvefit('fun',x0,xdata,ydata,options,'grad');
- [x,options] = lsqcurvefit('fun',x0,xdata,ydata,…);
- [x,options,funval] = lsqcurvefit('fun',x0,xdata,ydata,…);
- [x,options,funval,Jacob] = lsqcurvefit('fun',x0,xdata,ydata,…);
输出目标函数值格式:
f = fun(x,xdata)
*x0为迭代的初值
lsqnonlin函数
设已知xdata = (xdata1,xdata2,…,xdatan),ydata = (ydata1,ydata2,…,ydatan),lsqnonlin用以求含参量x(向量)的向量值函数
f(x) = (f1(x),f2(x),…,fn(x))T
中的参量x,使得fT(x)f(x) = f21(x)+ f22(x)+…+ f2n(x)最小,其中 fi(x) = f(x,xdatai,ydatai) = F(x,datai)-ydatai.
输入格式为:
- x = lsqnonlin'fun',x0);
- x = lsqnonlin('fun',x0options);
- x = lsqnonlin('fun',x0,options,'grad');
- [x,options] = lsqcurvefit('fun',x0,xdata,ydata,…);
- [x,options,funval] = lsqcurvefit('fun',x0,…);
(拟合问题)
(三)区别与联系
- 联系
都是根据实际中一组已知数据来构造一个能够反映数据变化规律的近似函数的方法。 - 区别
插值问题仅通过插值方法找到未知点对应的值,不一定得到近似函数的表达形式;
数据拟合要求得到一个具体的近似函数表达式。
qs
第一次写博客(๑ت๑)♡
也还在学习中~