佛山科学技术学院
实 验 报 告
课程名称 数值分析
实验项目 插值法与数据拟合
专业班级 机械工程 姓 名 余红杰 学 号 10
指导教师 陈剑 成 绩 日 期 月 日
一、实验目的
1、学会Lagrange 插值、牛顿插值和三次样条插值等基本插值方法;
2、讨论插值的Runge现象
3、学会Matlab提供的插值函数的使用方法,会用这些函数解决实际问题。
二、实验原理
1、拉格朗日插值多项式
2、牛顿插值多项式
3、三次样条插值
三、实验步骤
1、用MATLAB编写独立的拉格朗日插值多项式函数
2、用MATLAB编写独立的牛顿插值多项式函数
3、用MATLAB编写独立的三次样条函数(边界条件为第一、二种情形)
4、已知函数在下列各点的值为:
根据步骤1,2,3编好的程序,试分别用4次拉格朗日多项式、牛顿插值多项式以及三次样条函数(自然边界条件)对数据进行插值,并用图给出
{},、和。
5、在区间[-1,1]上分别取用两组等距节点对龙格函数作多项式插值,对不同值,分别画出插值函数及的图形。
6、下列数据点的插值
0 | 1 | 4 | 9 | 16 | 25 | 36 | 49 | 64 | |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
可以得到平方根函数的近似,在区间[0,64]上作图。
(1)用这9个点作8次多项式插值。
(2)用三次样条(第一边界条件)程序求。
7、对于给函数在区间[-1,1]上取,试求3次曲线拟合,试画出拟合曲线并打印出方程,与第5题的结果比较。
四、实验过程与结果:
1、Lagrange 插值多项式源代码:
function ya=lag(x,y,xa)
%x 所有已知插值点
%y 插值点对应函数值
%xa 所求点,自变量
%ya 所求点插值估计量matlab拟合数据
ya=0;
mu=1;
%初始化
%循环方式求L系数,并求和:
for i = 1:length(y)
for j = 1:length(x)
if i ~= j
mu = mu * (xa - x(j) ) / ( x(i) - x(j) );
else
continue
end
end
ya = ya + y(i) * mu ;
mu = 1;
end
2、Newton源代码:
function ya = newton(x,y,xa)
%x 所有已知插值点
%y 插值点对应函数值
%xa 所求点,自变量
%ya 所求点插值估计量
%建立系数零矩阵D及初始化:
D = zeros(length(x)-1);
ya = y(1);
xi = 1;
%求出矩阵D,该矩阵第一行为牛顿插值多项式系数:
for i=1:(length(x)-1)
D(i,1) = (y(i+1) -y(i))/(x(i+1) -x(i));
end
for j=2:(length(x)-1)
for i=1:(length(x)-j)
D(i,j) = (D(i+1,j-1) - D(i,j-1)) / (x(i+j) - x(i));
end
end
%xi为单个多项式(x-x(1))(x-x(2))...的值
for i=1:(length(x)-1)
for j=1:i
xi = xi*(xa - x(j));
end
ya = ya + D(1,i)*xi;
xi = 1;
end
3、三次样条插值多项式
(1)(第一边界条件)源代码:
function y=yt1(x0,y0,f_0,f_n,x) _____________(1)
%第一类边界条件下三次样条插值;
%xi 所求点;
%yi 所求点函数值;
%x 已知插值点;
%y 已知插值点函数值;
%f_0左端点一次导数值;
%f_n右端点一次导数值;
n = length(x0);
z = length(y0);
h = zeros(n-1,1);
k=zeros(n-2,1);
l=zeros(n-2,1);
S=2*eye(n);
for i=1:n-1
h(i)= x0(i+1)-x0(i);
end
for i=1:n-2
k(i)= h(i+1)/(h(i+1)+h(i));
l(i)= 1-k(i);
end
%对于第一种边界条件:
k = [1;k]; _______________________(2)
l = [l;1]; _______________________(3)
%构建系数矩阵S:
for i = 1:n-1
S(i,i+1) = k(i);
S(i+1,i) = l(i);
end
%建立均差表:
F=zeros(n-1,2);
for i = 1:n-1
F(i,1) = (y0(i+1)-y0(i))/(x0(i+1)-x0(i));
end
D = zeros(n-2,1);
for i = 1:n-2
F(i,2) = (F(i+1,1)-F(i,1))/(x0(i+2)-x0(i));
D(i,1) = 6 * F(i,2);
end
%构建函数D:
d0 = 6*(F(1,2)-f_0)/h(1); ___________(4)
dn = 6*(f_n-F(n-1,2))/h(n-1); ___________(5)
D = [d0;D;dn]; ______________(6)
m= S\D;
%寻x所在位置,并求出对应插值:
for i = 1:length(x)
for j = 1:n-1
if (x(i)<=x0(j+1))&(x(i)>=x0(j))
y(i) =( m(j)*(x0(j+1)-x(i))^3)/(6*h(j))+...
(m(j+1)*(x(i)-x0(j))^3)/(6*h(j))+...
(y0(j)-(m(j)*h(j)^2)/6)*(x0(j+1)-x(i))/h(j)+...
(y0(j+1)-(m(j+1)*h(j)^2)/6)*(x(i)-x0(j))/h(j) ;
break;
else continue;
end
end
end
(2)(自然边界条件)源代码:
仅仅需要对上面部分标注的位置做如下修改:
__(1):function y=yt2(x0,y0,x)
__(2):k=[0;k]
__(3):l=[l;0]
__(4)+(5):删除
—(6):D=[0:D:0]
4、
——————————————
PS:另建了一个f方程文件,后面有一题也有用到。
function y=f(x0)
y = 1./(1+25.*x0.^2);
___________________________
clc;clear;
x1=[,,,,];
y1=[,,,,];
plot(x1,y1,'.');
hold on
xo=[::1];
y=lag(x1,y1,xo);
plot(xo,y,'o')
hold on;
y=newton(x1,y1,xo);
plot(xo,y,'r');
hold on;
y=yt2(x1,y1,xo);
plot(xo,y,'*')
h = legend('原始','拉格','牛顿','自样',4);
5、
clc,clear;
x1=linspace(-1,1,10);
x2=linspace(-1,1,20);
xo=[-1::1];
yo=f(xo);
plot(xo,yo);
hold on;
y=f(x1);
y=newton(x1,y,xo);
plot(xo,y,'k');
hold on;
y=f(x2);
y=newton(x2,y,xo);
plot(xo,y,'r')
h = legend('原始','10插','20插',3);
6、
clc,clear;
x1=[0 1 4 9 16 25 36 49 64];
y1=[0 1 2 3 4 5 6 7 8 ];
xo=[0:1:64];
y=lag(x1,y1,xo)
plot(xo,y,'k');
hold on
y=yt2(x1,y1,xo)
plot(xo,y,'r')
h = legend('拉格','自然样条',2);
7、
clc,clear;
x1=linspace(-1,1,11);
xo=[-1::1];
y=f(x1);
yo=f(xo);
plot(xo,yo,'r');
hold on
p=polyfit(x1,y,3);
y1=polyval(p,xo);
plot(xo,y1)
h = legend('原图','三次曲线拟合',2);
p
%该曲线的三次多项式系数依次显示
5、讨论分析及感想
个人感觉就是在数据点比较少,要求比较低的情况下,使用拉格朗日或是牛顿插值就足够了。但是当数据点比较多的时候,使用样条曲线就更好。当数据更多时,就可以使用曲线拟合方法来求近似值。
工程数学的基础知识并不是很苦难,但是很实用,是有必要好好学下的。Matlab也是比较强
大的工具,比较符合人的思维逻辑,上手很快。看书上的程序例子和实际编写还是有区别的,看得懂不一定编写的好,主要还是思维方式的锻炼吧~格式方法之类,只要了解了其基本功能,然后就是一系列的组合,多训练就熟悉了,比较有趣的课程吧,关键是有数据,有输出图像,看的清晰明白。而且出现的错误,都有清晰的指导,修改起来也很快捷。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论