9.5方程求根的数值试验Word格式文档下载.docx
《9.5方程求根的数值试验Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《9.5方程求根的数值试验Word格式文档下载.docx(10页珍藏版)》请在冰点文库上搜索。
(3)
四数据流向图
恰当选择迭代的初始值
给出其导函数
给出已知其根的简单函数
Y
输出结果
判断是否符合精度要求
对上面的是三种算法分别进行迭代
N
五符号引用
标志符
数学符号
类型
个数
入
出
作用
i
整型
不定
迭代次数
X0/y0/z0
实型
*
初始值、迭代后的值以及最后结果
X1/y1/z1
中间变量
a
1
的值
m
六函数说明
实验中选取了两个简单的函数进行了实验,即:
(1);
则
(2);
函数分别为对进行迭代法,在每一步中都用来代替,每隔一步计算一次公式中的导数的程序。
七流向图
i=0;
根据已经选定的X0/y0/z0,赋值给X1/y1/z1
利用公式(3),计算x0
利用公式
(2),计算x0
利用公式
(1),计算x0
(Ⅲ)
(Ⅱ)
(Ⅰ)
输出,结束
输出误差
八模块和程序
1.迭代模块
do
{
if(i%2==0)
{a=g1(z0);
}
z1=z0;
z0=z1-g(z1)/a;
i++;
cout<
<
"
x"
i<
="
setw(12)<
z0<
'
\t'
误差为:
fabs(z0-4)<
endl;
}
while(fabs(z0-4)>
1e-15);
当迭代次数为偶数时,即i为2的倍数时,计算一次公式的导数的值。
当时,即尚未达精度要求,则需要继续计算,迭代。
2.源程序
#include<
iostream.h>
math.h>
iomanip.h>
floatf(floatx)
{returnx*x-1.0;
}//以函数f(x)=x^2-1为例
floatf1(floaty)
{return2.0*y;
}//函数f(x)=x^2-1的导数为f'
(x)=2*x
floatg(floatm)
{returnsqrt(m)-2.0;
}//以函数f(x)=sqrt(x)-2为例
floatg1(floatn)
{return1.0/(2*sqrt(n));
voidN(floatx0)//用Newton迭代算法
{
floatx1;
inti=0;
cout<
迭代初值为:
x0="
x0<
//输出迭代初始值
do
x1=x0;
x0=x1-f(x1)/f1(x1);
cout<
fabs(x0-1)<
while(fabs(x1-x0)>
voidN1(floaty0)//导数用f'
(x0)来代替
floaty1,a;
a=f1(y0);
//计算出f'
(x0)的值
y0<
f'
(x0)的值为:
a<
do
y1=y0;
y0=y1-f(y1)/a;
fabs(y0-1)<
while(fabs(y1-y0)>
voidN2(floatz0)//每隔一步计算一次导数
floatz1,m;
{m=f1(z0);
z0=z1-f(z1)/m;
fabs(z0-1)<
while(fabs(z0-z1)>
voidG(floatx0)
x0=x1-g(x1)/g1(x1);
fabs(x0-4)<
voidG1(floaty0)
a=g1(y0);
g'
y0=y1-g(y1)/a;
fabs(y0-4)<
voidG2(floatz0)
floatz1,a;
voidmain(void)
一、以函数f(x)=x^2-1为例,已知其根为1,-1。
<
1.1.用Newton迭代算法:
N(0.78);
endl<
1.2.每一步中都用来代替的算法:
N1(0.78);
1.3.每隔一步计算一次公式中的导数的算法:
N2(0.78);
二、以函数f(x)=sqrt(x)-2为例,已知其根为4。
2.1.用Newton迭代算法:
G
(2);
2.2.每一步中都用来代替的算法:
G1
(2);
cout<
2.3.每隔一步计算一次公式中的导数的算法:
G2
(2);
注:
函数N,G基本思路、原理是相同的,只是将函数换了而已,方法简单、易懂,但不够简洁,可以考虑重新编程序,将他们用同一个函数表示出来,而调用时的参数不同来加以区分,这样可以简化程序,减少程序的篇幅。
九结果讨论
1.程序运行结果如下:
(1)开始调试程序时所选取的初值,导致迭代发散:
初值为0.15时,采用(Ⅲ)迭代所得根为-1:
(2)下面是改变出始值之后的结果
函数的计算结果
函数的计算结果
2.结果讨论:
从上面两个函数的例子,比较三种算法所得的结果,可以看出来迭代法和方法(Ⅲ)收敛的速度比较快,而(Ⅱ)的收敛速度相对较慢,达到相同精度的迭代次数要远大于其他两种方法(如二中,迭代法和方法(Ⅲ)的次数分别为4、5,而方法(Ⅱ)需要迭代14次)。
八问题思考与总结
通过编写和调试程序,熟悉了迭代法。
程序中,采用了平时所熟悉的do…while循环,使得程序易于理解,但程序的最后一步,即当结果满足误差的范围时,还会多进行一次迭代。
对于第一个函数,开始时初值的选取不合理,造成了程序迭代的次数比较多,甚至还造成了死循环。
分析后知:
这是因为迭代法的局部收敛性,选取了适当的初值,最终得到了正确的结果同时,在选取初值时,我发现,对上面的,对于方法(Ⅲ),选取初值为0.15时,它与根1更接近,但是在迭代过程中,它恰恰收敛到了-1,但如果选取初值0.78,它收敛到了1。
这也进一步说明,迭代时,需要恰当的选取初值,这对结果的影响比较大。
其次,(Ⅱ)中想通过用来代替,以减少计算量,结果导致计算次数的增加,甚至使本来收敛的初值的迭代变得发散,所以方法不可取,而每隔一步计算一次公式中的导数的算法比较容易让人接受。