数值分析上机作业**:**学号:******专业:道路与铁道工程院系:交通学院****:***日期:2015年1月习题一1 题目17.(上机题)舍入误差与有效数 设2211NN j S j ==-∑,其精确值为1311221N N ⎛⎫-- ⎪+⎝⎭。
(1)编制按从大到小的顺序22211121311N S N =+++---,计算N S 的通用程序; (2)编制按从小到大的顺序2221111(1)121N S N N =+++----,计算N S 的通用程序; (3)按两种顺序分别计算210S ,410S ,610S ,并指出有效位数。
(编制程序时用单精度);(4)通过本上机题你明白了什么?2 通用程序代码2.1 按从小到大的顺序计算N Svoid AscendSum(unsigned long int N)// 计算从大到小的总和 {for (unsigned long int j=2;j<=N;j++) ascendSum+=(float )1.0/(j*j-1);cout<<"Sum From 1 to N (Ascend) is: "<<ascendSum<<endl; Error(ascendSum); Delimiter();} 2.2 按从大到小的顺序计算N Svoid DescendSum(unsigned long int N)//计算从小到大的总和 {for (unsigned long int j=N;j>=2;j--) descendSum+=(float )1.0/(j*j-1);cout<<"Sum From N to 1 (Descend) is: "<<descendSum<<endl; Error(descendSum); Delimiter();}3计算结果展示图1 N=100时的计算结果图2 N=10000时的计算结果图3 N=1000000时的计算结果表1-1 计算结果汇总N S精确值按从小到大按从大到小N S 值有效位数 N S 值有效位数210S 0.7400494814 0.7400494814 10 0.740049541 6 410S 0.7498999834 0.7498521209 4 0.7498999834 10 610S0.74999898670.75185602920.752992510824 计算结果分析(1)如果采用单精度数据结构进行计算,则相较于双精度的数据结果,由于数据存储字长的限制导致计算机存在较大的舍入误差,因此本程序采用的是双精度数据存储方式。
(2)由计算结果可知,正序计算和逆序计算的精度是不稳定的。
由计算结果可以发现,当N=100时,正序计算(1-N )的精度较高;当N=10000时,逆序计算(N-1)的精度较高;当N=1000000时,正序计算和逆序计算的精度一样。
当然,和其他同学做出来的结果对比,结论并不一致。
我个人分析这是因为电脑的硬件、软件(位数)不同等原因导致的。
但总体而言,在N 较小时,正序计算精度高于逆序计算的精度。
当N 较大时,正序和逆序计算的精度接近。
(3)由于计算机的实际计算过程是一种舍入机制,故对于我们计算所采用的加法交换律是不成立的。
计算机中若干数相加时,先要进行对阶操作,即将两数的阶数统一为绝对值较大的数的阶数。
这样一来将导致绝对值较小的数的有效数字可能会大量损失,增大舍入误差,即所谓的“大数吃小数”现象。
为了避免这种现象的出现,在进行加减法的时候应该先将绝对值较小的数相加,再与绝对值较大的数相加这样按阶逐步递增的相加。
5 完整代码#include <iostream> #include <iomanip> #include <math.h> using namespace std;float accurateSum=0,ascendSum=0,descendSum=0;void Delimiter()//输出一系列星号以间隔 {for (int i=1;i<=50;i++) cout<<"*";cout<<endl;}void Error(float Sum)//计算绝对误差{float error;error=fabs(Sum-accurateSum);int flag;for(flag=0;flag<10;flag++){error=error*10;if (error>0.5)break;}cout<<"There are "<<flag<<" Valid numbers."<<"\n";}void AccurateSum(unsigned long int N)//计算精确值{accurateSum=0.5*(1.5-(float)1/N-(float)1/(N+1));cout<<"Accurate sum is: "<<setprecision(10)<<accurateSum<<endl;Delimiter();}void AscendSum(unsigned long int N)//计算从大到小的总和{for(unsigned long int j=2;j<=N;j++)ascendSum+=(float)1.0/(j*j-1);cout<<"Sum From 1 to N (Ascend) is: "<<ascendSum<<endl;Error(ascendSum);Delimiter();}void DescendSum(unsigned long int N)//计算从小到大的总和{for(unsigned long int j=N;j>=2;j--)descendSum+=(float)1.0/(j*j-1);cout<<"Sum From N to 1 (Descend) is: "<<descendSum<<endl;Error(descendSum);Delimiter();}void main()//主程序{long int N;while(1){cout<<"Input an integer N (N>=2):";cin>>N;if (N<2)cout<<"Invalid input, Please try it again!\n";elsebreak;}AccurateSum(N);AscendSum(N);DescendSum(N);}习题二1 题目20.(上机题)Newton 迭代法(1)给定初值0x 及容许误差ε,编制Newton 法解方程()0f x =根的通用程序。
(2)给定方程3()/30f x x x =-=,易知其有三个根1x *=20x *=,3x *=。
①由Newton 方法的局部收敛性可知存在0δ>,当0(,)x δδ∈-时,Newton 迭代序列收敛于根2x *。
试确定尽可能大的δ。
②试取若干初始值,观察当0(,1)x ∈-∞-,(1,)δ--,(,)δδ-,(,1)δ,(1,)∞时Newton 序列是否收敛以及收敛于哪一个根。
(3) 通过本上机题,你明白了什么?2 通用程序代码2.1 Newton 法解方程通用程序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; }2.2 求解尽可能大δdouble MaximalDeviateRange() //求解尽可能大的范围 {double step=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;cout<<"The maximal deviate range for x converging to x2*=0 is (-"<<delta<<","<<delta<<")"<<endl;return delta;}3计算结果展示图2-4 计算结果在取步长为10−5的情况下,允许误差eps=10−5时有x轴上的一个小区间 (−0.7746,0.7746)为Newton迭代序列在x2∗=0处的尽可能大的局部收敛区间。
当x0=(−∞,1),(−1,−δ),(−δ,δ),(δ,1),(1,∞)时牛顿迭代序列分别收敛于−1.732051,1.732051,0,−1.732051,1.732051。
4计算结果分析(1)通过本次上机编程并通过多次的调试,可以发现运行结果很好的验证了教材上牛顿迭代法具有局部收敛性这一重要性质。
(2)选择不同的初值区间,迭代序列会收敛于不同的根。
所以为了收敛到需要的计算结果,就需要选择合适的牛顿迭代法大范围收敛区间。
(3)产生上述结果的原因是所选取的部分区间不满足大范围收敛的条件,导致并没有收敛到理想的结果。
5完整代码#include<iostream>#include<iomanip>#include<math.h>using namespace std;double eps=1e-5;double f(double x)//函数f(x)的录入{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 lengthint cnt=1; //step countdouble delta;cout<<"**********************Newton Iteration(eps=1e*5)**********************"<<endl;while(fabs(NewtonIteration(step*cnt,eps))<=eps){cnt++;}delta=step*cnt;cout<<"The 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, x converges to the value of: % 8.6f\n",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);}习题三1 题目39.(上机题)列主元Guass 消去法对于某电路的分析,归结为求解线性方程组RI =V 。