E N D
计算方法作业 组员: 胡明东 U200715272 王云龙 U200715229 朱良 U200715360 盛孟 U200715281 王川 U200715272 韩飞 U200715272 陈东亮 U200715272 万远收 U200715272 班级: 土木0702班
题目一.在[0,4]上求解exp(-x^2)=cos(x)+1的根 方法一:newton法 • 因为f(x)= exp(-x^2)-cos(x)-1 • f(X)’=-2x*exp (-x^2)+sin(x) • 所以 • xk+1=xk-f(xk)/f(xk)’ • 画图编程求解
#include <stdio.h> #include <math.h> void main() { float x2,x1,x0; int i; x0=0; x1=x0-(exp(-x0*x0)-cos(x0)-1)/(-2*x0*exp(-x0*x0)+sin(x0)); x2=x0; x0=x1; printf("i=0 x0=1 x1=%f\n",x1); for(i=1;fabs(x1-x2)>0.000002;i++) { x1=x0-(exp(-x0*x0)-cos(x0)-1)/(-2*x0*exp(-x0*x0)+sin(x0)); x2=x0; x0=x1; printf("i=%d x%d=%f x%d=%f\n",i,i,x2,i+1,x1); } } 程序
结果分析 • 当x=0时,f(x)’=0,会出现乱码 • 当x=1时,求的此方程的另一个根 • 当x=2时,才求得在区间[0,4]内的根
方法二:割线法 分析:割线法newton法中的f’(x)用 来代替。它是割线的斜率。而newton法中实际上是切线斜率。这种方法需要两个初值。 它的收敛速度要比newton法慢 。
程序 #include <stdio.h> #include <math.h> #define A 1e-5 float f(float x) { return exp(-x*x)-cos(x)-1; } void main() { float a,x0=0.0,x1=4.0; int n=0; while (fabs(x0-x1)>A) { a=x1; x1=x0-f(x0)*(x0-x1)/(f(x0)-f(x1)); n++; printf("\nx%d=%f",n,x1); x0=a; } }
第二题 取x0=2和x1=1。利用newton法,割线法,迭代法和艾特肯法求上面方程的根。
Matlab 绘制的图形 ,可知根的大致区间在1到2之间。
Newton法 • 分析:如函数的图像所示:根在1到2 之间。使用Newton法,取x=2作为初值。收敛至x(k)与x(k+1)的差别满足精度要求即可求出它的根。 • Newton法是收敛速度较快的方法。
#include <stdio.h> #include <math.h> #define A 1e-5 float f(float x) { return x*x*x+2*x*x+10*x-20; } float d(float x) { return 3*x*x+4*x+10; } void main() { float x0,x1=2.0; int n=0; while (fabs(x0-x1)>A) { x0=x1; x1=x0-f(x0)/d(x0); n++; printf("\nx%d=%f",n,x1); } } 程序代码
割线法 • 分析:割线法newton法中的f’(x)用 来代替。它是割线的斜率。而newton法中实际上是切线斜率。这种方法需要两个初值。 它的收敛速度要比newton法慢 。
程序代码 • #include <stdio.h> • #include <math.h> • #define A 1e-5 • float f(float x) • { • return x*x*x+2*x*x+10*x-20; • } • void main() • { • float a,x0=2.0,x1=1.0; • int n=0; • while (fabs(x0-x1)>A) • { • a=x1; • x1=x0-f(x0)*(x0-x1)/(f(x0)-f(x1)); • n++; • printf("\nx%d=%f",n,x1); • x0=a; • } • }
迭代法 • 分析:用迭代法,本题可构造多种不同的迭代公式。找出一种在x=1.5(由图形判断)收敛且速度较快的: 对右边函数求导 取绝对值>1 发散 对右边函数求导 去绝对值>1 发散 对右边求导 取绝对值>1 发散
三者都发散:说明想要通过规整的移项来构造迭代公式行不通。从而要拆开一些项进行移项构造。经过尝试,得到这样一个方程是收敛的(仍然是取x=1.5):三者都发散:说明想要通过规整的移项来构造迭代公式行不通。从而要拆开一些项进行移项构造。经过尝试,得到这样一个方程是收敛的(仍然是取x=1.5): 收敛。根据此方程编程求解
程序代码 • #include <stdio.h> • #include <math.h> • #define A 1e-5 • float f(float x) • { • return sqrt((x*x*x-4*x*x+10*x-20)/(-6)); • } • void main() • { • float x0=1.5,a=0.0,x1; • int n=0; • while (fabs(x0-a)>A) • { • a=x0; • x1=f(x0); • x0=x1; • n++; • printf("\nx%d=%f",n,x1); • } • }
该法与前两种方法比较速度明显要慢。可能由于方程的选取仍然不是最优化的。还有其它收敛速度更快的方程。该法与前两种方法比较速度明显要慢。可能由于方程的选取仍然不是最优化的。还有其它收敛速度更快的方程。
艾特肯法 校正 再校正 改进 虽然这个方程在迭代法中是发散的。但是可以对这个发散的方程建立艾特肯迭代公式进行校正和改进如上。
#include <stdio.h> • #include <math.h> • #define A 1e-5 • float f(float x) • { • return (20-x*x*x-2*x*x)/10; • } • void main() • { • float x0=2.0,x1,x2,x=0.0,b=1.0; • int n=0; • while (fabs(b-x)>A) • { • b=x; • x1=f(x0); • x2=f(x1); • x=x2-pow(x2-x1,2)/(x2-2*x1+x0); • n++; • x0=x; • printf("\nx%d=%f",n,x); • } • } 程序代码