c语言计算机编程三种方法求解非线性方程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
本科专业学年论文题目:非线性方程求解比较
姓名:何娟
专业:计算机科学技术系
班级:08级本科(2)班
指导老师:刘晓娜
完成日期:2010年11 月21 日
题 目:非线性方程求解比较
摘 要
本文给出了三种求解非线性方程的方法,分别是二分法,牛顿迭代法,割弦法。
二分法巧妙地利用插值得到的点以及有根区间中点这两点处的函数值,缩小隔根区间,以期望得到更快的收敛速度。
牛顿迭代法是非线性方程根的一种常见的数值方法,对于非线性方程的单重零点来说,牛顿迭代法一般具有局部二阶收敛性,但是当所求的根X*是F(X)的M 重根时,M 是大于等于2的整数,此时牛顿迭代法只有一阶收敛性。
弦截法是将牛顿迭代公式中用差商F(k x )-F(1-k x )/ (k x - 1-k x )代替导数'()k F x 。
本文给出了算法改进的具体步骤及算法流程图相关的数值结果也说明了方法的有效性。
关 键 词 : 二分法;牛顿迭代法;割弦法;非线性方程
目录
第一章绪论- 3 -
第二章求解非线性方程的三种常见算法……………………………- 4
-
2.1 二分法………………………………………………………-
4 -
2.2 牛顿迭代法……………………………………………………- 5 -
2.3 割弦法- 6 -
第三章求解非线性方程的三种算法比较- 8 -
3.1 二分法求解方法- 8 -
3.2 牛顿迭代法求解- 10 -
3.3 割弦法求解- 11 -
参考文献- 14 -
第一章绪论
在科技飞速发展的今天,计算机已经成为我们生活中不可缺少的一部分了,在我们生活与生产中扮演越来越重要的角色,而科学计算已经成为科学计算的重要方法之一,其应用范围已渗透到所有科学领域,作为科学与工程计算的数学工具,计算方法已成为高等院校数学与应用数学,信息与计算科学,应用物理学等必修课。
在永恒变化发展的自然界与人类社会中,在研究其内部规律的各个科学领域中,更深刻、更精确地描述其内部规律的数学工具之一,就是非线性方程。
非线性代数是研究大规模离散数据的运算处理与内在性状的数学科学,科学技术离不开数据处理与数据分析,因此非线性代数具有广泛的应用。
无论在物理学、力学、化学、控制论等科学领域中,非线性方程屡见不鲜。
就是在生命科学领域中,也是用非线性方程来描述生命过程中的能量、信息、物质等传递过程的。
因此,对非线性方程的求解自然就是一个非常重要了。
然而求解非线性方程有很多种方法,每种方法都有自己的优缺点。
目前已有的数学软件可以帮助我们实现上机计算,基本上已经将数值分析的主要内容设计成简单的函数,只要调用这些函数进行运算便可得到数值结果。
非线性代数中许多数值计算与计算机结合,才能得到更很好,更快,更精准的结果。
为了将计算机与线性代数方程组更好的结合在一起,本文做了比较全面的的解说。
本文比较全面的介绍了现代计算机科学与工程计算中常见的数值计算方法,对这些数值计算方法的基本理论与实际计算机实践应用进行了详细的分析,同时还简要的分析了这些数值算法的计算效果,稳定性,收敛效果,适用范围以及优劣性与特点。
本文着重于化抽象为具体,引用一个具体的非线性方程用发散性的思维对其进行彻底的分析,主要有:
①引入一个非线性方程,分别运用三种思想进行分析,得到三种解法的根本思想;
②把数学方法与数学思想提出来,并进行简洁易懂的理论证明,既突出了线性代数的理论和基本思想,又可以帮助读者对该数学方法的理解;
③给出各种算法的循环思想以及流程图,展现出一个清新的框架在读者面前;
④基于c语言的基础上,写出可执行的代码。
⑤对各种算法得到的结果进行比较分析。
第二章 求解非线性方程的三种常见算法
2.1 二分法
单变量函数方程:
f (x )=0
其中,f(x)在闭区间[a ,b]上连续、单调,且f(a)*f(b)<0,则有函数的介值定理可知,方程f (x )=0在(a ,b )区间内有且只有一个解*x ,二分法是通过函数在区间端点的符号来确定*x 所在区域,将有根区间缩小到充分小,从而可以求出满足给定精度的根*x 的近似值。
下面研究二分法的几何意义:
设1a =1, 1b =b, 区间[]11,b a ,中点1x = 211b a +及()1x f ,若()1x f =0,则*x =1x ,若 f(1a )*f(1x )<0,令2a =1a ,2b =1x ,则根*x ∈ [2a ,2b ]中,这样就得到长度缩小一半的有根区间[2a ,2b ],若 f(1b )*f(1x )<0,令2a =1x ,2b =1b ,则根*x ∈ [2a ,2b ]中,这样就得到长度缩小一半的有根区间[2a ,2b ],即f(2a )f(2b )<0,此时
2b -2a =2
11a b -,对有根区间[2a ,2b ]重复上述步骤,即分半求中点,判断中电处符号,则可得长度有缩小一半的有根区间[2a ,2b ],
如图所示:
重复上述过程,第n 步就得到根*x 的近似序列{}n x 及包含*x 的区间套,如下:
(1)...],....[],[],[2211⊃⊃⊃n n b a b a b a
(2)],[,0)()(*n n n n b a x b f a f ∈<
(3)n a -n b =)
(1121---n n b a =…=12--n a b (4) ,2n n n b a x +=且|*x -n x |≤12
--n a b (n=1,2,3…..) 显然lim n x ,且n x 以等比数列的收敛速度收敛于*x ,因此用二分法求f (x )=0的实根*x 可以达到任意指定精度。
2.2 牛顿迭代法
设方程f(x)=0在其根*x 的某个领域U(*x ,δ)内有一阶连续导数,且f’(*x ) ≠0。
求f(x)=0的根*x ,首先要将f(x)=0转化为等价形式()x x ϕ=,并使ϕ (x)满足不动点迭代的一般理论。
于是我们令ϕ (x)=x+h(x)f(x),可由ϕ ‘(1x )=0来确定h(x)的结构,根据ϕ’(x)=1+h ’(*x )f(*x )+h(*x )f’(x1)=1+h(*x )f’(*x )=0可得
h(*x )=-1/f’(*x ) ,由于f’(x) ≠0,且f’(x) 连续,因此当h(x)=-1/f’(x) 时, h ’(x1)=0,即令ϕ (x)=x-f(x)/f‘(x), 从而有迭代格式
1+k x = )
(')(k k k x f x f x - (k=0,1,2,…..) 由于1x , 2x , 3x …….都在U 领域里,从而当B 比较小时,可用f’(0x )可近似代替f’(k x ),1+k x = k x - )
()(0x f x f k ,此方法称为牛顿迭代法 下面研究牛顿法的几何意义:
设r 是方程f (x )=0的根,选取0x 作为的r 初始近似值,经过(0x ,f(0x ))做曲线y=f(x)的切线的方程:y=f(0x )+f’(0x )(x- 0x ),求出L 与x 的交点的横坐标1x = 0x -f(0x )/f’(0x ),称1x 为r 的一次近似值经过点(1x ,f(1x ))做切线y=f(x)的切线,并求出该切线与x 轴的交点横坐标:2x = 1x -f(1x )/f’(1x ),2x 称为r 的二次近似值,重复以上操作可以得到r 的近似值序列。
下述三个定理分别讨论了牛顿法的收敛性质:
定理1:对于方程f(x)=0,设f (x )在[a ,b]上有二阶连续导数且满足下述条件:
(1)f(a)f(b)<0;
(2)f’(x) ≠0, )(x f ''≠0,对任意的x ∈[a,b];
(3)存在0x ∈[a,b],使f (0x ))(0x f ''>0,
则由牛顿法产生的迭代序列{}n x 收敛于f(x)=0的根*x ,且
)
(2)()(**2**1lim
x f x f x x x x k k k '''=--+∞→ 定理2:对于方程f(x)=0,设f (x )在[a ,b]上有二阶连续导数且满足下述条件:
(1)f(a)f(b)<0;
(2)对任意的x ∈[a,b], f’(x) ≠0, )(x f ''≠0
(3)
)
()(a f a f '<b-a, )()(b f b f '<b-a
则对于任何0x ∈[a,b],由牛顿法产生的迭代序列{}n x 收敛于f(x)=0的根*x
定理 3:设*x 是方程f(x)=0的根,在*x 的某个开区间内)(x f ''连续且f’(x) ≠0,则存在δ>0,当0x ∈【*x δ-,*x +δ】时,由牛顿迭代法1+k x = )
(')(k k k x f x f x - (k=0,1,2,…..)式产生的序列{}n x 是以不低于二阶的收敛速度收敛到*x .
2.3 割弦法
设k x ,1-k x 为方程f(x)=0的两个近似根。
用差商得:f(k x )-f(1-k x )/ k x - 1-k x , 代替牛顿迭代公式中的导数 f’(k x ), 于是得到如下的迭代公式:
1+k x =k x -)()
()()(11----k k k k k x x x f x f x f 。
下面研究割弦法的几何意义: 经过点(k x ,f(k x ))及点(1-k x ,f(1-k x ))两点作割线,其点斜式方程为:
Y=f (k x )- )()()(11k k k k k x x x x x f x f -----,其零点为X=k x - )()
()()(11----k k k k k x x x f x f x f 把X 用1+k x 表示即得到迭代格式,它又称为双点弦割法,需要两个初值
此割线与 X 轴交点的横坐标就是新的近似值1-k x ,所以弦截法又称为割线法,如图所示。
下面三个定理为弦割法收敛定理:
定理1:设f (x )在其零点*x 的邻域U (*x ,δ)= [*x -δ, *x +δ] ( δ>0)内有二阶连续导数,0)(*≠'x f ,则当0x ∈U (*x ,δ)时,由割弦法式产生的序列{}n x 收敛于*x ,且收敛的阶为1.618。
定理2:设)(x f ''在区间[a,b] 上连续,且满足下述三点
(1)f(a)f(b)<0;
(2)对任意的x ∈[a,b], 有f’(x) ≠0, )(x f ''≠0
(3))
()(a f a f '≤b-a, )()(b f b f '≤b-a 则对于任意初始0x ,1x ∈[a,b],由弦割法产生的迭代序列{}n x 收敛于f(x)=0唯一的根*x
定理 3:设在其零点*x 的邻域U(*x ,δ)=[*x -δ, *x +δ](δ>0)内有二阶连续导数,f’(x) ≠0则当0x ∈ U(*x ,δ)时,由弦割1+k x =k x -
)()
()()(11----k k k k k x x x f x f x f 式产生的序列{}n x 收敛于*x ,且收敛的阶为1.618。
第三章 求解非线性方程的三种算法比较
本章主要通过具体实例比较了第二章中三种算法的优缺点,并得到相应 结论,求解非线性方程 x*x*x+4*x*x-10=0 在[1,2]上,x0=1.5附近的解精确到0.000 000 001。
3.1 二分法求解方法
二分法是求方程近似根的方法中行之有效的最简单的方法,它的递推过程简单,便于计算机上实现,实现二分法的基本步骤如下。
(1) 输入有根区间的端点 a,b 及预先给定的精度 exp ;
(2) 计算x=(a+b)/2 ;
(3) 若 f(a)*f(x)<0,则b=x ;否则a=x ;
(4) 若 |b-a|<exp ,则输出方程满足精度要求的根x ,
则计算结束;否则转(2)。
二分法算法流程图:
c 语言代码:
#include "stdio.h"
#include "math.h"
float function(float x)
{
float f;
f=(float) x*x*x+4*x*x-10;
return f;
}
void main()
{
float 1x ,2x , 0x ,f 1x ,f 2x ,f 0x ; 1x =10;x2=-10;
f(1x )=function(1x );
f(2x )=function(2x );
do
{
0x =(1x +2x )/2; /*计算中点*/
f(0x )=function(0x ); /*计算中点处的函数值*/
if(f(0x )*f(1x )<0) /*计算新的区间*/
{ /*区间中点的函数值与1x 的函数值正负号相反*/
/*区间中点的y坐标与1x 点的y坐标在不同y半轴上*/
2x =0x ; /*新区间为[1x , 0x ]*/
f(2x )= f(0x );
}
else
{ /*区间中点的y坐标与1x 点的y坐标在相同y半轴上*/
1x =0x ; /*新区间为[x0, 2x ]*/
f(1x )=f(0x );
}
}while(fabs(f 0x )>=1e-6);
printf("The root is %f",0x );
}
运行结果:
n 有根区间[a,b] n x
f(n x )的符号 1 [1.0,2.0] 1.5
+ 2 [1.0,1.5] 1.25
_ 3 [1.25,1.5] 1.375
+ 4 [1.25,1.375] 1.3125
_ 5 [1.3125,1.375] 1.343 75
_ 6 [1.3475,1.375] 1.359 375
_ 7 [1.359375,1.375] 1.367 185
+
The root is 1.365230
3.2 牛顿迭代法求解 步骤:
(1) 给出初始近似根 0x 及精度exp ;
(2) 计算1x =0x -f(0x )/f’(0x ) ;
(3) 若 |1x -0x |<0 ,转向(4);否则 0x =1x ,转向(2);
(4) 输出满足精度的根1x ,结束。
算法流程图:
c 语言代码: #include "stdio.h" #include "math.h" float function(float x) {
float f;
f= x*x*x+4*x*x-10; return f; }
float derivative(float x) {
float f; f= 2x+8; return f; }
void main() {
float x, 0x ,fx,f;
x=1.5; do {
0x =x;
fx=function(0x ); f=derivative(x); x=0x -fx/f;
}while(fabs(x-0x )>=1e-6); printf("The root is %f",0x ); }
运行结果:
The root is 1.365231
3.3 割弦法求解 步骤:
(1) 选择迭代初值 0x ,1x 及精度 esp ;
(2) 计算 2x =1x -(f(1x ) *(1x -0x )/ f(1x )-f(0x )); (3) 若|2x -1x |<0,转向(4);否则 0x =1x ,1x =2x ,转向(2); (4) 输出满足精度的根 2x ,结束 算法流程图:
c 语言代码: #include <stdio.h> #include <math.h>
#define eps 0.00001 /* 容许误差 */ #define N 100 /* 最大迭代次数N */ float f(float x) /* 定义函数f(x) */ { float y;
y= x*x*x+4*x*x-10; return(y); }
void main() { float 0x ,x1, 2x ; int i;
printf("input 0x ,1x ="); scanf("%f,%f",&0x ,&1x ); for(i=1;i<=N;i++)
{ 2x =1x -(f(1x )*(1x -0x ))/(f(1x )-f(0x )); /* 弦截法迭代公式 */
if(fabs(2x -1x )<eps || fabs(f(2x ))<eps) /*满足精度要求输出近似根并退出*/ { printf("\nRoot of equation is:%8.6f\n",2x ); return; }
0x =1x ; /* 准备下一次迭代的初值 */ 1x =2x ;
}
printf("\nAfter %d repeat, no solved.\n",N); /* 输出无解信息 */ }
运行结果: K k x
f(k x )
0 1.0 -5.0 1 2.0
14.0
2 1.26
3 157 895 -1.60227
4 384 3 1.338 827 839 -0.430 364 744 4 1.366 616 39
5 -0.022 909 427
5
1.365 211 903
-2.990 671*pow(10,-4)
6 1.365 200 01 -2.0416*pow(10,-7)
7 1.365 230 013 0.0
8 1.365 230 013 0.0
Root of equation is: 1.365230 小结:
二分法的优点是计算简单,方法可靠,误差容易估计,只要求连续,且总是收敛的,因此对函数的性质要求较低。
它的缺点是不能求偶数重根,也不能求复根,且收敛较慢。
故一般不单独将其用于求根,只用其为根求得一个较好的近似值。
牛顿迭代法是多项式求根的一种效率很高的算法,收敛速度快(对单根)。
算法简单是迭代法中较好者,但是它有两个缺点:第一每次只能求出一个ε-根,求其它根时若采用降次处理又会产生精度降低的问题。
第二有时会遇到由于初始点选择不当而使算法失效。
,牛法和割弦法都是先将f(x)线性化,然后求根,但线性化的方式不同:从分析的角度说,牛顿法是在根 *x 邻近点处的切线函数作为f(x)的近似,而割弦法是在*x 邻近用f(x)的一次插值函数作为f (x)的近似函数,它们本质的区别在于,牛顿迭代法在计算1+k x 时,只用到前一步的值k x ,弦截法需要用两个猜测值1-k x ,k x ,因此使用这种方法必须先给出两个初始值1x , 0x 。
根据以上三种方法的优缺点,我们在使用非线性方程求根时,应根据实际方程选出一种或者多种方法进行综合求解,以便快速,便捷的求出最佳精确值。
参考文献
[1] 郭曦娟,Jacobi和Gauss-Seidel迭代法收敛性的判定【J】,东北重型机械学院学报,1995:19(1)。
[2] 郝福华,侯建强,孟晋忠,迭代法在编程中的应用【J】,山西水利科技,1995:109(5)。
[3] 赵艳霞,非线性方程求根的迭代法研究【J】,鸡西大学学报。
2008:8(2)。
[4] 黄忆潭,王德明,割线法向牛顿法德过度格式【J】,哈尔滨工业大学学报,1995:27(4)。
[5] 吴新元,解非线性方程的二阶收敛指数迭代法【J】,计算方法,1998:20(4)。
[6] 程小力,牛顿法的收敛性【J】,浙江工业大学学报,1997:25(3)。
[7] 倪攸颖,求解非线性方程的一种半隐式迭代法【J】,哈尔滨理工大学学报,1998:3(2)。
[8] 高虹倪,曹泽阳,一种新的非线性方法的求根迭代法【J】,空军工程大学学报,2002:3(2)。