在工程测量和科学实验中,所得到的数据通常都是离散的。如果要得到这些离散点以外的其他点的数值,就需要根据这些已知数据进行插值。例如,测量得
n
n
n 个点的数据为
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
…
,
(
x
n
,
y
n
)
(x_{1},y_{1}),(x_{2},y_{2}),dots ,(x_{n},y_{n})
(x1,y1),(x2,y2),…,(xn,yn),这些数据点反映了一个函数关系
y
=
f
(
x
)
y=f(x)
y=f(x),然而并不知道
f
(
x
)
f(x)
f(x) 的解析式。
数据插值的任务就是根据上述条件构造一个函数
y
=
g
(
x
)
y=g(x)
y=g(x), 使得在
x
(
i
=
1
,
2
,
.
.
.
n
)
x(i=1, 2, ... n)
x(i=1,2,...n),有
g
(
x
)
=
f
(
x
)
g(x)=f(x)
g(x)=f(x),且在两个相邻的采样点
(
x
i
,
x
i
+
1
)
(
i
=
1
,
2
,
…
,
n
−
1
)
(x_{i},x_{i+1})(i=1,2,dots ,n-1)
(xi,xi+1)(i=1,2,…,n−1) 之间,
g
(
x
)
g(x)
g(x) 光滑过渡。如果被插值函数
f
(
x
)
f(x)
f(x) 是光滑的,并且采样点足够密,一般在采样区间内,
f
(
x
)
f(x)
f(x) 与
g
(
x
)
g(x)
g(x) 比较接近。插值函数
g
(
x
)
g(x)
g(x) 一般由线性函数、多项式、样条函数或这些函数的分段函数充当。
根据被插值函数的自变量个数,插值问题分为一维插值、 二维插值和多维插值等;根据选用的插值方法,插值问题又分为线性插值、多项式插值和样条插值等。MATLAB 提供了一维、二维、
N
N
N 维数据插值函数 interp1、interp2 和 interpn,以及 3 次埃尔米特(Hermite)插值函数 pchip 和 3 次样条插值函数 spline 等。
函数根据
X
、
Y
X、Y
X、Y 的值,计算函数在
X
1
X1
X1 处的值。其中,
X
、
Y
X、Y
X、Y 是两个等长的已知向量,分别描述采样点和采样值。若同一个采样点有多种采样值,则
Y
Y
Y 可以为矩阵,
Y
Y
Y 的每一列对应一组采样。
X
1
X1
X1 是一个向量或标量,描述欲插值的点,
Y
1
Y1
Y1 是一个与
X
1
X1
X1 等长的插值结果。method 用于指定插值方法,允许的取值有以下几种。
注意:对于超出 X 范围的插值点,使用 “linear” 和 “nearest” 插值方法,会给出 “NaN” 错误。对于其他的方法,将对超出范围的插值点执行外插值算法。
例如,以下概率积分的数据如下表所示,我们用不同的插值方法计算
f
(
0.472
)
f(0.472)
f(0.472)。
f
(
x
)
=
2
π
∫
0
x
e
−
x
2
d
x
f(x)=frac{2}{sqrt{pi}}int_{0}^{x}e^{-x^{2}}mathrm{d}x
f(x)=π2∫0xe−x2dx
x
x
x
f
(
x
)
f(x)
f(x)
0.46
0.4846555
0.47
0.4937542
0.48
0.5027498
0.49
0.5116683
这是一个一维插值问题,程序如下:
>> x=0.46:0.01:0.49;%给出x
>> f=[0.4846555,0.4937542,0.5027498,0.5116683];%给出f(x)>> format long%显示小数点后16位
>>interp1(x,f,0.472)%用默认方法,即线性插值计算f(0.472)
ans =0.495553320000000>>interp1(x,f,0.472,'nearest')%用最近点插值计算f(0.472)
ans =0.493754200000000>>interp1(x,f,0.472,'pchip')%用3次埃尔米特计算f(0.472)
ans =0.495561119712056>>interp1(x,f,0.472,'spline')%用3次样条插值计算f(0.472)
ans =0.495560736000000>> format short%小数点后显示4位
其中,
X
、
Y
X、Y
X、Y 是两个向量,分别描述两个参数的采样点,
Z
Z
Z 是与参数采样点对应的函数值,
X
1
、
Y
1
X1、Y1
X1、Y1 是两个向量或标量,描述欲插值的点。
Z
1
Z1
Z1 是根据相应的插值方法得到的插值结果。
method 的取值与一维插值函数相同,但二维插值不支持 'pchip' 方法。
X
、
Y
、
Z
X、Y、Z
X、Y、Z 也可以是矩阵形式。同样,对于超出
X
、
Y
X、Y
X、Y 范围的插值点,使用 'linear' 和 'nearest' 插值方法,会给出 NaN 错误。对于 'spline' 方法,将对超出范围的插值点执行外插值算法。
例如,设
z
=
x
2
+
y
2
z=x^{2}+y^{2}
z=x2+y2,我们对
z
z
z 函数在
[
0
,
1
]
×
[
0
,
2
]
[0,1]×[0,2]
[0,1]×[0,2] 区域内进行插值。
程序如下:
>> x=0:0.1:1;>> y=0:0.2:2;>>[X,Y]=meshgrid(x,y);%产生自变量网络坐标
>> Z=X.^2+Y.^2;%求对应的函数值
>>interp2(x,y,Z,0.5,0.5)%在(0.5.0.5)点插值
ans =0.5100>>interp2(x,y,Z,[0.5,0.6],0.4)%在(0.5.0.4)点和(0.6,0.4)点插值
ans =0.41000.5200>>interp2(x,y,Z,[0.5,0.6],[0.4,0.5])%在(0.5.0.4)点和(0.6,0.5)点插值
ans =0.41000.6200%在(0.5.0.4),(0.6.0.4),(0.5.0.5)和(0.6,0.5)各点插值
>>interp2(x,y,Z,[0.50.6]',[0.40.5])
ans =0.41000.52000.51000.6200
如果想提高插值精度,可选择插值方法为 'spline',对于本例,精度可以提高。输入如下程序:
>>interp2(x,y,Z,[0.50.6]',[0.4 0.5],'spline')
ans =0.41000.52000.50000.6100
例如,某实验对一根长 10 m 的钢轨进行热源的温度传播测试。用
d
d
d 表示测量点距离(m),用
t
t
t 表示测量时间(s),用
c
c
c 表示测得各点的温度(℃),测量结果如下表所示。我们试用线性插值求出在一分钟内每隔 20 s、钢轨每隔 2 m 处的温度。
ci =95.000030.20005.600000090.333347.400027.466716.00007.20004.000081.000058.866744.933333.200022.733317.666767.000064.600058.000051.600046.600041.0000
下图是根据插值结果
[
d
i
,
t
i
,
c
i
]
[d_{i},t_{i},c_{i}]
[di,ti,ci],用绘图函数 surf(di,ti,ci) 绘制的钢轨温度分布图。如果加密插值点,则绘制的分布图更理想。
为此,构造函数
y
=
g
(
x
)
y=g(x)
y=g(x) 去逼近
f
(
x
)
f(x)
f(x),这里不要求曲线
g
(
x
)
g(x)
g(x) 严格通过采样点,但希望
g
(
x
)
g(x)
g(x) 能尽量地靠近这些点,就是使误差
δ
i
=
g
(
x
)
−
f
(
x
)
(
i
=
1
,
2
,
…
,
n
)
δ_{i}=g(x)-f(x) (i=1, 2,…,n)
δi=g(x)−f(x)(i=1,2,…,n) 在某种意义下达到最小。
MATLAB 曲线拟合的最优标准是采用常见的最小二乘原理,所构造的
g
(
x
)
g(x)
g(x) 是一个次数小于插值节点个数的多项式。
我们假设测得
n
n
n 个离散数据点
(
x
i
,
y
i
)
(
i
=
1
,
2
,
.
.
.
n
)
(x_{i}, y_{i})(i=1, 2,... n)
(xi,yi)(i=1,2,...n),欲构造一个
m
(
m
≤
n
)
m(m≤n)
m(m≤n) 次多项式
p
(
x
)
p(x)
p(x):
p
(
x
)
=
a
m
x
m
+
a
m
−
1
x
m
−
1
+
…
+
a
1
x
+
a
0
p(x)=a_{m}x^{m}+a_{m-1}x^{m-1}+…+a_{1}x+a_{0}
p(x)=amxm+am−1xm−1+…+a1x+a0
所谓曲线拟合的最小二乘原理,就是使上述拟合多项式在各节点处的偏差
p
(
x
i
)
−
y
i
p(x_{i})-y_{i}
p(xi)−yi 的平方和
∑
i
=
1
n
(
p
(
x
i
)
−
y
i
)
2
sum_{i=1}^{n}(p(x_{i})-y_{i})^{2}
∑i=1n(p(xi)−yi)2 达到最小。数学上已经证明,上述最小二乘逼近问题的解总是确定的。
函数根据采样点
X
X
X 和采样点函数值
Y
Y
Y,产生一个
m
m
m 次多项式
P
P
P 及其在采样点的误差向量
S
S
S。
其中
X
、
Y
X、Y
X、Y 是两个等长的向量,
P
P
P 是一个长度为
m
+
1
m+1
m+1 的向量,
P
P
P 的元素为多项式系数。mu 是一个二元向量,mu(1) 是函数 mean(X) 求向量
X
X
X 的平均值,而 mu(2) 是函数 std(X) 求向量
X
X
X 的方差。
可以用 polyval 函数按所得的多项式计算
X
X
X 各点上多项式的值。
例如,我们用一个 3 次多项式在区间
[
0
,
2
π
]
[0,2pi]
[0,2π] 内逼近函数
sin
x
sin x
sinx。
在给定区间上,我们均匀地选择 50 个采样点,并计算采样点的函数值,然后利用 3 次多项式逼近。
程序如下:
>> X=linspace(0,2*pi,50);%在0到2Π之间等差的选取50个点
>> Y=sin(X);>> P=polyfit(X,Y,3)%得到3次多项式的系数和误差
P =0.0912-0.85961.8527-0.1649
以上求得了 3 次拟合多项式
p
(
x
)
p(x)
p(x) 的系数,得
p
(
x
)
=
0.0912
x
3
−
0.8596
x
2
+
1.8527
x
−
0.1649
p(x)=0.0912x^{3}-0.8596x^{2}+1.8527x-0.1649
p(x)=0.0912x3−0.8596x2+1.8527x−0.1649。
下面,我们利用绘图函数得方法将多项式
p
(
x
)
p(x)
p(x) 和
sin
x
sin x
sinx进行比较,程序如下:
>> X=linspace(0,2*pi,50);>> Y=sin(X);>> P=polyfit(X,Y,3)
P =0.0912-0.85961.8527-0.1649>> Y1=polyval(P,X);>>plot(X,Y,':o',X,Y1,'-*')
绘制出
sin
x
sin x
sinx 和多项式
p
(
x
)
p(x)
p(x) 在给定区间得函数曲线,如下图所示。其中虚线是
sin
x
sin x
sinx,实线是
p
(
x
)
p(x)
p(x)。函数 polyval(P,X) 返回多项式
p
(
x
)
p(x)
p(x) 得值。
三、数值微分
一般来说,函数的导数依然是一个函数。设函数
f
(
x
)
f(x)
f(x) 的导函数
f
′
(
x
)
=
g
(
x
)
f'(x)=g(x)
f′(x)=g(x),高等数学关心的是
g
(
x
)
g(x)
g(x) 的形式和性质,而数值分析关心的问题是怎样计算
g
(
x
)
g(x)
g(x) 在一串离散点
X
=
(
x
1
,
x
2
,
…
,
x
n
)
X=(x_{1}, x_{2},…,x_{n})
X=(x1,x2,…,xn) 的近似值
G
=
(
g
1
,
g
2
,
…
,
g
n
)
G=(g_{1},g_{2},…,g_{n})
G=(g1,g2,…,gn) 以及所计算的近似值有多大误差。
1. 数值差分与差商
任意函数
f
(
x
)
f(x)
f(x) 在
x
x
x 点的导数是通过极限定义的:
f
′
(
x
)
=
lim
h
→
0
f
(
x
+
h
)
−
f
(
x
)
h
f'(x)=lim_{h o 0}frac{f(x+h)-f(x)}{h}
f′(x)=h→0limhf(x+h)−f(x)
f
′
(
x
)
=
lim
h
→
0
f
(
x
)
−
f
(
x
−
h
)
h
f'(x)=lim_{h o 0}frac{f(x)-f(x-h)}{h}
f′(x)=h→0limhf(x)−f(x−h)
f
′
(
x
)
=
lim
h
→
0
f
(
x
+
h
/
2
)
−
f
(
x
−
h
/
2
)
h
f'(x)=lim_{h o 0}frac{f(x+h/2)-f(x-h/2)}{h}
f′(x)=h→0limhf(x+h/2)−f(x−h/2)
上述式子中,均假设
h
>
0
h>0
h>0,如果去掉上述等式右端的
h
⟶
0
hlongrightarrow 0
h⟶0 的极限过程,并引进记号:
△
f
(
x
)
=
f
(
x
+
h
)
−
f
(
x
)
igtriangleup f(x)=f(x+h)-f(x)
△f(x)=f(x+h)−f(x)
▽
f
(
x
)
=
f
(
x
)
−
f
(
x
−
h
)
igtriangledown f(x)=f(x)-f(x-h)
▽f(x)=f(x)−f(x−h)
δ
f
(
x
)
=
f
(
x
+
h
/
2
)
−
f
(
x
−
h
/
2
)
delta f(x)=f(x+h/2)-f(x-h/2)
δf(x)=f(x+h/2)−f(x−h/2)
称
△
f
(
x
)
、
▽
f
(
x
)
igtriangleup f(x)、igtriangledown f(x)
△f(x)、▽f(x) 及
δ
f
(
x
)
delta f(x)
δf(x) 分别在函数
x
x
x 点处以
h
(
h
>
0
)
h(h>0)
h(h>0) 为步长的向前差分、向后差分和中心差分。当步长为
h
h
h 充分小时,有
f
′
(
x
)
≈
△
f
(
x
)
h
f'(x)approx frac{igtriangleup f(x)}{h}
f′(x)≈h△f(x)
f
′
(
x
)
≈
▽
f
(
x
)
h
f'(x)approx frac{igtriangledown f(x)}{h}
f′(x)≈h▽f(x)
f
′
(
x
)
≈
δ
f
(
x
)
h
f'(x)approx frac{delta f(x)}{h}
f′(x)≈hδf(x)
和差分一样,称
△
f
(
x
)
/
h
、
▽
f
(
x
)
/
h
igtriangleup f(x)/h、igtriangledown f(x)/h
△f(x)/h、▽f(x)/h 及
δ
f
(
x
)
/
h
delta f(x)/h
δf(x)/h 分别为函数在
x
x
x 点处以
h
(
h
>
0
)
h(h>0)
h(h>0) 为步长的向前差商、向后差商和中心差商。
当步长
h
(
h
>
0
)
h(h>0)
h(h>0) 充分小时,函数
f
f
f 在点
x
x
x 的微分接近于函数在该点的任意种差分,而
f
f
f 在点
x
x
x 的导数接近于函数在该点的任意种差商。
2. 数值微分的实现
有两种方式计算任意函数
f
(
x
)
f(x)
f(x) 在给定点
x
x
x 的数值导数,第一种方式是用多项式或样条函数
g
(
x
)
g(x)
g(x) 对
f
(
x
)
f(x)
f(x) 进行逼近(插值或拟合),然后用逼近函数
g
(
x
)
g(x)
g(x) 在点
x
x
x 处的导数作为
f
(
x
)
f(x)
f(x) 在点
x
x
x 处的导数,第二种方式是用
f
(
x
)
f(x)
f(x) 在点
x
x
x 处的某种差商作为其导数。
(1) DX=dif(X):计算向量
X
X
X 的向前差分,
D
X
(
i
)
=
X
(
i
+
1
)
−
X
(
i
)
,
i
=
1
,
2
,
…
,
n
−
1
DX(i)=X(i+1)-X(i), i=1,2,…,n-1
DX(i)=X(i+1)−X(i),i=1,2,…,n−1。
(2) DX= diff(X,n):计算
X
X
X 的
n
n
n 阶向前差分。例如,diff(X,2)=diff(diff(X))。
(3) DX-dif(A,n,dim):计算矩阵
A
A
A 的
n
n
n 阶差分,dim=1 时(默认状态),按列计算差分;dim=2 时,按行计算差分。
例如,我们设
x
x
x 由
[
0
,
2
π
]
[0, 2pi]
[0,2π] 间均匀分布的 6 个点组成,求
sin
x
sin x
sinx 的 1~3 阶差分。
程序如下:
>> X=linspace(0,2*pi,6);>> Y=sin(X)
Y =00.95110.5878-0.5878-0.9511-0.0000>> DY=diff(Y)%计算Y的一阶差分
DY =0.9511-0.3633-1.1756-0.36330.9511>> D2Y=diff(Y,2)%计算Y的二阶差分,也可以用命令diff(DY)计算
D2Y =-1.3143-0.81230.81231.3143>> D3Y=diff(Y,3)%计算Y的三阶差分,也可以用命令diff(D2Y)或diff(DY,2)计算
D3Y =0.50201.62460.5020
例如,设
f
(
x
)
=
x
3
+
2
x
2
−
x
+
12
+
x
+
5
6
+
5
x
+
2
f(x)=sqrt{x^{3}+2x^{2}-x+12}+sqrt[6]{x+5}+5x+2
f(x)=x3+2x2−x+12+6x+5+5x+2 我们用不同的方法求函数
f
(
x
)
f(x)
f(x) 的数值导数,并在用一个坐标系中画出
f
′
(
x
)
f'(x)
f′(x) 的图像。
首先用一个 5 次多项式
p
(
x
)
p(x)
p(x) 拟合函数
f
(
x
)
f(x)
f(x),并对
p
(
x
)
p(x)
p(x) 求一般意义下的导数
d
p
(
x
)
dp(x)
dp(x),求出
d
p
(
x
)
dp(x)
dp(x) 在假设点的值。
第二种方法直接求
f
(
x
)
f(x)
f(x) 在假设点的数值导数。
第三种方法求出
f
′
(
x
)
f'(x)
f′(x):
f
′
(
x
)
=
3
x
2
+
4
x
−
1
2
x
3
+
2
x
2
−
x
+
12
+
1
6
x
+
5
6
+
5
f'(x)=frac{3x^{2}+4x-1}{2sqrt{x^{3}+2x^{2}-x+12}}+frac{1}{6sqrt[6]{x+5}}+5
f′(x)=2x3+2x2−x+123x2+4x−1+66x+51+5
然后直接求
f
′
(
x
)
f'(x)
f′(x) 在假设点的导数,最后在同一坐标轴显示这 3 条曲线。