非线性方程迭代解法实验报告Word格式文档下载.docx
《非线性方程迭代解法实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《非线性方程迭代解法实验报告Word格式文档下载.docx(10页珍藏版)》请在冰豆网上搜索。
Newton下山法;
求方程在指定区间上的全部实根.准确到8位有效数字。
(2).在
(1).的基础上讨论迭代法的加速(选作)
2.实验内容
(1)对以上非线性方程,分析、设计算法,确定有根区间,进行根的隔离;
(2)在选取的单根区间内,编程实现用不同方法,分别求根;
(编写通用过程或函数);
(3)对所用算法的收敛阶、局部收敛性、优缺点和精度等作分析及比较.并附运算结果的截图(可用Excel图表或其他绘图软件工具对实验结果分析);
(4)以实验报告的形式提交总结;
(5)学生在完成本实验后,提交实验报告、程序源代码、程序可执行文件以及程序使用说明等压缩文档。
一、开发环境
PC机一台PC微机
Windows操作系统
MicrosoftVisualStudio8.0集成开发环境
二、模型建立(或算法简述)
1.首先是求函数的根区间:
求根区间采用割分小区间的方法,然后求每个区间点的函数值,当fx(x1)*fx(x2)<
0时,方程在此区间必定有一个函数。
在求区间点的函数时,如果有fx(x)=0的情况,那么这个点就是方程的解,可以直接就求出方程的根了。
当根的区间全部求出来后,(x1+x2)/2作为初始值来求解方程。
2.牛顿迭代解法:
FXk+1=Xk-F(X)/F(x)'
。
将初始值代入方程,看条件|FXk+1-FXk|<
e,如果成立,则停止运算,输出结果。
3.牛顿简化迭代:
用F(X0)'
代替F(Xk),运算时不必每次都求道数值。
4.弦割法:
5.下山法:
求下山因子时,根据条件,
,。
三、模型求解
3.1程序设计(方案)说明
根据上面模型,设计了四个函数:
1.是求根区间函数,求得的根区间和根,用一个数组记录下来,设计两个记录变量来记录根和跟区间个数。
2.是求方程数值函数,求根区间和求解都要用到。
3.是求导数值函数,当用牛顿迭代时用到。
4.是求下山因子函数,当用下山法时用到。
3.2源代码(关键代码要有注释)
非线性方程迭代解法的程序代码:
#include"
stdio.h"
stdlib.h"
stdafx.h"
math.h"
#defineN10
intrt=0;
//设置根区间个数全局变量
integg=0;
//设置求根区间时直接得到的根的个数全局变量
intk=0;
//根个数
doubleax[N];
//求得结果
doublec[N];
//记录根区间和根
doubleer=0.00000001;
//精确度
doublea[N]={-1,1,0,-3,0,1};
//方程为x^5-3x^3+x-1=0;
doublegetfx(doublex)//求数值函数
{
doublefx;
fx=a[5]*x*x*x*x*x+a[3]*x*x*x+a[1]*x+a[0];
returnfx;
}
doublegetfxl(doubleb[N],doublex)//求导数值函数
doublefxl;
fxl=b[4]*x*x*x*x+b[2]*x*x+b[0];
returnfxl;
voidroot(doubleq1,doubleq2)//求根区间
{
doublefx,fx0;
fx0=0;
doublem0,m1;
doublex;
doubled;
inti,j,l;
d=(q2-q1)/160;
for(i=0,j=9,l=0;
i<
161;
i++)
{
m1=q1+d*i;
x=m1;
fx=getfx(x);
if(fx==0)//直接求得根
{
c[j]=m1;
//记录根
j--;
egg=egg+1;
}
if(fx*fx0<
0)//是否满足有根条件
c[l]=m0;
c[l+1]=m1;
//记录有根区间
rt++;
//记录个数
l=l+2;
m0=m1;
fx0=fx;
//保留上一次的值
}
c[N];
doublegetyz(inti)//求下山因子函数
{
intj;
doublex1,x2;
x2=1;
x1=0.5;
for(j=1;
j<
i;
j++)
x2=x2*x1;
returnx2;
}
voidmain()
doubleb[N];
doubled[N];
doublex0,x1,x2,xj;
inti,j,l,h;
for(i=0,j=1;
5;
i++,j++)//求导
b[i]=a[j]*j;
doubleq1=-8,q2=8;
//有根区间=为[-8,8]
root(q1,q2);
c[N];
if(egg)//求根区间时,如果f(x)=0,可直接得到根
printf("
求根区间时,直接求得了%d个根,分别为:
\n"
egg);
i=egg;
for(j=9;
i>
0;
i--,j--)
ax[k]=c[j];
printf("
ax%d=%lf\n"
k+1,ax[k]);
//输出根
k++;
//记录根个数
if(rt)//是否求得所有根区间
求得了%d个根区间,分别为:
rt);
for(i=0;
rt;
d[2*i]=c[2*i];
d[2*i+1]=c[2*i+1];
[%lf,%lf]\n"
d[2*i],d[2*i+1]);
else
没有求得根区间,程序终止:
for(i=rt,l=0;
i--,l++)
x1=(d[2*l]+d[2*l+1])/2;
//求初始值
//x0=x1;
xj=getfxl(b,x0);
//牛顿简化
x0=x1;
x1=x0+0.1;
//弦割
for(j=0;
20;
j++)//最多迭代次
//x2=x1-getfx(x1)/getfxl(b,x1);
//牛顿
//x2=x1-getfx(x1)/xj;
for(h=1,x2=x1-getfx(x1)/getfxl(b,x1)*getyz(h);
fabs(getfx(x2))>
fabs(getfx(x1));
h++)
x2=x1-getfx(x1)/getfxl(b,x1)*getyz(h);
if(fabs(x2-x1)<
er)break;
x1=x2;
ax[k]=x2;
//printf("
用%d次牛顿迭代求得一个根,值为:
j);
//迭代次数
用%d次牛顿简化迭代求得一个根,值为:
//sprintf("
用%d次弦割迭代求得一个根,值为:
printf("
用%d次下山迭代求得一个根,值为:
//下山
ax%d=%.9lf\n"
k++;
getchar();
3.3模型的解(含运行结果截图)
图1:
牛顿迭代
简化牛顿迭代
图3:
弦割法
图4:
下山法
3.4结果分析
用牛顿迭代解法的收敛速度最快,求解的时候分别只用4次和3
指导教师批阅意见:
成绩评定:
指导教师签字:
年月日
备注: