数学建模学习笔记——插值与拟合


本文章为《数学建模算法与应用(司守奎)》书籍的学习笔记,文章内代码大部分为该书籍的搬运,主要目的为简化阅读的过程,以便直接实现代码的运用,我也会对书中的习题给出自己的解。

一、基础知识储备

1.插值

1.1.拉格朗日插值

function y=lagrange(x0,y0,x); %拉格朗日函数,新建一个.m文件。
%x0,y0为已知数据点的向量,x为待求点的向量
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

1.2.牛顿插值

牛顿插值与拉格朗日插值的区别是牛顿插值的高阶插值方程可以由低阶方程递推而来。

%已知数据点
X = [1 2 3 4 5 6];
Y = [-3,0,15,48,105,192];
n = length(X);
D = zeros(n,n);
D(:,1) = Y';
for j = 2:n
	for k = j:n
	D(k,j) = (D(k,j-1)-D(k-1,j-1))/(X(k)-X(k-j+1));
	end
end
%D为差商表,产生的D的对角线上的元素即为牛顿插值方程从前往后的每一项的系数
C = D(n,n)
for k = (n-1):-1:1
	C = conv(C,poly(X(k)));
	m = length(C);
	C(m) = C(m)+D(k,k);
end
%最终C的第i个元素为多项式中次数(n-i)的项的系数

1.3.分段线性插值

%常用,x0,y0为已知数据向量,y0可为矩阵,当为矩阵时,该函数对x0和y0的每一列进行拟合,
%返回和y0同样维数的矩阵,x为待求向量,method为可选函数方法,具体内容请查阅官方文档。
%该函数也可以对复数和日期与时间进行插值。
y = interp1(x0,y0,x,'method') 
pp = interp1(x,v,method,'pp')
%使用method算法返回分段多项式形式的v(x)。用y = ppval(pp,x)计算函数值。

1.4.Hermite插值

function y=hermite(x0,y0,y1,x); %Hermite插值函数,新建一个.m文件。
%设n个节点的数据以数组x0(已知点的横坐标),y0(函数值),y1(导数值)
%输入,m个插值点以数组x输入,输出数组y为m个插值。
n=length(x0);m=length(x); 
for k=1:m 
	yy=0.0; 
	for i=1:n 
		h=1.0; 
		a=0.0; 
		for j=1:n 
			if j~=i 
			h=h*((x(k)-x0(j))/(x0(i)-x0(j)))^2; 
			a=1/(x0(i)-x0(j))+a; 
		end 
	end 
	yy=yy+h*((x0(i)-x(k))*(2*a*y0(i)-y1(i))+y0(i)); 
	end 
	y(k)=yy; 
end

1.5.三次样条插值

%spline
y=interp1(x0,y0,x,'spline');
y=spline(x0,y0,x);
pp=csape(x0,y0,conds),y=ppval(pp,x)
%conds为边界条件,可以使用官方自带的参数,也可以自己定义边界条件,自己定义边界条件时,
%pp = csape(x0,y0_ext,conds),此时conds为1*2的元素为12的矩阵,1,2代表边界条件为
%几阶导数,yo_ext= [左边界值 y0 有边界值]

1.6.B样条函数插值

搞不懂啊,实现插值还可以用griddedInterpolant(网格点)或scatteredInterpolant(散点)函数实现,包括内部插值和外部插值。

1.7.二维插值

%插值节点为网格点——
z=interp2(x0,y0,z0,x,y,'method') 
%其中x0,y0分别为m维和n维向量,表示节点,z0为n×m维矩阵,用法同一维。
pp=csape({x0,y0},z0,conds,valconds),z=fnval(pp,{x,y}) 
%其中x0,y0分别为m维和n维向量,z0为m×n维矩阵,z为矩阵,用法同一维。
%插值节点为散乱点——
zi=griddata(x,y,z,xi,yi','cubic')

2.曲线拟合的线性最小二乘法

2.1.线性最小二乘法

基本思想为找到一个曲线,使该曲线上对应点与已知点的差的平方和最小,要进行较好的拟合,我们首先可以打印所有的数据点,观察数据点满足何种曲线,然后用该曲线去拟合数据点,常用曲线有直线,多项式,双曲线,指数曲线。

%用最小二乘法拟合x,y到曲线y=a+bX^2
x=[19 25 31 38 44]'; 
y=[19.0 32.3 49.0 73.3 97.8]'; 
r=[ones(5,1),x.^2]; 
ab=r\y%最小二乘法的解方程组法,直接左除。
x0=19:0.1:44; 
y0=ab(1)+ab(2)*x0.^2; 
plot(x,y,'o',x0,y0,'r')

2.2.多项式拟合方法

a=polyfit(x0,y0,m) 
%其中输入参数x0,y0为要拟合的数据m为拟合多项式的次数,输出参数a为拟合多项式
%y=amx^m++a1x+a0系数a=[am,,a1,a0]
%计算指定点函数值使用函数y=polyval(a,x)

3.最小二乘优化

目标函数由若干个函数的平方和组成。

3.1.最小二乘优化函数

%最小二乘优化的四个函数
%lsqlin、lsqcurvefit、lsqnonlin、lsqnonneg
%具体使用方法查阅官方文档

3.2.cftool工具箱用法

4.曲线拟合与函数逼近

前面讲的曲线拟合是已知一组离散数据{(xi , yi),i =1,L,n},选择一个较简单的函数f(x),如多项式,在一定准则如最小二乘准则下,最接近这些数据。如果已知一个较为复杂的连续函数 y(x), x ∈[a,b],要求选择一个较简单的函数f (x),在一定准则下最接近 f (x),就是所谓函数逼近。
最小函数逼近满足最小平方逼近,即简单函数与复杂函数的差的平方的积分最小。具体如何实现请查询书籍。

二、章节习题解答

Q1

%新建.m文件
function y = f3(x)
y = x.^3-6*x.^2+5*x-3;
end

x = linspace(0,10,100);
y = f3(x);
y2 = y+rand(1,100);
y3 = y+randn(1,100);
subplot(2,2,1);plot(x,y);
subplot(2,2,2);plot(x,y2);
subplot(2,2,3);plot(x,y3);
a22 = polyfit(x,y2,2);%a22即表示对y2作二次拟合的参数
a23 = polyfit(x,y2,3);
a24 = polyfit(x,y2,4);
a34 = polyfit(x,y3,4);
a33 = polyfit(x,y3,3);
a32 = polyfit(x,y3,2);

Q2

y0 = 0:400:4800;y0 = y0';x0 = 0:400:5600;
z0 = [1350 1370 1390 1400 1410 960 940 880 800 690 570 430 290 210 150 
1370 1390 1410 1430 1440 1140 1110 1050 950 820 690 540 380 300 210 
1380 1410 1430 1450 1470 1320 1280 1200 1080 940 780 620 460 370 350 
1420 1430 1450 1480 1500 1550 1510 1430 1300 1200 980 850 750 550 500 
1430 1450 1460 1500 1550 1600 1550 1600 1600 1600 1550 1500 1500 1550 1550 
950 1190 1370 1500 1200 1100 1550 1600 1550 1380 1070 900 1050 1150 1200 
910 1090 1270 1500 1200 1100 1350 1450 1200 1150 1010 880 1000 1050 1100 
880 1060 1230 1390 1500 1500 1400 900 1100 1060 950 870 900 936 950 
830 980 1180 1320 1450 1420 400 1300 700 900 850 810 380 780 750 
740 880 1080 1130 1250 1280 1230 1040 900 500 700 780 750 650 550 
650 760 880 970 1020 1050 1020 830 800 700 300 500 550 480 350 
510 620 730 800 850 870 850 780 720 650 500 200 300 350 320 
370 470 550 600 670 690 670 620 580 450 400 300 100 150 250];
y = 0:50:4800;y = y';x = 0:50:5600;
z=interp2(x0,y0,z0,x,y,'spline');
hold on
mesh(x,y,z);
[C,h] = contour(x,y,z,[500:500:2000]);
clabel(C,[500:500:2000]);
hold off

Q3

X = [1:8];
Y = [15.3,20.5,27.4,36.6,49.1,65.6,87.87,117.6];
n = length(X);
A = [ones(n,1),X'];
Y = log(Y); 
Y = Y';
a = A\Y;
ans = exp(a);%ans(1)即为第一个参数值,a(2)即为第二个参数值
x = linspace(1,8,100);
y = ans(1)*exp(a(2)*x);
Y = exp(Y);%复原Y
plot(x,y,'r',X,Y,'o');

Q4

%本题代码参考网络且解法比较粗糙
C = [0 3175 44636 3350 
3316 3110 49953 3260 
6635 3054 53936 3167 
10619 2994 57254 3087 
13937 2947 60574 3012 
17921 2892 64554 2927 
21240 2850 68535 2842 
25223 2795 71854 2767 
28543 2752 75021 2697 
32284 2697 85968 3475 
39435 3550 89953 3397 
43318 3445 93270 3340];
t = C(:,[1,3]);t = t(:);T = t/3600;%时间转化为小时
h = C(:,[2,4]);h = h(:);H = h/100*30.24*pi*57*30.24*57*30.24/4/1000/3.785;
%水位转化为G
n = length(T);
Tl = T(1:n-1);Tr = T(2:n);tmedi = (Tl+Tr)/2;%tmedi为相邻时间间隔的中间的时间点
Hl = H(1:n-1);Hr = H(2:n);Vw = (Hl-Hr)./(Tr-Tl);%Vw为tmedi时刻的所在时间段的平均流速
index = find(Vw<0);tmedi(index)=[];Vw(index)=[];%去除流速小于0的数据点
a = polyfit(tmedi,Vw,4);
va = polyval(a,1:0.1:30);
hold on
plot(tmedi,Vw,'*');
plot(1:0.1:30,va);
hold off;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值