《计算方法》实验报告.docx
《《计算方法》实验报告.docx》由会员分享,可在线阅读,更多相关《《计算方法》实验报告.docx(9页珍藏版)》请在冰豆网上搜索。
计算机科学与工程学院
《计算方法》实验报告
学号
姓名
班级
实验项目名称
计算方法实验
一、实验名称
实验一插值与拟合
二、实验目的:
(1)明确插值多项式和分段插值多项式各自的优缺点;
(2)编程实现拉格朗日插值算法,分析实验结果体会高次插值产生的龙格现象;
(3)运用牛顿插值方法解决数学问题。
三、实验内容及要求
(1)对于
要求选取11个等距插值节点,分别采用拉格朗日插值和分段线性插值,计算x为0.5,4.5处的函数值并将结果与精确值进行比较。
输入:
区间长度,n(即n+1个节点),预测点
输出:
预测点的近似函数值,精确值,及误差
(2)已知用牛顿插值公式求的近似值。
输入:
数据点集,预测点。
输出:
预测点的近似函数值
四、实验原理及算法描述
算法基本原理:
(1)拉格朗日插值法
(2)牛顿插值法
算法流程
五、程序代码及实验结果
(1)输出:
A.拉格朗日插值法
B.分段线性插值
X y(精确) y(拉格朗日)y(分段线性)误差(拉)误差(分)
0.500000 0.800000 0.843407 0.750000 -0.054259 0.050000
4.500000 0.047059 1.5787200.0486425-32.547674 -0.033649
(2)输出:
X y(精确) y(牛顿插值)误差(牛顿插值)
5.00000 2.236068 2.266670 -0.013686
源码:
(1)A.拉格朗日插值法
#include
#include
#include
usingnamespacestd;
doubleLagrange(intN,vector&X,vector&Y,doublex);
intmain(){
doublep,b,c;
chara='n';
do{
cout<<"请输入差值次数n的值:
"<intN;
cin>>N;
vectorX(N,0);
vectorY(N,0);
cout<<"请输入区间长度(a,b):
"< cin>>p;
cin>>b;
c=b-p;
c=c/(N-1);
for(inti=0;i X[i]=p;
Y[i]=1/(1+p*p);
p=p+c;
}
cout<<"请输入要求值x的值:
"<doublex;
cin>>x;
doubleresult=Lagrange(N,X,Y,x);
cout<<"由拉格朗日插值法得出结果:
"<cout<<"是否要继续?
(y/n):
";
cin>>a;
}while(a=='y');
return0;
}
doubleLagrange(intN,vector&X,vector&Y,doublex){
doubleresult=0;
for(inti=0;idoubletemp=Y[i];
for(intj=0;jif(i!
=j){
temp=temp*(x-X[j]);
temp=temp/(X[i]-X[j]);
}
}
result+=temp;
}
returnresult;
};
B:
分段线性插值
#include
#include
#include
usingnamespacestd;
doublefenduan(intN,vector&X,vector&Y,doublex,doublec);
intmain(){
doublep,b,c;
chara='n';
do{
cout<<"请输入差值次数n的值:
"<intN;
cin>>N;
vectorX(N,0);
vectorY(N,0);
cout<<"请输入区间长度(a,b):
"< cin>>p;
cin>>b;
c=b-p;
c=c/(N-1);
for(inti=0;i X[i]=p;
Y[i]=1/(1+p*p);
p=p+c;
}
cout<<"请输入要求值x的值:
"<doublex;
cin>>x;
doubleresult=fenduan(N,X,Y,x,c);
cout<<"由分段线性插值法得出结果:
"<cout<<"是否要继续?
(y/n):
";
cin>>a;
}while(a=='y');
return0;
}
doublefenduan(intN,vector&X,vector&Y,doublex,doublec){
doubleresult=0;
intb;
b=0;
while(x-X[b]>c)
{
b=b+1;
}
result=Y[b]*(1-(x-X[b])/c)+Y[b+1]*((x-X[b])/c);
returnresult;
};
(3)牛顿插值法
#include
#include
#include
usingnamespacestd;
doubleChaShang(intn,vector&X,vector&Y);
doubleNewton(doublex,vector&X,vector&Y);
intmain(){
chara='n';
do{
intn;
cout<<"请输入插值点个数:
"<cin>>n;
vectorX(n,0);
vectorY(n,0);
cout<<"请输入插值点对应的值及函数值(Xi,Yi):
"<for(inti=0;icin>>X[i]>>Y[i];
}
cout<<"请输入要求值x的值:
"<doublex;
cin>>x;
cout<<"由牛顿插值法得出结果:
"<cout<<"是否要继续?
(y/n):
";
cin>>a;
}while(a=='y');
return0;
}
doubleChaShang(intn,vector&X,vector&Y){
doublef=0;
doubletemp=0;
for(inti=0;itemp=Y[i];
for(intj=0;jif(i!
=j)temp/=(X[i]-X[j]);
f+=temp;
}
returnf;
}
doubleNewton(doublex,vector&X,vector&Y){
doubleresult=0;
for(inti=0;idoubletemp=1;
doublef=ChaShang(i,X,Y);
for(intj=0;j
temp=temp*(x-X[j]);
}
result+=f*temp;
}
returnresult;
}
六、实验总结
1.通过实验一数据发现,拉格朗日插值在低次插值时,同源函数偏差并不大,但在高次插值时同原函数偏差大、存在明显的龙格现象,而分段线性插值可以避免出现的龙格现象,与原函数比较吻合,但是分段线性插值由于其分段属性,使得插值函数失去光滑性,可以考虑采用Hermite插值优化。
2.通过实验二计算过程发现,拉格朗日插值法的线性插值的计算过程没有继承性,即增加一个节点时整个计算工作必须重新开始。
而牛顿插值则避免了这一问题,这样大量的节省了乘、除法运算次数,减少了计算的时间。
因此,对于一些结构相当复杂的函数,牛顿插值法比拉格朗日插值法要占优势。
五、教师评语(或成绩)
教师签字:
9