合肥工业大学 计算机专业 计算方法实验报告.docx
- 文档编号:24264391
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:44
- 大小:740.89KB
合肥工业大学 计算机专业 计算方法实验报告.docx
《合肥工业大学 计算机专业 计算方法实验报告.docx》由会员分享,可在线阅读,更多相关《合肥工业大学 计算机专业 计算方法实验报告.docx(44页珍藏版)》请在冰豆网上搜索。
合肥工业大学计算机专业计算方法实验报告
合肥工业大学
计算机与信息学院
实验报告
课程:
计算方法
专业班级:
学号:
姓名:
Java界面
其实都不难按照程序流程图就可以完成了
实验一插值与拟合
一、实验目的
(1)明确插值多项式和分段插值多项式各自的优缺点;
(2)编程实现三次样条插值算法,分析实验结果体会高次插值产生的龙格现象;
(3)理解最小二乘拟合,并编程实现线性拟合,掌握非线性拟合转化为线性拟合的方法
(4)运用常用的插值和拟合方法解决实际问题。
二、实验内容
(1)对于f(x)=1/(1+x*x)实现三次样条插值
(2)实现最小二乘法的直线拟合
数据如下:
165
123
150
123
141
187
126
172
125
148
三、基本原理(计算公式)
(1)三次样条插值在每个内节点上具有2阶导数。
(2)最小二乘法拟合直线为y=a+bx,而a,b有如下等式(N为给出的数据点的总个数)
;
四、算法设计与实现(流程图,关键点)
最小二乘法直线拟合:
输入数据后,按照公式计算a,b。
用得到的拟合直线计算预测点的近似函数值。
五、输入与输出
(1)三次样条插值
输入:
区间长度,n+1个数据点,预测点
输出:
预测点的近似函数值,精确值,及误差
(2)最小二乘法直线拟合
输入:
n个数据点,预测点
输出:
预测点的近似函数值
六、结果讨论和分析
代码
三次样条插值
#include
#include
#defineN10
usingnamespacestd;
doubleu0(doublex){
return(x-1)*(x-1)*(2*x+1);
}
doubleu1(doublex){
returnx*x*(3-2*x);
}
doublev0(doublex){
returnx*(x-1)*(x-1);
}
doublev1(doublex){
returnx*x*(x-1);
}
doubles3(doublex,doubley,doubley1,doublem,doublem1,doubleh){
returnu0(x)*y+u1(x)*y1+h*v0(x)*m+h*v1(x)*m1;
}
doublef(doublex){
return1/(1+x*x);
}
intmain(){
ifstreamfin;
fin.open("E:
\\t.txt");
if(!
fin){
cout<<"erroropeninginputstream"< system("pause"); return0; } doublex[N+1],y[N+1],m[N+1],A[N],B[N],C[N]; doubleh[N]; doublea[N],b[N]; doublef0,fn; doubletemp; inti; for(i=0;i<=N;i++){ fin>>x[i]>>y[i]; } fin>>f0>>fn; h[0]=x[1]-x[0]; for(i=1;i h[i]=x[i+1]-x[i]; a[i]=h[i-1]/(h[i-1]+h[i]); b[i]=3*((1-a[i])*(y[i]-y[i-1])/h[i-1]+a[i]*(y[i+1]-y[i])/h[i]); } m[1]=b[1]-(1-a[1])*f0; m[N-1]=b[N-1]-a[N-1]*fn; for(i=2;i m[i]=b[i]; } for(i=1;i B[i]=2; C[i]=a[i]; } for(i=2;i A[i]=1-a[i]; } C[1]=C[1]/B[1]; m[1]=m[1]/B[1]; doublet; for(i=2;i! =N-2;i++){ t=B[i]-C[i-1]*A[i]; C[i]=C[i]/t; m[i]=(m[i]-m[i-1]*A[i])/t; } m[N-1]=(m[N-1]-m[N-2]*A[N-1])/(B[N-1]-C[N-2]*A[N-1]); for(i=N-2;i>0;i--){ m[i]=m[i]-C[i]*m[i+1]; } cout<<"please: (输入插值节点在"< while(cin>>temp){ doublett=temp; if(temp cout<<"插值节点为"< continue; } for(i=1;i<=N;i++){ if(temp } temp=(temp-x[i-1])/h[i-1]; temp=s3(temp,y[i-1],y[i],m[i-1],m[i],h[i-1]); cout<<"插值节点为"< } system("pause"); fin.close(); return0; } 最小二乘法的直线拟合 #include #include #definen5 usingnamespacestd; doublesum(doublex[],intk){ inti; doublesum=0; for(i=0;i sum=sum+x[i]; returnsum; } doublesum2(doublex[],intk){ inti; doublesum=0; for(i=0;i sum=sum+x[i]*x[i]; returnsum; } doublesumxy(doublex[],doubley[],intk){ inti; doublesum=0; for(i=0;i sum=sum+x[i]*y[i]; returnsum; } intmain(){ ifstreamfin; fin.open("E: \\t.txt"); if(! fin){ cout<<"erroropeninginputstream"< system("pause"); return0; } doublex[n],y[n],a,b; doublex0,y0; inti; for(i=0;i fin>>x[i]>>y[i]; } b=(n*sumxy(x,y,n)-sum(x,n)*sum(y,n))/(n*sum2(x,n)-sum(x,n)*sum(x,n)); a=(sum(y,n)-b*sum(x,n))/n; cout<<"最小二乘法直线拟合得到a: "< "< cout<<"请输入插值节点x: "; while(cin>>x0){ y0=a+b*x0; cout<<"当x="< cout<<"请输入插值节点x: "; } system("pause"); fin.close(); return0; } 实验二数值积分 一、实验目的 (1)熟悉复化梯形方法、复化Simpson方法、梯形递推算法、龙贝格算法; (2)能编程实现龙贝格算法和中点加速; (3)理解并掌握自适应算法和收敛加速算法的基本思想; (4)分析实验结果体会各种方法的精确度,建立计算机求解定积分问题的感性认识 二、实验内容 (1)用龙贝格算法计算 (2)用中点加速方法计算 的一阶导数 三、基本原理(计算公式) (1)龙贝格算法 梯形递推公式 加权平均公式: (2)中点加速 中点公式: G(h)=(f(a+h)-f(a-h))/2/h 加权平均: G1(h)=4*G(h/2)/3-G(h)/3 G2(h)=16*G1(h/2)/15-G1(h)/15 G3(h)=64*G2(h/2)/63-G2(h)/63 四、算法设计与实现(流程图,关键点) 中点加速: 输入数据后根据公式计算导数值 五、输入与输出 (1)用龙贝格算法计算 输入: 积分区间,误差限 输出: 序列Tn,Sn,Cn,Rn及积分结果 (2)用中点加速方法计算 的一阶导数 输入: 求导节点,步长 输出: 求得的导数值,精确值 六、结果讨论和分析 代码 龙贝格算法 #include #include #include usingnamespacestd; doublef(doublex){ if(x==0)return1; returnsin(x)/x; } intmain(){ ifstreamfin; fin.open("E: \\t.txt"); if(! fin){ cout<<"erroropeninginputstream"< system("pause"); return0; } doublea,b,e,t1,t2,s1,s2,c1,c2,r1,r2; doublex,h,s; fin>>a>>b>>e; cout<<"积分区间为["< cout<<"kT2S2C2R2"< h=b-a; t1=(f(a)+f(b))*h/2; cout<<0<<""< intk; for(k=1;k<=10;k++,h=h/2,t1=t2,s1=s2){ s=0; x=a+h/2; do{ s=s+f(x); x=x+h; }while(x t2=t1/2+h*s/2; s2=t2+(t2-t1)/3; if(k==1){ cout< continue; } c2=s2+(s2-s1)/15; if(k==2){ cout< c1=c2; continue; } r2=c2+(c2-c1)/63; cout< if(k==3){ r1=r2; c1=c2; continue; } if(fabs(r2-r1) cout<<"数值积分结果为"< break; } r1=r2; c1=c2; } system("pause"); return0; } 中点加速算法 #include #include #include usingnamespacestd; doublef(doublex){ returnexp(x); } doublef1(doublex){ returnexp(x); } doubleg(doublex,doubleh){ return(f(x+h)-f(x-h))/2/h; } doubleg1(doublex,doubleh){ return4*g(x,h/2)/3-g(x,h)/3; } doubleg2(doublex,doubleh){ return16*g1(x,h/2)/15-g1(x,h)/15; } doubleg3(doublex,doubleh){ return64*g2(x,h/2)/63-g2(x,h)/63; } intmain(){ ifstreamfin; fin.open("E: \\t.txt"); if(! fin){ cout<<"erroropeninginputstream"< system("pause"); return0; } doublea,h; while(fin>>a>>h) cout<<"当x="< system("pause"); fin.close(); return0; } 实验三非线性方程求根迭代法 一、实验目的 (1)熟悉非线性方程求根简单迭代法,牛顿迭代及牛顿下山法 (2)能编程实现牛顿下山法 (3)认识选择迭代格式的重要性 (4)对迭代速度建立感性的认识;分析实验结果体会初值对迭代的影响 二、实验内容 用牛顿下山法解方程 (初值为0.6) 三、基本原理(计算公式) 求非线性方程组的解是科学计算常遇到的问题,有很多实际背景.各种算法层出不穷,其中迭代是主流算法。 只有建立有效的迭代格式,迭代数列才可以收敛于所求的根。 因此设计算法之前,对于一般迭代进行收敛性的判断是至关重要的。 牛顿法也叫切线法,是迭代算法中典型方法,只要初值选取适当,在单根附近,牛顿法收敛速度很快,初值对于牛顿迭代 至关重要。 当初值选取不当可以采用牛顿下山算法进行纠正。 一般迭代: 牛顿公式: 牛顿下山公式: 下山因子 下山条件 四、算法设计与实现(流程图,关键点) 五、输入与输出 输入: 初值,误差限,迭代最大次数,下山最大次数 输出: 近似根各步下山因子 六、结果讨论和分析 代码 牛顿下山法 #include #include #include usingnamespacestd; doublef(doublex){//函数 returnx*x*x-x-1; } doublef1(doublex){//一阶导数 return3*x*x-1; } intmain(){ ifstreamfin; fin.open("E: \\t.txt"); if(! fin){ cout<<"Erroropeninginputstream"< system("pause"); return0; } doublex0,x1,e,j,temp; intN,M,k,i; fin>>x0>>e>>M>>N; cout<<"迭代初值为"< x1=0; for(k=0;k =0;k++){ i=0; j=1; temp=f(x0)/f1(x0); do{ x1=x0-temp/j; cout<<"x0: "< "< "< "<<1/j<<",迭代次数: "< i++; j=j*2; if(i>=M)break; }while(fabs(f(x1))>=fabs(f(x0))); if(i>=M){ cout<<"重新选择x0"< break; } if(fabs(x1-x0) cout<<"迭代成功,求得结果为"< break; } x0=x1; } if(k>=N)cout<<"迭代失败"< if(f1(x0)==0)cout<<"一阶导数为0"< fin.close(); system("pause"); return0; } 实验四求解线性方程组 一、实验目的 (1)熟悉求解线性方程组的有关理论和方法; (2)能编程实现高斯-塞德尔迭代法、列主元高斯消去法、LU分解法 (3)通过测试,进一步了解各种方法的优缺点 (4)根据不同类型的方程组,选择合适的数值方法 二、实验内容 (1)用高斯-塞德尔迭代法求 (2)列主元高斯消去法求 (3)LU分解法求解方程组 三、基本原理(计算公式) 线性方程组大致分迭代法和直接法。 只有收敛条件满足时,才可以进行迭代。 雅可比及高斯-塞德尔是最基本的两类迭代方法,最大区别是迭代过程中是否引用新值进行剩下的计算。 消元是最简单的直接法,并且也十分有效的,列主元高斯消去法对求解一般的线性方程组都适用,同时可以用来求矩阵对应的行列式。 约当消去实质是经过初等行变换将系数矩阵化为单位阵,主要用来求矩阵的逆。 在使用直接法,要注意从空间、时间两方面对算法进行优化。 高斯-塞德尔迭代: 列主元高斯消去法: 列主元 消元 回代 四、算法设计与实现(流程图,关键点) LU分解法: 依次求得L、U、y和x 五、输入与输出 (1)用高斯-塞德尔迭代法 输入: 系数矩阵A,最大迭代次数N,初始向量,误差限e 输出: 解向量 (2)列主元高斯消去法 输入: 系数矩阵A 输出: 解向量 (3)LU分解法 输入: 系数矩阵A 输出: 解向量 六、结果讨论和分析 代码 高斯塞德尔迭代 #include #include #include #definen3 usingnamespacestd; voidshow(doublea[n+1][n+1],doubleb[n+1]){ inti,j; cout<<"原方程为: "< for(i=1;i<=n;i++){ for(j=1;j if(a[i][j+1]<0) cout< else cout< cout< } } intmain(){ ifstreamfin; fin.open("E: \\t.txt"); if(! fin){ cout<<"Erroropeninginputstream"< system("pause"); return0; } doublex[n+1],y[n+1],a[n+1][n+1],b[n+1],e,temp,max; inti,j,k,N; fin>>e>>N; for(i=1;i<=n;i++){ fin>>x[i]; y[i]=x[i]; } cout<<"初始向量为: "; for(i=1;i cout< for(i=1;i<=n;i++){ for(j=1;j<=n;j++)fin>>a[i][j]; fin>>b[i]; } show(a,b); k=0; while(true){ for(i=1;i<=n;i++){ temp=0; for(j=1;j<=n;j++) if(j! =i)temp=temp+a[i][j]*y[j]; y[i]=(b[i]-temp)/a[i][i]; } max=fabs(y[1]-x[1]); for(i=2;i<=n;i++) if(max max=fabs(y[i]-x[i]); if(max cout<<"高斯赛德尔迭代求得原方程的解为"< for(i=1;i<=n;i++)cout<<"x"< cout< break; } if(k==N){ cout<<"迭代失败"< break; } else{ k++; for(i=1;i<=n;i++)x[i]=y[i]; } } fin.close(); system("pause"); return0; } 高斯消去 #include #include #include #definen3 usingnamespacestd; voidshow(doublea[n+1][n+1],doubleb[n+1]){ inti,j; cout<<"原方程为: "< for(i=1;i<=n;i++){ for(j=1;j if(a[i][j+1]<0) cout< else
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 合肥工业大学 计算机专业 计算方法实验报告 合肥 工业大学 计算方法 实验 报告