数学建模值插值算法

插 值

  • 基本原理

已知在互不相同的多个点 处,函数) 分别取到函数值 构造一个最高次数不超过 的多项式 ,使其满足 然后用 来作为 的近似值,这种方法为插值法。如果要求近似函数(曲线或曲面)经过所已知的所有数据点,这类问题就是插值。

  • 插值与拟合的关系

    1. 联系

都是根据实际中一组已知数据来构造一个能够反映数据变化规律的近似函数的方法。

    1. 区别

1、插值:是在离散数据的基础上补插连续函数,使得插值函数通过全部给定的离散样本点。插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。总之,插值是求过一组已知点的近似函数。

拟合:是用一个连续函数(曲线)靠近给定的离散数据,使其与给定的数据相吻合。拟合也是根据一组已知点求近似函数,但不要求过已知点。

因此,插值和拟合都是根据一组已知样本点,求变化规律和特征相似的近似曲线的过程。但是插值要求近似曲线完全经过所有的给定数据点,而拟合只要求近似曲线在整体上尽可能接近数据点,并反映数据的变化规律和发展趋势。

2、插值也可以看作是一种特殊的拟合,是要求误差函数为0的拟合。由于数据点通常都带有误差,误差为0往往意味着过度拟合,过拟合模型对于训练集以外的数据的泛化能力往往是较差的。因此在实践中,插值多用于图像处理和缺失数据处理,拟合多用于实验数据处理。

3、当实验数据精度较高且数量较少是可以优先考虑插值, 而实验数据精度较低且数目较多,而数据整体上呈现一定的趋势时可以考虑拟合。

  • 插值MATLAB实现

    1. 一维插值

1 已知飞机下轮廓线上数据如下:

x

0

3

5

7

9

11

12

13

14

15

y

0

1.2

1.7

2.0

2.1

2.0

1.8

1.2

1.0

1.6

matlab代码:

x0=[0 3 5 7 9 11 12 13 14 15];
y0=[0 1.2 1.7 2.0 2.1 2.0 1.8 1.2 1.0 1.6];
x_2=0:0.1:15;
y_f1=Lagrange(x0,y0,x_2);
y_f2=interp1(x0,y0,x_2);
y_f3=interp1(x0,y0,x_2,'spline');
subplot(3,1,1);
plot(x0,y0,'*',x_2,y_f1,'-');
grid;
title('拉格朗日插值');
subplot(3,1,2);
plot(x0,y0,'r^',x_2,y_f2,'-b');
grid;
title('线性插值');
subplot(3,1,3);
plot(x0,y0,'ro',x_2,y_f3,'-b');
grid; 
title('三次样条插值');

总结:由图可知,拉格朗日插值出现外沿振荡现象,三次样条插值所得的曲线逼近函数值,线条也具有光滑性。所以采用三次样条插值效果更好。

    1. 二维插值(节点均匀)

2:一组数据如下所示:

1

2

3

4

5

1

34

40

41

41

39

2

36

41

45

47

46

3

33

39

43

50

47

4

32

40

44

45

46

5

28

35

40

41

42

Matlab代码部分:

x = 1:1:5;
y = 1:1:5;
z = [34 40 41 41 39
36 41 45 47 46
33 39 43 50 47
32 40 44 45 46
28 35 40 41 42];
x0 = 1:0.1:5;
y0 = 1:0.1:5;
mesh(x,y,z);
title('插值前二维图')
z0 = interp2(x,y,z,x0,y0','spline'); % 注意y_1'是转置(列向量)
mesh(x0,y0,z0);
title('三次样条插值');

    1. 二维插值(节点不均匀)

例三:一组数据如下所示:

x

13

14

10

8

18

19

10

16

10

7

8

16

16

12

y

0.7

14

2

15

2

13

9

-1

-8

0.3

6

-7

8

-3

z

4

8

6

8

9

8

8

9

9

8

8

9

4

9

Matlab代码部分:

1.	x = [13 14 10 8 18 19 10 16 10 7 8 16 16 12];  
2.	y = [0.7 14 2 15 2 13 9 -1 -8 0.3 6 -7 8 -3];  
3.	z = [4 8 6 8 6 8 8 9 9 8 8 9 4 9];  
4.	%mesh(x,y,z)  
5.	[x0,y0]  =meshgrid(5:0.1:20,-5:0.1:20)  
6.	z1 = griddata(x,y,z,x0,y0,'cubic');  
7.	mesh(x0,y0,z1)  
8.	title('三次插值图')  
9.	z2 = griddata(x,y,z,x0,y0,'linear');  
10.	mesh(x0,y0,z2)  
11.	title('线性插值图')

  • 插值法的特点

    1. 用途:

1、在数模比赛中,需要用已知数据进行分析时,可能会出现已知数据缺失或不足的情况,此时可利用该方法产生一些靠谱的数据点。

2、数据量太小,需要增加数据量来提升算法的执行效果。可以用插值法得到更多的样本值。

3、需要对某个区域的值进行预测。通过插值算法将插值点的值计算出来。

4、图形化计算结果

  • 插值Python实现

    1. 一维插值

例1:飞机下轮廓线上数据Anaconda(Jupyter)

1.	#导入第三方库  
2.	import numpy as np  
3.	import matplotlib.pyplot as plt  
4.	from scipy.interpolate import interp1d   
5.	from scipy.interpolate import lagrange  
6.	from six.moves import xrange  
7.	  
8.	x = [0,3,5,7,9,11,12,13,14,15]  
9.	y = [0,1.2,1.7,2.0,2.1,2.0,1.8,1.2,1.0,1.6]  
10.	f_x0 = interp1d(x,y,kind='cubic') #三次样条插值 注:f(x)是函数  
11.	f_x1 = lagrange(x,y) #拉格朗日插值  
12.	f_x2 = interp1d(x,y,kind='linear') #线性插值  
13.	  
14.	x_int = np.linspace(0,15,1000) #插值的数据点集x_int  
15.	y_int = f_x0(x_int) #调用函数f(x),计算x_int的函数值  
16.	y_intL = f_x1(x_int)  
17.	y_intlin = f_x2(x_int)  
18.	  
19.	 #绘图  
20.	plt.scatter(x,y,c='b',marker='o',label= 'scatter')  
21.	plt.plot(x_int,y_int,c = 'r',label = 'cubic')  
22.	plt.plot(x_int,y_intlin,c = 'g',label = 'linear')  
23.	plt.legend(loc = 'lower right')  
24.	plt.show()  
25.	  
26.	plt.plot(x_int,y_intL,c = 'g',label = 'Largrange')  
27.	plt.legend(loc = 'lower right')  
28.	plt.show()  

    1. 二维插值

 例2:节点均匀Anaconda(Jupyter)

1.	import numpy as np  
2.	import matplotlib.pyplot as plt  
3.	from scipy.interpolate import interp2d  
4.	import matplotlib as mpl  
5.	  
6.	x = np.linspace(1,5,5)  
7.	y = np.linspace(1,5,5)  
8.	xx,yy = np.meshgrid(x,y) # 生成网格点的坐标 xx,yy (二维数组)  
9.	z = [[34,40,41,41,39],  
10.	     [36,41,45,47,46],  
11.	     [33,39,43,50,47],  
12.	     [32,40,44,45,46],  
13.	     [28,35,40,41,42]]  
14.	  
15.	f_1 = interp2d(xx,yy,z,kind='cubic') # 三阶样条插值  
16.	xnew = np.linspace(1,5,100)  
17.	xnew_1 = np.linspace(1,5,5)  
18.	ynew = np.linspace(1,5,100)  
19.	ynew_1 = np.linspace(1,5,5)  
20.	znew =f_1(xnew,ynew)  # 计算插值函数在f_1(xnew, ynew)所描述网格点集的函数值  
21.	znew_1 =f_1(xnew_1,ynew_1)  
22.	  
23.	#绘图  
24.	fig = plt.figure(figsize = (12,8))  
25.	ax1 = plt.subplot(1,2,1,projection='3d')  
26.	ax1.set_title("2-D original data")  
27.	ax1.plot_wireframe(xx,yy,znew_1,rstride = 2,cstride = 2,linewidth = 1)  
28.	surf1 = ax1.plot_surface(xx,yy,znew_1,rstride = 2,cstride = 2,cmap='rainbow')  
29.	xxnew, yynew = np.meshgrid(xnew, ynew)  # 将一维数组 xnew, ynew 转换为网格点集(二维数组)  
30.	#print("\txxnew:{},yynew:{},znew:{}".format(xxnew.shape,yynew.shape,znew.shape))  
31.	ax2 = plt.subplot(1,2,2, projection='3d')  # 3D 绘图要求 x,y,z 都是 n*m 二维数组  
32.	ax2.set_title("2-D cubic data")  
33.	ax2.plot_wireframe(xxnew, yynew,znew,rstride = 2,cstride = 2,linewidth = 1)  
34.	surf2 = ax2.plot_surface(xxnew,yynew,znew,rstride =  2,cstride = 2,cmap='rainbow')  
35.	plt.show() 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王的傲骨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值