当前位置:文档之家› 数值分析报告-二分法和牛顿法方程求根

数值分析报告-二分法和牛顿法方程求根

《数值分析》实验报告一**: **学号: PB********实验一一、实验名称方程求根二、实验目的与要求:通过对二分法和牛顿法作编程练习和上机运算,进一步体会它们在方程求根中的不同特点;比较二者的计算速度和计算精度。

三、实验内容:通过对二分法和牛顿迭代法作编程练习和上机运算,进一步体会它们在方程求根中的不同特点 。

(一)二分法算法:给定区间[a,b],并设f (a )与f (b )符号相反,取δ为根的容许误差,ε为值的容许误差。

(1)令c=(a+b)/2(2)如果(c-a)< δ或)(c f <ε,则输出c ,结束;否则执行(3)(3)如果f(a)f(c)<0,则令)()(,c f b f c b ←←;否则,则令)()(,c f a f c a ←←,重复(1),(2),(3)。

(二)牛顿迭代法:给定初值0x ,ε为根的容许误差,η为)(x f 的容许误差,N 为迭代次数的容许值。

(1)如果)(x f <η或迭代次数大于N ,则算法结束;否则执行(2)。

(2)计算)('/)(0001x f x f x x -=(3)若 < 或 < ,则输出 ,程序结束;否则执行(4)。

(4)令 = ,转向(1)。

四、实验题目与程序设计1、二分法3.1.1、用二分法求方程a. f(x)= x x tan 1--在区间[0,π/2]上的根,c. f(x)=6cos 22-++-x e x x 在区间[1,3]上的根。

源程序:3.1.1.a#include<stdio.h>#include<math.h>void main(){float a,b;double c,y,z;printf("plese input two number a and b:\n");scanf("%f%f",&a,&b);c=(a+b)/2;y=1/c-tan(c);printf("a=%f,b=%f,b-a=%f,c=%f,f(c)=%f\n",a,b,b-a,c,y);while(fabs(b-a)>0.00001|| fabs(y)>0.00001){z=1/a-tan(a);if(z*y<0)b=c;elsea=c;c=(a+b)/2;y=1/c-tan(c);printf("a=%f,b=%f,b-a=%f,c=%f,f(c)=%f\n",a,b,b-a,c,y);}x x 01-ε)(1x f ηx 1x 0x 1}输入0 1.5707563( /2~1.5705563)得到下表:由上表可以看出刚开始时f(c)取值幅度很大,但是经过一段历程之后,幅度变得平缓甚至基本接近与零,我们认为,x=0.8603是方程的根,结果与实际想要得到的值相当接近。

3.1.1 c#include<stdio.h>#include<math.h>void main(){ float a,b;double c,y,z;printf("plese input two number a and b:\n");scanf("%f%f",&a,&b);c=(a+b)/2;y=pow(2,-c)+exp(c)+2*cos(c)-6;printf("a=%f,b=%f,b-a=%f,c=%f,f(c)=%f\n",a,b,b-a,c,y);while(fabs(b-a)>0.00001 || fabs(y)>0.00001){z=pow(2,-a)+exp(a)+2*cos(a)-6;if(z*y<0)b=c;elsea=c;c=(a+b)/2;y=pow(2,-c)+exp(c)+2*cos(c)-6;printf("a=%f,b=%f,b-a=%f,c=%f,f(c)=%f\n",a,b,b-a,c,y);}}输入1 3 ,得到如下表:我们认为,x=1.8294是方程的根。

3.1.4、用二分法求方程04032010958411812467284224494536546362345678=+-+-+-+-x x x x x x x x 在[5.5,6.5]上的根,将-36改为-36.001,并重复试验。

源程序如下:#include<math.h>#include<stdio.h>void main(){float a,b,c,y,z,w;int n=0;printf("plese input two number a and b:\n");scanf("%f%f",&a,&b);c=(a+b)/2;y=pow(c,8)-36*pow(c,7)+546*pow(c,6)-4536*pow(c,5)+22449*pow(c,4)-67284*pow(c,3)+118124*c*c-109584*c+40320;printf(" a b b-a c f(a) f(c) f(b)\n");printf("%f,%f,%f,%f,%f,%f,%f\n",a,b,b-a,c,z,y,w);while(y>0.00001 || c-a>0.00001 ){z=pow(a,8)-36*pow(a,7)+546*pow(a,6)-4536*pow(a,5)+22449*pow(a,4)-67284*pow(a,3 )+118124*a*a-109584*a+40320;w=pow(b,8)-36*pow(b,7)+546*pow(b,6)-4536*pow(b,5)+22449*pow(b,4)-67284*pow(b ,3)+118124*b*b-109584*b+40320;if(z*y<0)b=c;elsea=c;c=(a+b)/2;y=pow(c,8)-36.001*pow(c,7)+546*pow(c,6)-4536*pow(c,5)+22449*pow(c,4)-67284*pow( c,3)+118124*c*c-109584*c+40320;printf("%f,%f,%f,%f,%f,%f,%f\n",a,b,b-a,c,z,y,w);n++;}}输入5.5 6.5 得到下表:我们认为x=6.0000是方程的根。

如果把第二项系数换成36.001,重复以上实验,则得到下表:由于f(a)和f(b)总是同为负数,我们在(5.5,6.5)之间没有找到需要的根,这就说明,当方程中某一个系数相差很小时,方程的根取值可能相差很大。

2、牛顿迭代法3.2.5、用牛顿法求方程011661242234=+-++x x x x 接近0.1的两根。

源程序如下:#include<stdio.h>#include<math.h>void main(){int n=0,M; float x,y,s,t,u,v;printf("plese input x M t and s :\n");scanf("%f%d%f%f",&x,&M,&t,&s);u=2*x*x*x*x+24*x*x*x+61*x*x-16*x+1;v=8*x*x*x+72*x*x+122*x-16;y=x-u/v;printf("N=%d,x=%f,y=%f,|y-x|=%f,f(x)=%f\n",n,x,y,fabs(y-x),u);n++;while(n<=M && fabs(y-x)>t && fabs(u)>s ){x=y;u=2*x*x*x*x+24*x*x*x+61*x*x-16*x+1;v=8*x*x*x+72*x*x+122*x-16;y=x-u/v;printf("N=%d,x=%f,y=%f,|y-x|=%f,f(x)=%f\n",n,x,y,fabs(y-x),u);n++;}}为了能够找到x=0.1附近的两个根,我们不妨取0x =0.0,0x =0.1和0x =0.2两个值尝试一下,分别得到如下的结果:(1)当0x =0.0时,我们认为x=0.1213是方程的根。

x=0.1时,我们认为x=0.1213是方程的根。

(2)当x=0.2时,我们认为x=0.1231是方程的根。

(3)当故方程在x=0.1附近的两根为x=0.1213和x=0.1231。

将这一过程表示在坐标图中:由于方程的两个根和x=0.1比较接近,可以看出,当初值取为0.1时,f(c)的函数最为平缓,这表示此时f (x )最先到达零点;其次,0.2比0.0更加接近于根x=0.1213和x=0.1231,所以初值为0.2的曲线比初值为0.0的曲线更加平缓。

这就说明了,用牛顿法解方程式,应该尽量使初值接近零点,这样能够更节省时间,得到的根更准确。

3.2.14、用牛顿法求解下面两个非线性方程的根a. ⎪⎩⎪⎨⎧=-++=++10101113169195244222y x y x x y y , b. ⎪⎩⎪⎨⎧=+-+=++-0tan 20223x y xy x y e x x3.2.14、a 取⎪⎪⎭⎫ ⎝⎛--++-++=10101113169195244)(222y x y x x y y X F ,则⎪⎪⎭⎫ ⎝⎛-++='1061113384852)(y x y X F ,⎪⎪⎪⎪⎪⎭⎫ ⎝⎛++---+++-+++--++---+++--++-='-=)111x 338)(4y 8()10-y 6(52)10101113169(52)195244)(111338()111x 338)(4y 8()10-y 6(52)10101113169)(4y 8()195244)(10-y 6(F(X))(H 2222221-y x y x x y y x y x y x x y y X F H X X k k +=+)1(,根据牛顿法的思想,其源程序如下:#include<stdio.h>#include<math.h>void main(){float x,y,u,v,s,t;int n=0,M;printf("plese input two number x 、y ,and M:\n");scanf("%f%f%d",&x,&y,&M); printf("%f,%f,%d\n",x,y,M);s=4*y*y+4*y+52*x-19;t=169*x*x+3*y*y+111*x-10*y-10;printf("N=%d,x=%f,y=%f,f1=%f,f2=%f\n",n,x,y,s,t);n++;while(n<=M){u=-((6*y-10)*(4*y*y+4*y+52*x-19)-(8*y+4)*(169*x*x+3*y*y+111*x-10*y-10))/(52*(6*y-10)-(8*y+4)*(338*x+111));v=-(-(338*x+111)*(4*y*y+4*y+52*x-19)+52*(169*x*x+3*y*y+111*x-10*y-10))/(52*(6*y-10)-(8*y+4)*(338*x+111));x=x+u;y=y+v;s=4*y*y+4*y+52*x-19;t=169*x*x+3*y*y+111*x-10*y-10;printf("N=%d,x=%f,y=%f,f1=%f,f2=%f\n",n,x,y,s,t);n++;}}输入初值0 0 10,这里10是指计算次数,得到下表从表中可以知道,方程的根是x=0.1342,y=1.3043,同时,从上表可以发现,在N>4之后,f1(X)和f2(X)基本上等于零,这个接近程度相当低,而且,方程很快能够得到需要的根,这说明牛顿法的效率是相当高的。

相关主题