数学建模之插值法及代码

发布时间 2023-11-21 15:59:43作者: Cr不是铬

发现更多知识,欢迎访问Cr不是铬的个人网站

引言

数模比赛中,常常需要根据已知的函数点进行数据、模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,“模拟产生”一些新的但又比较靠谱的值来满
足需求,这就是插值的作用。

插值法的定义

file


插值法的原理

file

file

拉格朗日插值法

说在前面,在数学建模比赛中,拉格朗日插值不好,有龙格现象。

不多做解释

file

分段插值

分段插值有分段线性插值,分段二次插值

分段插值在建模比赛中是比较常用到的。可以与后面的埃尔米特插值结合起来!

牛顿插值法

牛顿插值也有龙格现象!在数学建模还是用分段插值比较好

file

更苛刻的插值

Hermite插值

file

分段三次埃尔米特插值

分段三次埃尔米特插值很常用!

file

三次样条插值

file

关于这个具体详见代码部分,原理不作解释。

n维数据插值

file

代码部分

分段三次埃尔米插值法

%% 分段三次埃尔米插值法
x = -pi : pi;
y = sin(x);
%按间隔0.1来进行插值
new_x = -pi : 0.1 : pi;
%分段三次埃尔米插值
p = pchip(x,y,new_x);

绘图plot

%% 绘图plot
%plot的用法
%plot(x1,y1,x2,y2)
%线方式 -实线 :点线 -.虚点线 --虚线
%点方式 .圆点 +加号 *星号  x x型 o小圆
%颜色 y黄色 r红色 g绿色 b蓝色
%原始样本点
figure(1)
plot(x,y,'go')
%插值点
figure(2)
plot(new_x,p,'r-')

file

三次样条插值与分段三次埃尔米插值

%% 三次样条插值与分段三次埃尔米插值
x = -pi:pi;
y = sin(x);
new_x =-pi:0.1:pi;
p1 = pchip(x,y,new_x);
%三次样条插值
p2 = spline(x,y,new_x);

%两种插值的对比
figure(3)
plot(x,y,'o',new_x,p1,'r-',new_x,p2,'b-')
legend('样本点','分段三次插值','三次样条插值','Location','southeast')
% 说明:
% LEGEND(string1,string2,string3, …)
% 分别将字符串1、字符串2、字符串3……标注到图中,每个字符串对应的图标为画图时的图标。
% ‘Location’用来指定标注显示的位置

file


关于人口预测的补充

插值法也可以用来预测,但是实际建模用得很少。

%%  人口预测(插值在实际建模中不用来预测)
population=[133126,133770,134413,135069,135738,136427,137122,137866,138639, 139538];
year = 2009:2018;
p1 = pchip(year,population,2019:2022);
p2 = spline(year,population,2019:2022);
plot(year,population,'ro',2019:2022,p1,'gx-',2019:2022,p2,'bx-')
legend('原始数据','分段三次埃尔米预测','三次样条预测',Location='southeast')

file

## 作业部分

file

对上述部分进行插值。

由于有很多种类别要进行插值,可以在循环中进行处理。

代码:

%% 读取数据
load Z.mat
%第一行的原始周期
x = Z(1,:);
%获取行与列
[n,m] = size(Z);
% 注意Matlab的数组中不能保存字符串,如果要生成字符串数组,就需要使用元胞数组,其用大括号{}定义和引用
ylab={'周数','轮虫','溶氧','COD','水温','PH值','盐度','透明度','总碱度','氯离子','透明度','生物量'};  % 等会要画的图形的标签
disp(['共有' num2str(n-1) '个指标要进行插值。'])
disp('正在对一号池三次埃尔米特插值,请等待')%一号池共有十一组要插值的数据,算上星期所在的第一行,共十二行
%初始化
P = zeros(11,15);
%% 循环插值
    for i = 2 : n%第二行之后都是要插值的
    %原始样本点
    y = Z(i,:);
    %要进行插值的x
    new_x = 1:15;
    p1 = spline(x,y,new_x);
    subplot(4,3,i-1);%将所有图依次变现在4*3的一幅大图上
    plot(x,y,'o',new_x,p1,'r-');
    axis([0 15,-inf,inf])  %设置坐标轴的范围,这里设置横坐标轴0-15,纵坐标不变化
    xlabel('星期')%x轴标题
    ylabel(ylab{i})%y轴标题  这里是直接引用元胞数组中的字符串
    %保存结果
    P(i-1,:) = p1;
    end
legend('原始数据','三次样条插值结果','Location','southeast')
%加上第一行
P = [1:15;P];

本文由博客一文多发平台 OpenWrite 发布!