插值是离散函数逼近的重要方法,当需要通过函数有限个点去估算函数再其他点的近似值时,可根据已知样本创造一个函数,使得函数在已知点的值与样本相同,即可得到其他点的近似值。
在拉格朗日多项式中,我们已知N个点的坐标,构造函数,形如y1*(x-x2)(x-x3)(x-x4)…(x-xn)/[(x1-x2)(x1-x3)(x1-x4)…(x1-xn)]+y2*(x-x1)(x-x3)(x-x4)…(x-xn)/[(x2-x1)(x2-x3)(x2-x4)…(x2-xn)]+的多项式函数,且函数最多为N-1次。
可看出在已知点的坐标在多项式函数上。
function y = lagrange_interpolation(x0,y0,x)
%拉格朗日插值函数
%n 个节点数据以数组 x0, y0 输入(注意 Matlat 的数组下标从1开始),
%m 个插值点以数组 x 输入,输出数组 y 为 m 个插值
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
上图为运行效果,其中蓝色小点为插值点,圆点为已知点。
以上代码并未求出多项式函数表达式,因为此种方法进行函数拟合时,虽然经过了每一个已知点,但容易在边界点处出现过拟合,形成震荡,难以看出数据趋势,因此较适合于求函数有点的插值。
利用分段三次函数来连接N个已知点。先列一元三次四未知系数的N-1个方程,每一段函数经过两个已知点,且在第二个点处的导数值与下一段函数在该点的导数值相同,又有两个函数在该点的二阶导数相同,则在每个已知点可列出四个方程。由于未知数与方程个数相差两个,因此需人工给出根据实际问题的两个边界条件,边界条件为首个点与最后一个点在首个与最后一个函数的导数值,即为入射速率与出射速率。
1、经过每个已知点
2、计算过程为解线性方程组
3、可控制边界条件来改变拟合曲线
4、在数据端点处不会有震荡效果
1、分段函数不易于迭代
2、无法反应整体趋势
3、边界条件人为因素较大
4、仍然存在过拟合效果
x = [0 2 4 5 8 12 12.8 17.2 19.9 20]; y = exp(x).*sin(x);
xx = 0:.25:20;
yy = spline(x,y,xx);
plot(x,y,'o',xx,yy)
设方程y = ax+b,将y1-f(x1)形式的平方和来得到一个以a、b为未知数的二次函数,利用导数或合并同类项方法来得到未知数,得出拟合方程。
%最小二乘法
clear
clc
x=[9,13,15,17,18.6,20,23,29,31.7,35];
y=[-8,-6.45,-5.1,-4,-3,-1.95,-1.5,-0.4,0.2,-0.75];
coefficient=polyfit(x,y,1); %用一次函数拟合曲线,想用几次函数拟合,就把n设成那个数
y1=polyval(coefficient,x);
plot(x,y,'o',x,y1,'-')
设一元三次方程,进行线性拟合相同的操作,进行坐标值减去函数值做平方和,得到四未知数的方程,用该方程做偏导数,可计算出未知数。
%最小二乘法
clear
clc
x=[9,13,15,17,18.6,20,23,29,31.7,35];
y=[-8,-6.45,-5.1,-4,-3,-1.95,-1.5,-0.4,0.2,-0.75];
coefficient=polyfit(x,y,2); %用一次函数拟合曲线,想用几次函数拟合,就把n设成那个数
y1=polyval(coefficient,x);
plot(x,y,'o',x,y1,'-')