当前位置:文档之家› 数值计算(二分法、简单迭代法、Newton迭代法、弦截法(割线法、双点弦法))

数值计算(二分法、简单迭代法、Newton迭代法、弦截法(割线法、双点弦法))

本科生实验报告实验课程数值计算方法学院名称信息科学与技术学院专业名称计算机科学与技术学生姓名学生学号指导教师实验地点实验成绩二〇一六年五月二〇一六年五月实验一非线性方程求根1.1问题描述实验目的:掌握非线性方程求根的基本步骤及方法,。

实验内容:试分别用二分法、简单迭代法、Newton迭代法、弦截法(割线法、双点弦法),求x5-3x3+x-1= 0 在区间 [-8,8]上的全部实根,误差限为10-6。

要求:讨论求解的全过程,对所用算法的局部收敛性,优缺点等作分析及比较,第2章算法思想2.1二分法思想:在函数的单调有根区间内,将有根区间不断的二分,寻找方程的解。

步骤: 1.取中点mid=(x0+x1)/22.若f(mid)=0,则mid为方程的根,否则比较与两端的符号,若与f(x0)异号,则根在[x0,mid]之间,否则在[mid,x1]之间。

3并重复上述步骤,直达达到精度要求,则mid为方程的近似解。

2.2 简单迭代法思想:迭代法是一种逐次逼近的方法,它是固定公式反复校正跟的近似值,使之逐步精确,最后得到精度要求的结果。

步骤:1.构造迭代公式f(x),迭代公式必须是收敛的。

2.计算x1,x1=f(x0).3.判断|x1-x0|是否满足精度要求,如不满足则重复上述步骤。

4.输出x1,即为方程的近似解。

开始输入x0,eX1=f(x0)|x1-x0|<eX1=x0;输出x1结束Noyes f 为迭代函数2.3 Newton 迭代法思想:设r 是的根,选取作为r 的初始近似值,过点做曲线的切线L ,L 的方程为,求出L 与x 轴交点的横坐标,称x 1为r 的一次近似值。

过点做曲线的切线,并求该切线与x 轴交点的横坐标,称为r 的二次近似值。

重复以上过程,得r 的近似值序列,其中,称为r 的次近似值步骤:1.计算原函数的导数f ’(x);构造牛顿迭代公式2.计算 ,若f’(x0)=0,退出计算,否则继续向下迭代。

3.若|x1-x0|满足精度要求,x1即为方程的近似解。

开始输入x0,eX1=x0-f(x0)/f(x1)|x1-x0|<eX1=x0;输出x1结束Noyesf ’(x0)=02.4弦截法思想:为加速收敛,改用两个端点都在变动的弦,用差商替代牛顿迭代公式的导数f’(x)。

步骤: 1.构造双点弦法的公式2.计算x2=x1-f(x1)(x1-x0)/f(x1)-f(x0);3.判断f(x2)是否满足精度要求,若没有则按照上述步骤继续迭代,否则输出x2.x2即为方程的近似解。

第3章测试结果及分析测试结果函数图像函数 Y=x5-3x3+x-1二分法(表1-1,1-2,1-3)[-1.6,-1.3]k xk k xk k xk0 -1.45 5 -1.50156 10 -1.504931 -1.525 6 -1.50391 11 -1.5052 -1.4875 7 -1.50508 12 -1.505043 -1.50625 8 -1.50449 13 -1.505064 -1.49688 9 -1.50479 14 -1.50507表1-1区间[-1.2,-0.9]k xk k xk k xk0 -1.05 5 -0.998437 10 -1.000051 -0.975 6 -1.00078 11 -0.9999762 -1.0125 7 -0.999609 12 -1.000013 -0.99375 8 -1.0002 13 -0.9999944 -1.00312 9 -0.999902 14 -1表1-2区间[1.5,1.8]表1-3简单迭代法(表2-1.2-2.2-3)初值-1.5表2-1初值-1表2-2表2-3牛顿迭代法(表3-1.3-2,3-3)初值-1.5 结果 x=-1.50507表3-1初值-1 结果 x=-1.50507表3-2初值1.6 结果 x=1.69028表3-3双点弦法(表4-1.4-2,4-3)区间[-1.6,-1.3] 结果 x=-1.50507表4-1区间[-1.2,-0.9] 结果 x= -1表4-2区间[1.5,1.8] 结果 x=1.69028表4-3从测试结果可以看出二分法和简单迭代法的收敛速度远大于牛顿迭代和弦截法的收敛速度。

二分法和简单迭代法的公式易于构造和计算,牛顿迭代法虽然收敛高,但要求导数,计算的复杂度高!双点弦法随稍慢于牛顿跌代法,可以用差商代替牛顿迭代法中的导数,降低了计算的复杂度!附录:源程序清单#include<iostream>#include<math.h>using namespace std;double foot =0.3;//定义寻根步长int a=-8,b=8;double*rn=new double[5];//解的区间double*r =new double[5];// 方程近似解int m=0;//根的个数int x_count;double precision=0.000001;//精度要求//函数的表达式(x^5-3x^3+x-1)double f(double x){return(pow(x,5)-3*pow(x,3)+x-1);}void init(){//根据函数图像确定根的区间和迭代初值r[0]=-1.5;r[1]=-1;r[2]=1.6;rn[0]=-1.6;rn[1]=-1.2;rn[2]=1.5;}//寻找根的区间void search(){ //若没有给出区间和初值,进行逐步搜索有根区间for(int i=0;i*foot-8<8;i++){if(f(i*foot-8)*f((i+1)*foot-8)<0){rn[m]=i*foot-8;m++;}}}//=====================二分法==========================double Dichotomy (double a,double b){double mid=0;int i=0;while(fabs(b-a)>precision){mid =(a+b)/2;if(f(a)*f(mid)<=0) b=mid; //判断与端点函数值得符号else a=mid;cout<<mid<<endl;}r[x_count++]=mid;return mid;//返回最终结果}//================简单迭代法=========================//构造迭代公式double fitera(double x){double result=0;double xx=3*pow(x,3)-x+1;if(xx<=0){xx=-xx;return pow(xx,1.0/5.0)*(-1);}elsereturn pow(xx,1.0/5.0);}//简单迭代double itera(double x0){cout<<x0<<endl;double x1=fitera(x0);while(fabs(x1-x0)>precision){x0=x1;x1=fitera(x0); //没有到达精度要求继续迭代cout<<x1<<endl;}return x1;//返回最终结果}//===============牛顿迭代法==================//计算函数的一阶导数fderivatives(double x)double fderivatives(double x){return5*pow(x,4)-9*(x,2)+1;}//构造牛顿迭代公式newtonitera(double x)double newtonitera(double x){if(fderivatives(x)==0)return-1;//若导数为0 则停止迭代elsereturn x-(f(x)/fderivatives(x));}//牛顿迭代double newton(double x0){double x1=newtonitera(x0);while(fabs(x1-x0)>precision){x0=x1;if(newtonitera(x0)==-1)break;x1=newtonitera(x0); //继续迭代cout<<x1<<endl;}return x1;//返回最终结果}//==================双点弦法迭代======================//构造弦截法的迭代公式double twopointchord_f(double x0,double x1){return x1-(f(x1)/(f(x1)-f(x0)))*(x1-x0);}//双点弦法迭代double twopointchord(double x0,double x1){double x3=twopointchord_f(x0,x1);cout<<x3<<endl;while(fabs(f(x3))>precision){cout<<"f(x3)"<<f(x3)<<endl; //输出x3的函数值x0=x1;x1=x3;x3=twopointchord_f(x0,x1); //没有到达精度要求继续迭代// cout<<x3<<endl;}cout<<f(x3)<<endl;return x3;//返回最终结果}//测试void main(){init(); //初始化区间和迭代初值/* 测试代码输出每次的迭代结果和最终结果cout<<"------------------------二分法----------------------"<<endl;for(int i =0;i<3;i++){double result=0;cout<<"有根区间为["<<rn[i]<<" "<<rn[i]+foot<<"]"<<endl;result=Dichotomy(rn[i],rn[i]+foot); //将区间端点带入公式cout<<"求得近似解为"<<result<<endl;}cout<<"------------------------迭代法----------------------"<<endl;for(i =0;i<3;i++){double result=0;cout<<"有根区间为["<<rn[i]<<" "<<rn[i]+foot<<"]"<<endl;double x0 =r[i]; //取得初值result=itera(x0); //带入公式cout<<"求得近似解为"<<result<<endl;}cout<<"------------------------牛顿迭代----------------------"<<endl;for(i =0;i<3;i++){double result=0;cout<<"有根区间为["<<rn[i]<<" "<<rn[i]+foot<<"]"<<endl;double x0 =r[i]; //取得初值result=newton(x0); //带入公式cout<<"求得近似解为"<<result<<endl;}cout<<"------------------------弦截法----------------------"<<endl;for(i =0;i<3;i++){double result=0;cout<<"有根区间为["<<rn[i]<<" "<<rn[i]+foot<<"]"<<endl; result=twopointchord(rn[i],rn[i]+foot); //将区间端点带入公式cout<<"求得近似解为"<<result<<endl;}/*。

相关主题