数值实验报告.docx
《数值实验报告.docx》由会员分享,可在线阅读,更多相关《数值实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
数值实验报告
北京XX大学计算机与通信工程学院
实验报告
实验名称:
《数值计算方法》课程实验
学生姓名:
_____________XX_______________
专业:
________计算机科学与技术________
班级:
_____________XXXX____________
学号:
_____________XXXXXX___________
指导教师:
_____________XXXXX_____________
实验成绩:
________________________________
实验地点:
__________XXXXXXX____________
实验时间:
____2017____年___6___月___6___日
一、实验目的与实验要求
1、实验目的
实验1:
探究非线性方程的解法,比较不同解法的优劣性,针对具体问题对解法进行实践,并迭代达到指定的精确度。
实验2:
探究一般化曲线拟合的方法,采用最小二乘法对含有多项式,指数和对数多种形式的函数进行拟合,确定拟合结果中的系数。
实验3:
探究多种积分的数值解法,根据给定的精度,选择恰当的数值积分方法,确定迭代步数与步长,分析积分数值解法的优劣性。
2、实验要求
实验1:
采用两种算法求解非线性方程,比较两种算法的性能。
实验2:
用最小二乘法拟合由不超过三阶多项式和指数、对数函数线性组合成的符合函数,确定各个项的系数
实验3:
自选一种数值积分方法求解积分值,根据要求的精度给出最终的迭代步数和步长,分析优缺点。
二、实验设备(环境)及要求
实验1,3采用C语言编写,编译环境为DEVC++。
实验2涉及矩阵操作,故采用MATLAB编写。
三、实验内容与步骤
1、实验1
(1)实验内容
·采用至少两种不同的算法求解ex+3*x3-x2-2=0在[0,1]范围内的一个根,要求两次迭代误差小于10-4。
·根据实验结果,比较分析不同算法的性能。
(2)主要步骤
本实验由C语言实现。
在两种不同的算法上选用简单迭代法和牛顿迭代法。
简单迭代法是将方程化成一个与原方程同解的方程,方程一端化成自变量x,然后判断迭代函数是否收敛,如果收敛的话,不停地迭代将使x趋于一个定值,这个定值就是原方程的近似解。
而牛顿迭代法是直接给出形如
的迭代函数进行迭代,如果满足两个端点异号,f’(x)在[a,b]上不等于零,f’’(x)在[a,b]上不变号且初值
满足条件f(
)f’’(
)≥0,则由牛顿迭代法产生的序列单调收敛于[a,b]内的唯一根。
两种算法在理论上,牛顿迭代法的收敛速度要大于简单迭代法,以下进行迭代解非线性方程组并验证收敛速度的差异。
1.简单迭代法:
将
移项,整理,得到迭代函数如下:
,选取收敛的初值点
=0。
在实现上利用for循环进行迭代,直到相邻两次的误差小于
。
C语言代码如下:
简单迭代函数:
floatSimpleIteration(floatx)//简单迭代
{
returnpow((x*x+2-exp(x))/3.0,1.0/3);//pow(doublex,doubley);函数为求x的y次方
}
主函数中简单迭代法部分:
a[0]=SimpleIteration(0);//简单迭代法
printf("简单迭代法:
\n");
printf("迭代值\t\t相邻两次误差\n");
printf("%f\n",a[0]);
for(i=1;;i++)
{
a[i]=SimpleIteration(a[i-1]);
d1=fabs(a[i]-a[i-1]);
printf("%f\t%f\n",a[i],d1);
if(d1<1e-4)break;
}
2.牛顿迭代法:
根据牛顿迭代法迭代函数的一般形式可以得到具体的迭代函数如下:
,选取与简单迭代法相同的初值
=0。
C语言代码如下:
牛顿迭代函数:
floatNewtonIteration(floatx)//牛顿迭代
{
returnx-(exp(x)+3*x*x*x-x*x-2)/(exp(x)+9*x*x-2*x);
}
主函数中牛顿迭代法的部分:
b[0]=NewtonIteration(0);//牛顿迭代法
printf("\n牛顿迭代法:
\n");
printf("迭代值\t\t相邻两次误差\n");
printf("%f\n",b[0]);
for(j=1;;j++)
{
b[j]=NewtonIteration(b[j-1]);
d2=fabs(b[j]-b[j-1]);
printf("%f\t%f\n",b[j],d2);
if(d2<1e-4)break;
}
两个迭代法完整C语言代码如下:
#include
#include
#include
#defineMAXSIZE30
floatSimpleIteration(floatx)//简单迭代
{
returnpow((x*x+2-exp(x))/3.0,1.0/3);//pow(doublex,doubley);函数为求x的y次方
}
floatNewtonIteration(floatx)//牛顿迭代
{
returnx-(exp(x)+3*x*x*x-x*x-2)/(exp(x)+9*x*x-2*x);
}
voidmain()
{
floata[MAXSIZE];
floatb[MAXSIZE];
floatd1=1;
floatd2=1;
inti,j;
a[0]=SimpleIteration(0);//简单迭代法
printf("简单迭代法:
\n");
printf("迭代值\t\t相邻两次误差\n");
printf("%f\n",a[0]);
for(i=1;;i++)
{
a[i]=SimpleIteration(a[i-1]);
d1=fabs(a[i]-a[i-1]);
printf("%f\t%f\n",a[i],d1);
if(d1<1e-4)break;
}
b[0]=NewtonIteration(0);//牛顿迭代法
printf("\n牛顿迭代法:
\n");
printf("迭代值\t\t相邻两次误差\n");
printf("%f\n",b[0]);
for(j=1;;j++)
{
b[j]=NewtonIteration(b[j-1]);
d2=fabs(b[j]-b[j-1]);
printf("%f\t%f\n",b[j],d2);
if(d2<1e-4)break;
}
}
执行程序,结果如下:
可见,牛顿迭代法的收敛速度大于简单迭代法,具体详见实验结果与分析。
2、实验2
(1)实验内容
·已知如下数据:
x:
1.00001.40001.80002.20002.60003.00003.40003.80004.20004.60005.0000
y:
2.71836.644815.366730.186752.654284.5925128.1972186.2022262.1349360.7020488.3660
·数据可能来自于不超过3阶多项式和指数、对数函数线性组合形成的复合函数([1,x,x2,x3,ex,ln(x)]),请采用最小二乘算法确定复合函数中各个函数项的系数。
(2)主要步骤
最小二乘法是在确定函数形式的情况下,找出一条最靠近所有数据点的直线,其判定规则是
达到最小。
在求解的过程中,用最小二乘法拟合复合函数的过程实际上就是求法方程组的过程。
分别写出各项的内积
和
然后求解方程组
=
根据题目中给出的数据点和复合函数形式,可以定义出如下的6种基函数,具体的MATLAB代码如下:
functiony=f(x,n)
ifn==1y=1;
end
ifn==2y=x;
end
ifn==3y=x.^2;
end
ifn==4y=x.^3;
end
ifn==5y=exp(x);
end
ifn==6y=log(x);
end
end
然后在M命令文件中调用上述函数,并输入相应的n。
整个法方程组的系数矩阵可以用一个三重for循环实现,等号右侧的矩阵用另一个二重循环实现,实现系数矩阵的MATLAB代码如下:
fork=1:
6%ؖ控制行
fori=1:
6%ؖ控制列
forj=1:
11%ؖ控制所有元素求和
D(k,i)=f(X(j),k).*f(X(j),i)+D(k,i);
end
end
end
等式右边的矩阵的MATLAB代码如下:
forl=1:
6%ؖ控制行
form=1:
11%ؖ控制所有元素求和
F(l)=f(X(m),l).*Y(m)+F(l);
end
end
完整的MATLAB代码如下:
functiona=LS()
clc
clear
formatshort
X=[11.41.82.22.633.43.84.24.65];%11个元素
Y=[2.71836.644815.366730.186752.654284.5925128.1972186.2022262.1349360.7020488.3660];
D=zeros(6);
F=zeros(1,6)';
a=[];
fork=1:
6
fori=1:
6
forj=1:
11
D(k,i)=f(X(j),k).*f(X(j),i)+D(k,i);
end
end
end
forl=1:
6
form=1:
11
F(l)=f(X(m),l).*Y(m)+F(l);
end
end
a=D\F%ؖ求解
end
得出的结果如下:
a=
-2.0006
0.0006
-1.0000
3.0000
1.0000
-5.0008
所以,拟合出的复合函数应为
3、实验3
(1)实验内容
·选择一种数值积分方法求解下列函数在区间[0,2]内的积分值,要求精度小于10-5:
f(x)=(3x-x2+x3+ex)0.5
·给出迭代步数和最终的步长,并分析你所采用方法的优缺点。
(2)主要步骤
在积分难求出解析解时通常用数值解的方法求积分结果的近似值,在本题的实现方法上选用复合Simpson公式进行数值积分的计算,并从步数n=2,步长h=
开始逐步细化步长,增大步数,直到精度满足题目中的要求
。
首先在定义一个题目中给出的待积分的函数,C语言代码如下:
doublefunction(doublex)
{
doubles;
s=sqrt(3*x-x*x+x*x*x+exp(x));
returns;
}
然后编写复合Simpson公式,将其定义在一个独立的函数中,C代码如下:
doubleReiterationOfSimpson(doublea,doubleb,doublen,doublef(doublex))
{
doubleh,fa,fb,xk,xj;
h=(b-a)/n;
fa=f(a);
fb=f(b);
doubles1=0.0;
doubles2=0.0;
intk,j;
for(k=1;k{
xk=a+k*h;
s1=s1+f(xk);
}
for(j=0;j{
xj=a+(j+0.5)*h;
s2=s2+f(xj);
}
doublesn;
sn=h/6*(fa+fb+2*s1+4*s2);
returnsn;
}
最后在主函数中定义初始步数n为2,初始步长h为0.5,并通过for循环逐步增大n,直到相邻两次误差小于
,具体的C代码如下:
voidmain()
{
doublen=2;
doubleh=1/n;
inti;
doubleS[MAXN];
printf("====================复合Simpson公式法=====================\n\n");
printf("迭代步数\t步长\t\t积分数值\t误差\n");
S[0]=ReiterationOfSimpson(0,2,n,function);
printf("%d\t\t%f\t%f\n",(int)n,h,S[0]);
n++;
h=1/n;
S[1]=ReiterationOfSimpson(0,2,n,function);
printf("%d\t\t%f\t%f\t%f\n",(int)n,h,S[1],S[1]-S[0]);
for(i=2;S[i-1]-S[i-2]>=1e-5;i++)
{
n=i+2;
h=1/n;
S[i]=ReiterationOfSimpson(0,2,n,function);
printf("%d\t\t%f\t%f\t%f\n",(int)n,h,S[i],S[i]-S[i-1]);
}
}
程序执行的结果如下:
可见,在迭代步数n为10时,即步长为0.1时,精度达到要求,且此时的积分数值约为4.941104。
优劣性分析见实验结果与分析。
四:
实验结果与分析
实验1:
通过采用简单迭代法和牛顿迭代法处理同一问题,观察达到指定精度时所需的不同迭代次数,简单迭代法经过7步之后误差小于
,牛顿迭代法经过6步之后误差小于
,所以在收敛速度上来讲,牛顿迭代法的性能优于简单迭代法。
实验2:
通过采用最小二乘法拟合一个由不超过3阶多项式和指数、对数函数线性组合形成的复合函数,通过解法方程组求解,在求解过程中熟悉了最小二乘法的求解方法和基本概念,包括最小二乘法和插值的区别所在。
在计算机中可以通过循环较容易地求得各个基函数的内积,从而构建求解法方程组。
实验3:
通过用数值积分方法求解一个函数在一个积分区间的积分值,并根据具体的精度要求给出迭代步数和最终步长。
在方法上我选用了复合Simpson公式法,复合Simpson公式在Simpson公式的基础上提高了求积的精度,将[a,b]等分成n个子区间,在每个子区间上使用低阶求积公式计算,然后把所有子区间上的计算结果求和。
复合Simpson公式的优点在于通过增加子区间的个数可以缩小误差提高精度,这一点比单纯的Simpson公式,梯形公式和Cotes公式要好。
但是缺点在于复合Simpson公式是4阶收敛的,在收敛速度上没有复合Cotes公式收敛的快,所以需要n=10时才能达到精度要求。
五:
结论(讨论)
1、实验结论
在本次数值计算实验课中一共完成了三个实验,分别对应理论课程中三章的内容,分别复习并实践了非线性方程的迭代解法,插值与拟合,积分的数值解法等内容。
这三个实验涉及到了数值计算方法的主要内容,熟悉了数值计算方法的理论知识,并加以应用,在有一定创新度并结合各种具体编程环境的基础上,在实践中体会到了数值计算方法在实际问题中的作用。
在具体实现上,分别用C语言实现了1,3两个实验,用MATLAB实现了第2个实验,锻炼了把数值计算方法结合到不同应用场景的能力,为今后在各领域的使用打下基础。
在具体的实验上,在第一个实验中,应用了简单迭代法和牛顿迭代法解常见的非线性方程,熟悉了各种非线性方程的解法,包括二分法,简单迭代法,牛顿迭代法弦截法和牛顿下山法等。
其中应用简单迭代法和牛顿迭代法求解了题目中的问题,理解了两者的区别,牛顿迭代法直接通过迭代函数的一般形式给出具体的迭代函数,且收敛速度比简单迭代法要快。
在第二个实验中,应用了最小二乘法拟合一个由不超过3阶多项式和指数、对数函数线性组合形成的复合函数,熟悉了最小二乘法的概念及求解方法,通过构造法方程组来求解最小二乘法拟合的问题,并在一定程度上了解了最小二乘法拟合后平方误差的计算方法。
在第三个实验中,应用了数值积分方法中的复合Simpson公式法解一个函数在固定区间中的积分值。
由于复杂的函数在一定情况下难以找到解析解,所以要通过数值积分的方法求数值解。
在求数值解的方法上主要有梯形公式,Simpson公式,Cotes公式,复合梯形公式,复合Simpson公式,复合Cotes公式等,其中复合的公式通过在区间内等分子区间提高数值积分的精度,子区间个数越多,精度越高,直到达到目标的精度为止。
在实验中主要应用了复合Simpson公式求解积分,熟悉并理解了相关的理论知识并加以实践,在一定程度上掌握了相关的方法。
2、讨论
在本次数值计算实验课程中,完成了课程中要求的实验,进一步掌握了实验中涉及的知识点,包括非线性方程的解法,最小二乘法拟合,数值积分法等等,但是对于实验题目中未涉及到的内容仍有些掌握不牢,比如说线性方程组的解法,插值,常微分方程的数值解法等等,所以我认为实验课中涉及的知识点可以覆盖到各章最好,这将在熟悉知识点上提供很大的帮助。
六、教师评审
教师评语
实验成绩
签名:
日期: