合工大计算方法试验报告.docx
- 文档编号:11532327
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:13
- 大小:20.95KB
合工大计算方法试验报告.docx
《合工大计算方法试验报告.docx》由会员分享,可在线阅读,更多相关《合工大计算方法试验报告.docx(13页珍藏版)》请在冰点文库上搜索。
合工大计算方法试验报告
合工大计算方法试验报告
《计算方法》试验报告
班级:
学号:
姓名:
实验一、牛顿下山法1
实验目的
(1)熟悉非线性方程求根简单迭代法,牛顿迭代及牛顿下山法
(2)能编程实现简单迭代法,牛顿迭代及牛顿下山法(3)认识选择迭代格式的重要性(4)对迭代速度建立感性的认识;分析实验结果体会初值对迭代的影响2
实验内容
(1)用牛顿下山法解方程(初值为0.6)输入:
初值,误差限,迭代最大次数,下山最大次数输出:
近似根各步下山因子
(2)设方程f(x)=x-3x–1=0有三个实根x=1.8793,x=-0.34727,x=-1.53209现采用下面六种不同计算格式,求f(x)=0的根x或x
x=;x=;x=;x=;x=;x=x-
输入:
初值,误差限,迭代最大次数输出:
近似根、实际迭代次数3
算法基本原理求非线性方程组的解是科学计算常遇到的问题,有很多实际背景.各种算法层出不穷,其中迭代是主流算法。
只有建立有效的迭代格式,迭代数列才可以收敛于所求的根。
因此设计算法之前,对于一般迭代进行收敛性的判断是至关重要的。
牛顿法也叫切线法,是迭代算法中典型方法,只要初值选取适当,在单根附近,牛顿法收敛速度很快,初值对于牛顿迭代至关重要。
当初值选取不当可以采用牛顿下山算法进行纠正。
一般迭代:
牛顿公式:
牛顿下山公式:
图3.1一般迭代算法流程图
下山因子
下山条件4
算法描述一般迭代算法见流程图图3.2牛顿下山算法流程图
牛顿下山算法见流程图:
5、代码:
#include
#include
#include
usingnamespacestd;
class
srrt
{
private:
intn;
double
*a,*xr,*xi;
public:
srrt(intnn)
{
n=nn;
a=newdouble[n+1];
//动态分配内存
xr=newdouble[n];
xi=newdouble[n];
}
voidinput();
//由文件读入代数方程系数
voidsrrt_root();
//执行牛顿下山法
voidoutput();
//输出根到文件并显示
~srrt()
{
delete[]a,xr,xi;
}
};
voidsrrt:
:
input()
//由文件读入代数方程系数
{
int
i;
charstr1[20];
coutstr1;
ifstream
fin(str1);
if(!
fin)
{cout>a[i];
//读入代数方程系数
fin.close();
}
voidsrrt:
:
srrt_root()
//执行牛顿下山法
{
intm,i,jt,k,is,it;
doublet,x,y,x1,y1,dx,dy,p,q,w,dd,dc,c;
doubleg,u,v,pq,g1,u1,v1;
m=n;
while((m>0)&&(fabs(a[m])+1.0==1.0))m=m-1;
if(m1.0)dd=1.0;
dc=6.28/(4.5*k);c=0.0;
}
while(1==1)
{
c=c+dc;
dx=dd*cos(c);dy=dd*sin(c);
x1=x+dx;y1=y+dy;
if(c=q)it=1;
}
}
if(t>=1.0e-03)gotol40;
if(g>1.0e-18)
{
it=0;
if(it==0)
{
is=1;
dd=sqrt(dx*dx+dy*dy);
if(dd>1.0)dd=1.0;
dc=6.28/(4.5*k);c=0.0;
}
while(1==1)
{
c=c+dc;
dx=dd*cos(c);dy=dd*sin(c);
x1=x+dx;y1=y+dy;
if(c=q)it=1;
}
}
if(t>=1.0e-03)gotol40;
if(g>1.0e-18)
{
it=0;
if(it==0)
{
is=1;
dd=sqrt(dx*dx+dy*dy);
if(dd>1.0)dd=1.0;
dc=6.28/(4.5*k);c=0.0;
}
while(1==1)
{
c=c+dc;
dx=dd*cos(c);dy=dd*sin(c);
x1=x+dx;y1=y+dy;
if(cstr2;
ofstreamfout(str2);
if(!
fout)
{coutx[i][j];
}
}
for(i=0;ii;j--)
{
result[i]=result[i]-result[j]*x[i][j];
}
}
for(i=0;ixishu[i][j];
}
}
in.close();
//ofstreamout(“d:
//2.txt“);
intt=0;
while(t++n;
a=newfloat*[n];
for(inti=0;ia[i][j];
smallest(a,n,&b,&k);
//coutx;
result=b+k*x;
outn;
for(i=0;ix[i];
//couty[i];//coutt;
switch(t){
case1:
//coutf0>>f1;
c[0]=1;a[n]=1;
fxym[0]=6*((y[1]-y[0])/(x[1]-x[0])-f0)/h[0];
fxym[n]=6*(f1-(y[n]-y[n-1])/(x[n]-x[n-1]))/h[n-1];
break;
case2:
//coutf0>>f1;
c[0]=a[n]=0;
fxym[0]=2*f0;fxym[n]=2*f1;
break;
default:
coutch;
}while(ch=='y'||ch=='Y');
return0;}voidprintout(intn){
cout< for(inti=0;i cout< [“< /* cout< <<(y[i]-fxym[i]*h[i]*h[i]/6)/h[i]<<“*(“< <<(y[i+1]-fxym[i+1]*h[i]*h[i]/6)/h[i]<<“(x-“< cout<0)cout< elsecout<<-t<<“*(x-“< elsecout<<“-“<<-t<<“*(x-“< cout<0)cout<<“+“< elsecout<<“-“<<-t<<“*(“< elsecout<<“-“<<-t<<“*(x-“< cout< } cout< 最小二乘法: 三次样条差值: 8、分析体会 在实际应用中,有时需解决的问题中运算很复杂且运算量也很大,这时我们就需要借助计算机的帮助解决实际问题,即利用最小二乘法和样条插值在C++语言中的编程实现,可以帮助我更好的理解计算方法,上级实践有益于我的进一步学习。 因为在我们现实生活中我们需要通过已有的数据来发掘事物本身的内在规律,或者模拟出相应的数学模型来解决。 所以这就需要我们用到上述相关知识来完成。 实验五、龙贝格算法1实验目的 (1)熟悉复化梯形方法、复化Simpson方法、梯形递推算法、龙贝格算法; (2)能编程实现复化梯形方法、复化Simpson方法、梯形递推算法、龙贝格算法;(3)理解并掌握自适应算法和收敛加速算法的基本思想;(4)分析实验结果体会各种方法的精确度,建立计算机求解定积分问题的感性认识2 实验内容 (1)用龙贝格算法计算输入: 积分区间,误差限输出: 序列Tn,Sn,Cn,Rn及积分结果(参考书本P81的表2-4) (2)设计方案计算国土面积 为了计算瑞士国土的面积,首先对地图作了如下测量: 以西向东方向为x轴,由南向北方向为y轴,选择方便的原点,并将从最西边界到最东边界在x轴上的区间适当地划分为若干段,在每个分点的y方向测出南边界点和北边界点的y坐标,数据如表(单位mm): x 7.0 10.5 13.0 17.5 34.0 40.5 44.5 48.0 56.0 y1 44 45 47 50 50 38 30 30 34y2 44 59 70 72 93 100 110 110 110x 61.0 68.5 76.5 80.5 91.0 96.0101.0104.0106.5y1 36 34 41 45 46 43 37 33 28y2 117 118 116 118 118 121 124 121 121x 111.5118.0123.5136.5142.0146.0150.0157.0158.0y1 32 65 55 54 52 50 66 66 68y2 121 122 116 83 81 82 86 85 68 瑞士地图的外形如图(比例尺18mm: 40km) 问题: 试由测量数据计算瑞士国土的近似面积,并与其精确值41288平方公里比较提示: A.将计算国土面积问题转化为求积分问题B.当被积函数为表格形式(仅提供一组数据点,函数形式未知),使用梯形公式最为简单3 算法基本原理在许多实际问题中,常常需要计算定积分的值。 根据微积分学基本定理,若被积函数f(x)在区间[a,b]上连续,只要能找到f(x)的一个原函数F(x),便可利用牛顿-莱布尼兹公式求得积分值。 但是在实际使用中,往往遇到如下困难,而不能使用牛顿-莱布尼兹公式。 (1)找不到用初等函数表示的原函数 (2)虽然找到了原函数,但因表达式过于复杂而不便计算(3)f(x)是由测量或计算得到的表格函数由于以上种种困难,有必要研究积分的数值计算问题。 利用插值多项式则积分转化为,显然易算。 称为插值型求积公式。 最简单的插值型求积公式是梯形公式和Simpson公式,。 当求积结点提供较多,可以分段使用少结点的梯形公式和Simpson公式,并称为复化梯形公式、复化Simpson公式。 如步长未知,可以通过误差限的控制用区间逐次分半的策略自动选取步长的方法称自适应算法。 梯形递推公式给出了区间分半前后的递推关系。 由梯形递推公式求得梯形序列,相邻序列值作线性组合得Simpson序列,Simpson序列作线性组合得柯特斯序列,柯特斯序列作线性组合的龙贝格序列。 若|R2-R1| 如此加工数据的过程叫龙贝格算法,如下图所示: 图2.1龙贝格算法数据加工流程 复化梯形公式复化Simpson公式梯形递推公式加权平均公式: 龙贝格算法大大加快了误差收敛的速度,由梯形序列O(h2)提高到龙贝格序列的O(h8)4 算法描述 (1)梯形递推算法见流程图图2.2梯形递推算法流程图 图2.3龙贝格算法流程图 (2)龙贝格算法见流程图5计算用例的参考输出实验1参考输出如下图2.4龙贝格参考输出 6、代码h=b-a; T2=T1=(F(a)+F(b))*h/2; //进行梯形公式数据装载 for(inti=0;i { T[i]=T2; sum=0; x=a+h/2; while(x { sum=F(x)+sum; x+=h; } T2=(T1+h*sum)/2; h=h/2; T1=T2; } //进行梯形公式到辛甫生的转化 for(inti=0;i S[i]=(4*T[i+1]-T[i])/3; //进行辛甫生到柯特斯的转化 for(inti=0;i C[i]=(16*S[i+1]-S[i])/15; //进行柯特斯到龙贝格的转化 for(inti=0;i R[i]=(64*C[i+1]-C[i])/63; 7、实验运行如图: 8、分析体会 用龙贝格积分法进行近似求积,其原理与埃特金插值有些类似,进行线性整合后使结果具有高精度的求积效果。 在实际过程中,由于对于评判合理步长的困难,我们常采取变步长的办法进行计算,使结果满足精度要求。 龙贝格运算过程: 梯形公式装载数据→辛甫生化→柯特斯化→龙贝格高精度化。 通过实验我牢记了龙贝格算法的演算过程,更体会到了这一方法的高效和高精度。 实验六欧拉算法、龙格库塔、亚当姆斯1 实验目的 (1)熟悉数值微分中Euler法,改进Euler法,Rung-Kutta方法; (2)能编程实现Euler法,改进Euler法,Rung-Kutta方法;(3)通过实验结果分析各个算法的优缺点;(4)明确步长对算法的影响并理解变步长的Rung-Kutta方法2 实验内容 (1) 0 输入: 求解区间,初值,数值解个数输出: 数值解 (2)小型火箭初始质量为900千克,其中包括600千克燃料。 火箭竖直向上发射时燃料以15千克/秒的速率燃烧掉,由此产生30000牛顿的恒定推力.当燃料用尽时引擎关闭。 设火箭上升的整个过程中,空气阻力与速度平方成正比,比例系数为0.4(千克/米).重力加速度取9.8米/秒2.输入: 相关数据输出: 引擎关闭瞬间火箭的高度、速度、加速度,及火箭到达最高点的时间和高度.提示: 可得到火箭飞行过程的方程: 初始条件为 3 算法基本原理在许多科学技术问题中,建立的模型常常以常微分方程的形式表示。 然而,除了少数特殊类型的常微分方程能用解析方法求其精确解外,要给出一般方程解析解的表达式是困难的。 所以只能用近似方法求其数值解,在实际工作中常用计算机求常微分方程的数值解。 所谓常微分方程的数值解即对于常微分方程初值问题计算出在一系列节点a=x0 数值解法的基本思想用差商代替导数,实现连续问题离散化,选取不同的差商代替导数可以得到不同公式。 改进欧拉公式是常用方法之一,包括预测和校正两步。 先用欧拉公式进行预报,再将预报值代入梯形公式进行校正,从而达到二阶精度。 通过龙格-库塔法我们可以获得更高精度。 经典龙格-库塔法即在区间[xn,xn+1]取四点,并对这四点的斜率进行加权平均作为平均斜率,通过泰勒公式寻找使局部截断误差为O(h5)(即4阶精度)的参数满足条件。 改进的欧拉公式: 预测校正四阶(经典)龙格-库塔公式 4 算法描述 (1)改进的欧拉算法见流程图 (2) 经典龙格-库塔算法见流程图5计算用例的参考输出 (1)实验1参考输出如下 图5.3经典龙格库塔算法 图5.2改进欧拉算法 (2)实验2参考输出如下关闭引擎时(秒),此时火箭的高度h==8322.4米,速度v==254.1728米/秒,加速度为a==4.0616米/秒,火箭到最高点的时间=51秒,高度=9186.4米。 6代码改进的欧拉格式: /*取h=0.2,用改进欧拉方法求解下列初值问题。 dy/dx=sqrt(2*x*x+3*y*y),y(0)=5,0<=x<=20.程序: */#include#include#definexxxx50doublef(doublex,doubley);voidmain(void){ doublea,b,h,x[xxxx],y[xxxx]; longi,n; printf(“\n请输入求解区间a,b: “); scanf(“%1f,%1f“,&a,&b); printf(“\n请输入步长h: “); scanf(“%1f“,&h); n=(long)((b-a)/h); x[0]=a; printf(“\n请输入起点x[0]=%1f处得纵坐标y[0]: “,x[0]); scanf(“%1f“,&y[0]); for(i=0;i { x[i+1]=x[i]+h; y[i+1]=y[i]+h*f(x[i],y[i]); y[i+1]=y[i]+h*(f(x[i],y[i])+f(x[i+1],y[i+1]))/2; } printf(“\n计算结果为: “); for(i=0;i<=n;i++) printf(“\nx[%1d]=%1f,y[%1d]=%1f“,i,x[i],i,y[i]);}doublef(doublex,doubley){ return(sqrt(2*x*x+3*y*y));}龙哥库塔: #includeusingnamespacestd; main(){ intk; floatX[k],Y[k],F[k]; floath=0.001; doubleK1,K2,K3,K4; floatf(float,float); X[0]=0.0; Y[0]=1.0; F[0]=f(X[0],Y[0]); for(k=0;k<100;k++) {X[k+1]=X[k]+h; K1=h*F[k]; K2=h*f(X[k]+0.5*h,Y[k]+0.5*K1); K3=h*f(X[k]+0.5*h,Y[k]+K2); K4=h*f(X[k]+h,Y[k]+K3); Y[k+1]=Y[k]+(K1+2.0*K2+2.0*K3+K4)/6.0; F[k+1]=f(X[k+1],Y[k+1]); cout< cout< cout< } system(“Pause“); return0;}floatf(floata,floatb){floatc; c=b-a*2.0/b; return(c); }7、欧拉算法 龙格库塔 亚当姆斯 8、分析体会 改进的欧拉算法、龙格库塔算法和亚当姆斯算法是计算方法中的难点,经过了上机实践了,掌握起来会更透彻一点。 程序的编制过程中,我体会到了将一个抽象的数值计算方法变为一个具体计算机程序的不易。 这个过程,让我对各种数值计算方法的数学公式有了更进一步的认识,因为要编制出计算机程序,就必须清楚数值计算方法的具体计算步骤。 学习了这门课,感觉实用性比较大。 这门课程也是连接数学与计算机之间的桥梁,计算方法这门学科只有和计算机结合才能体现出其价值。 借助计算机我们可以快速解决各种方程的求值,且结果具有高度精确性,这是单一的数学学习做不到的。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 合工大 计算方法 试验报告