1、数值分析上机作业最强版 数值分析上机作业姓 名:唐 皓学 号:142460专 业:道路与铁道工程院 系: 交通学院授课教师:吴 宏 伟日 期:2015年1月习题一1 题目17(上机题)舍入误差与有效数设,其精确值为。(1)编制按从大到小的顺序,计算的通用程序;(2)编制按从小到大的顺序,计算的通用程序;(3)按两种顺序分别计算,并指出有效位数。(编制程序时用单精度);(4)通过本上机题你明白了什么?2 通用程序代码2.1 按从小到大的顺序计算void AscendSum(unsigned long int N)/ 计算从大到小的总和 for(unsigned long int j=2;j=N;
2、j+) ascendSum+=(float)1.0/(j*j-1); coutSum From 1 to N (Ascend) is: ascendSum=2;j-) descendSum+=(float)1.0/(j*j-1); coutSum From N to 1 (Descend) is: descendSumendl; Error(descendSum); Delimiter();3 计算结果展示图1 N=100时的计算结果图2 N=10000时的计算结果图3 N=1000000时的计算结果表1-1 计算结果汇总精确值按从小到大按从大到小值有效位数值有效位数0.74004948140
3、.7400494814100.74004954160.74989998340.749852120940.7498999834100.74999898670.75185602920.752992510824 计算结果分析(1)如果采用单精度数据结构进行计算,则相较于双精度的数据结果,由于数据存储字长的限制导致计算机存在较大的舍入误差,因此本程序采用的是双精度数据存储方式。(2)由计算结果可知,正序计算和逆序计算的精度是不稳定的。由计算结果可以发现,当N=100时,正序计算(1-N)的精度较高;当N=10000时,逆序计算(N-1)的精度较高;当N=1000000时,正序计算和逆序计算的精度一样。
4、当然,和其他同学做出来的结果对比,结论并不一致。我个人分析这是因为电脑的硬件、软件(位数)不同等原因导致的。但总体而言,在N较小时,正序计算精度高于逆序计算的精度。当N较大时,正序和逆序计算的精度接近。(3)由于计算机的实际计算过程是一种舍入机制,故对于我们计算所采用的加法交换律是不成立的。计算机中若干数相加时,先要进行对阶操作,即将两数的阶数统一为绝对值较大的数的阶数。这样一来将导致绝对值较小的数的有效数字可能会大量损失,增大舍入误差,即所谓的“大数吃小数”现象。为了避免这种现象的出现,在进行加减法的时候应该先将绝对值较小的数相加,再与绝对值较大的数相加这样按阶逐步递增的相加。5 完整代码#
5、include #include #include using namespace std;float accurateSum=0,ascendSum=0,descendSum=0;void Delimiter()/输出一系列星号以间隔 for(int i=1;i=50;i+) cout*; coutendl;void Error(float Sum)/计算绝对误差 float error; error=fabs(Sum-accurateSum); int flag; for(flag=0;flag0.5) break; coutThere are flag Valid numbers.n;v
6、oid AccurateSum(unsigned long int N)/计算精确值 accurateSum=0.5*(1.5-(float)1/N-(float)1/(N+1); coutAccurate sum is: setprecision(10)accurateSumendl; Delimiter();void AscendSum(unsigned long int N)/计算从大到小的总和 for(unsigned long int j=2;j=N;j+) ascendSum+=(float)1.0/(j*j-1); coutSum From 1 to N (Ascend) is:
7、 ascendSum=2;j-) descendSum+=(float)1.0/(j*j-1); coutSum From N to 1 (Descend) is: descendSumendl; Error(descendSum); Delimiter();void main()/主程序 long int N; while(1) cout=2):; cinN; if (N2) cout=eps) x1=x2; x2=x1-f(x1)/df(x1); return x1;2.2 求解尽可能大double MaximalDeviateRange() /求解尽可能大的范围 double step=
8、1e-5; /step length int cnt=1; /step count double delta; cout*Newton Iteration (eps=1e*5)*endl; while(fabs(NewtonIteration(step*cnt,eps)=eps) cnt+; delta=step*cnt; coutThe maximal deviate range for x converging to x2*=0 is (-delta,delta)endl; return delta;6 计算结果展示图2-1 计算结果在取步长为的情况下,允许误差时有轴上的一个小区间为迭代序
9、列在处的尽可能大的局部收敛区间。当,时牛顿迭代序列分别收敛于。7 计算结果分析(1)通过本次上机编程并通过多次的调试,可以发现运行结果很好的验证了教材上牛顿迭代法具有局部收敛性这一重要性质。(2)选择不同的初值区间,迭代序列会收敛于不同的根。所以为了收敛到需要的计算结果,就需要选择合适的牛顿迭代法大范围收敛区间。(3)产生上述结果的原因是所选取的部分区间不满足大范围收敛的条件,导致并没有收敛到理想的结果。8 完整代码#include#include#include using namespace std;double eps=1e-5;double f(double x)/函数f(x)的录入
10、return (x*x*x)/3-x;double df(double x)/函数f(x)的导数 return (x*x)-1;double NewtonIteration(double x0,double eps)/Newton迭代法求解子程序 double x1,x2; x1=x0; x2=x1-f(x1)/df(x1); while (fabs(x1-x2)=eps) x1=x2; x2=x1-f(x1)/df(x1); return x1;double MaximalDeviateRange() /求解尽可能大的范围 double step=1e-5; /step length int
11、 cnt=1; /step count double delta; cout*Newton Iteration (eps=1e*5)*endl; while(fabs(NewtonIteration(step*cnt,eps)=eps) cnt+; delta=step*cnt; coutThe maximal deviate range for x converging to x2*=0 is (-delta,delta)endl; return delta;void Calculate(double x0)/计算Newton迭代法和相应的子程序 printf(If x0=% 11.4f,
12、x converges to the value of: % 8.6fn,x0,NewtonIteration(x0,eps);void main()/主程序 double delta=MaximalDeviateRange(); Calculate(-10000); Calculate(-1-delta)/2); Calculate(-delta/2); Calculate(delta/2); Calculate(1+delta)/2); Calculate(10000);习题三9 题目39(上机题)列主元消去法对于某电路的分析,归结为求解线性方程组。其中(1)编制解阶线性方程组的列主元消去
13、法的通用程序;(2)用所编程序解线性方程组,并打印出解向量,保留5位有效数;(3)本题编程之中,你提高了哪些编程能力?10 通用程序代码void GaussElimination(float matrixROWCOL)/高斯列主元消去法主程序 int row,col; int tmpRow,maxRow,tmpCol; float ratio; float rootROW; /Calculate the echelon matrix for(row=0;rowROW-1;row+) col=row; maxRow=row; for(tmpRow=row;tmpRowfabs(matrixmax
14、Rowcol) maxRow=tmpRow; SwapRow(matrixrow,matrixmaxRow); for(tmpRow=row+1;tmpRowROW;tmpRow+) ratio=matrixtmpRowcol/matrixrowcol; if(ratio=0) continue; for(tmpCol=0;tmpCol=0;tmpRow-) sum=0; for(cnt=tmpRow+1;cntROW;cnt+) sum+=AugmentedMatrixtmpRowcnt*rootcnt; roottmpRow=(AugmentedMatrixtmpRowCOL-1-sum)
15、/AugmentedMatrixtmpRowtmpRow; printf(The Solution Vector is:n); for(cnt=0;cntROW;cnt+) printf(% 8.5f ,rootcnt); printf(n);11 计算结果展示图 3-1计算结果解向量为:12 结果分析和心得体会(1)在本题编程过程中,由于考虑到列主元Gauss消去法的算法特点:程序的过程重复性高,故本程序采用模块化程序设计方法。这样就可以将每步都要重复进行的消去、交换列主元等过程的功能以模块函数来实现。这样可以使程序结构清晰,从而调试变得相对容易。(2)在输入/输出的控制方面,本程序采用格式
16、化输出,使输出结果自动对齐,提高了程序的结果的可阅读性。(3)为了能更方便快捷地进行矩阵数据的输入。将需要求解的线性方程增广矩阵存储在文件中,程序运行时自动调用并输出。因此,对于任意线性矩阵,只需将其增广矩阵存储于其中,并修改ROW和COL为实际行数与列数即可。(4)通过该程序的编写,提高了我对循环语句的运用、子程序调用以及找bug(错位)的能力。此外,我也对列主元Gauss消去法的步骤有了更加深刻的理解。13 完整代码#include#include#include#includeconst int ROW=9,COL=10;float AugmentedMatrixROWCOL;void
17、PrintMatrix(float matrixROWCOL)/输出解子程序 int row,col; for(row=0;rowROW;row+) for(col=0;colCOL;col+) printf(% 9.5f ,matrixrowcol); printf(n); void PrintDelimiter() for(int i=0;i100;i+) printf(*); printf(n);void ReadData(char filename, float matrixROWCOL)/读入数据程序 ifstream infile(filename); if (!infile) c
18、outCannot open the Augmented Matrix data file!n; coutThe Augmented Matrix is:endl; for(int i=0;iROW;i+) for(int j=0;jmatrixij; coutsetw(3)matrixij ; coutendl; PrintDelimiter(); infile.close();void SwapRow(float rowA, float rowB)/交换两行的子程序 int i; float tmp; for(i=0;iCOL;i+) tmp=rowAi; rowAi=rowBi; row
19、Bi=tmp; void GaussElimination(float matrixROWCOL)/高斯列主元消去法主程序 int row,col; int tmpRow,maxRow,tmpCol; float ratio; float rootROW; /Calculate the echelon matrix for(row=0;rowROW-1;row+) col=row; maxRow=row; for(tmpRow=row;tmpRowfabs(matrixmaxRowcol) maxRow=tmpRow; SwapRow(matrixrow,matrixmaxRow); for(
20、tmpRow=row+1;tmpRowROW;tmpRow+) ratio=matrixtmpRowcol/matrixrowcol; if(ratio=0) continue; for(tmpCol=0;tmpCol=0;tmpRow-) sum=0; for(cnt=tmpRow+1;cntROW;cnt+) sum+=AugmentedMatrixtmpRowcnt*rootcnt; roottmpRow=(AugmentedMatrixtmpRowCOL-1-sum)/AugmentedMatrixtmpRowtmpRow; printf(The Solution Vector is:
21、n); for(cnt=0;cntROW;cnt+) printf(% 8.5f ,rootcnt); printf(n);void main()/主程序 ReadData(AugmentedMatrix.txt,AugmentedMatrix); GaussElimination(AugmentedMatrix);题目四14 题目37(上机题)3次样条插值函数(1)编制求第一型3次样条插值函数的通用程序;(2)已知汽车门曲线型值点的数据如下:0123456789100123456789102.513.304.044.705.225.545.785.405.575.705.80端点条件为,用所
22、编制程序求车门的3次样条插值函数,并打印出。15 计算结果展示通过运行程序,求得S(X)的表达式后,分别求各个点的值,得到如下结果:图 4-1 运行结果即有:S(0.5)= 2.90856425S(1.5)= 3.67842873S(2.5)= 4.38147084S(3.5)= 4.98818792S(4.5)= 5.38327747S(5.5)= 5.72370219S(6.5)= 5.59441375S(7.5)= 5.4298928S(8.5)= 5.65976505S(9.5)= 5.7322969916 完整代码#include#include#includeusing namespace std;cons
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1