数学建模常见的一些方法
1. 插值算法
- 数模比赛中,常常需要根据已知的函数点进行数据、模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,“模拟产生”一些新的但又比较靠谱的值来满足需求,这就是插值的作用。
1.1 插值法的定义
1.2 插值法的分类
注:三角插值一般要用到傅里叶变换等复杂的数学工具。
1.3 一般插值多项式原理
1.4 拉格朗日插值法
在数值分析中,拉格朗日插值法是以法国十八世纪数学家约瑟夫∙路易斯∙拉格朗日命名的一种多项式插值方法。在若干个不同的地方得到相应的观测值,拉格朗日插值法可以找到一个多项式,其恰好在各个观测的点取到观测到的值。
1.5 龙格现象(Runge phenomenon)
高次插值会产生龙格现象,即在两端处波动极大,产生明显的震荡。在不熟悉曲线 运动趋势的前提下,不要轻易使用高次插值。
1.6 分段线性插值
1.7 分段二次插值
1.8 牛顿插值法
1.9 两种插值法的对比
1.10 两种插值法的另一个缺点
上面讲的两种插值仅仅要求插值多项式在插值节点处与被插函数有相等的函数值,而这种插值多项式却不能全面反映被插值函数的性态。 然而在许多实际问题中,不仅要求插值函数与被插值函数在所有节点处有相同的函数值,它也需要在一个或全部节点上插值多项式与被插函数有相同的低阶甚至高阶的导数值。 对于这些情况,拉格朗日插值和牛顿插值都不能满足。
1.11 埃尔米特 (Hermite)插值
不但要求在节点上的函数值相等,而且还要求对应的导数值也相等,甚至要求 高阶导数也相等,满足这种要求的插值多项式就是埃尔米特插值多项式。
1.12 埃尔米特 (Hermite)插值原理
1.13 分段三次埃尔米特插值
1.14 三次样条插值
1.15 三次样条多项式满足的条件
1.16 三次样条插值
Z =
1.0e+03 *
0.0010 0.0030 0.0050 0.0070 0.0090 0.0110 0.0130 0.0150
1.9130 1.9450 1.9200 2.2050 2.2600 2.3020 2.3850 2.4200
0.0051 0.0032 0.0067 0.0034 0.0024 0.0041 0.0064 0.0046
0.0219 0.0200 0.0268 0.0277 0.0234 0.0227 0.0254 0.0260
0.0248 0.0257 0.0268 0.0280 0.0304 0.0300 0.0276 0.0308
0.0093 0.0091 0.0091 0.0093 0.0092 0.0093 0.0092 0.0093
0.0018 0.0023 0.0019 0.0021 0.0021 0.0011 0.0015 0.0015
0.0280 0.0240 0.0260 0.0220 0.0220 0.0200 0.0190 0.0230
0.4251 0.4580 0.4925 0.4921 0.5019 0.5985 0.6044 0.6239
0.6281 0.6392 0.6489 0.6403 0.6164 0.6147 0.5071 0.5800
0.0280 0.0240 0.0260 0.0220 0.0220 0.0200 0.0190 0.0230
0.0306 0.0362 0.0498 0.0606 0.0566 0.0601 0.0680 0.0677
%插值预测中间周的水体评价指标
x=Z(1,:); %Z的第一行是星期Z: 1 3 5 7 9 11 13 15
[n,m]=size(Z);%n为Z的行数,m为Z的列数
% 注意Matlab的数组中不能保存字符串,如果要生成字符串数组,就需要使用元胞数组,其用大括号{}定义和引用
ylab={'周数','轮虫','溶氧','COD','水温','PH值','盐度','透明度','总碱度','氯离子','透明度','生物量'}; % 等会要画的图形的标签
disp(['共有' num2str(n-1) '个指标要进行插值。'])
disp('正在对一号池三次埃尔米特插值,请等待')%一号池共有十一组要插值的数据,算上星期所在的第一行,共十二行
P=zeros(11,15);%对要储存数据的矩阵P赋予初值
for i=2:n %从第二行开始都是要进行插值的指标
y=Z(i,:); %将每一行依次赋值给y
new_x=1:15; %要进行插值的x
p1=pchip(x,y,new_x); %调用三次埃尔米特插值函数
p2=spline(x,y,new_x);%三次样条插值
subplot(4,3,i-1); %将所有图依次变现在4*3的一幅大图上
plot(x,y,'ro',new_x,p1,'-',new_x,p2,'--',x,y,'-.');%画出每次循环处理后的图像
axis([0 15,-inf,inf]) %设置坐标轴的范围,这里设置横坐标轴0-15,纵坐标不变化
% xlabel('星期') %x轴标题
ylabel(ylab{i}) %y轴标题 这里是直接引用元胞数组中的字符串哦
P(i-1,:)=p1; %将每次插值之后的结果保存在P矩阵中
end
legend('原始数据','三次埃尔米特插值数据','三次样条插值','未插值','Location','SouthEast')
P = [1:15; P] %把P的第一行加上周数
可以对比一下插值后和没插值的图
1.17 插值结果对比
可以看出,三次样条生成的曲线更加光滑。在实际建模中,由于我们不知道数据的生成过程,因此这两种插值都可以使用