方程求根:二分法--不动点迭代--牛顿法--弦截法
1.问题概述
首先假定一个初始区间[a,b],函数f(x)=0,在此区间上连续。f(a)*(b)<0,说明在此区间至少存在一个实根。考察有根区间[a,b],取中点x0=(a+b)/2将它划分为两半,然后进行根的搜索,即检查f(x0)与f(a)是否同号;如果确系同号,说明所求的根x在x0的右侧,这时令a1=x0,b1=b;否则x必在x0的左侧,这时令a1=a,b1=x0(如图2-1所示)。不管出现哪一种情形,新的有根区间[a1,b1]的长度仅为[a,b]的一半,通过一步一步的二分操作,逐步靠经精确解。由于这是粗略的估计,最终很难得到一个准确解,所以只能求出一个靠近真实解的,所以我们应该在求解的开始时候确定一个误差,当迭代n次过后满足 |x-xn|<=误差 。同时我们可以求出迭代次数n=⌈log2((b-a)/2*误差)⌉
int n = ceil(log2(b - a) - log2(2 * atol)); for (int i = 0; i<n; i++) { middle = (a + b) / 2; fm = f(middle); if ((fl*fm) <= 0) { b = middle; fr = f(b); } else { a = middle; fl = f(a); } }
求实根最简单有效的方法:二分法。易于在计算机上实现,且对于函数f(x)的性质要求不高,仅仅要求它在有根区间上连续,且区间端点的函数值异号即可。它的缺点是不能求偶数重根,也不能求复根,收敛速度与以1/2为公比的等比数列相同,不算太快,因此一般在求方程近似根时,不太单独使用,常用它来为其他方法求方程近似根提供好的初值区间(重要:初值区间的确定直接决定求解的速度)。
2.不动点迭代(Fixed Point Iteration)将所求的非线性方程 f(x)=0 化为一个同解方程: x=g(x) 同时g(x)为连续函数
首先,取一初始值x0代入上式,得到:
x1=g(x0)x2=g(x1)… …xk+1=g(xk) k=0,1,2,… …n次迭代满足精度要求,此方法为简单的非线性迭代法。
注意:选取g(x)时,应当首先确定是否在取值区间收敛,否则不能求出根。
double x1 = x0 - f(x0) / f1(x0); while (abs(x1 - x0)>0.0001) { x0 = x1; x1 = x0 - f(x0) / f1(x0); }
最易于理解的方法:迭代法。对于迭代法,构造合适的迭代函数g(x)至关重要,它影响着迭代数列的收敛性(重要)。而且若要使不动点迭代收敛,则要求g(x)在区间[a,b]上的函数值也在此区间内,因此对初值的要求较高,需要提供较为近似的初始值x0.大多数情况下需要考虑迭代法的局部收敛性,在方成根的附近取初值。
3.牛顿法(Newton’s Method)考察一般形式的函数方程f(x)=0,首先运用校正技术建立迭代公式,设已知它的近似根xk,则自然要求校正值x(k+1)=xk+∆x能更好的满足所给方程,即f(xk+∆x)≈0,
将其左端用线性主部f(xk)+f’(xk)* ∆x代替,而令
f(xk)+f’(xk)*∆x=0
这是关于增量∆x的线性方程,据此定出∆x=-f(xk)/f’(xk)
从而关于校正值x(k+1)=xk+∆x有如下计算公式:
X(k+1)=xk-f(xk)/f’(xk)
这就是著名的牛顿公式。Newton法的突出优点是速度快,但它有个明显的缺点是每一步迭代需要提供导数值f’(xk),如果函数f(x)比较复杂,致使导数的计算比较困难,那么使用牛顿公式是不方便的。
while (abs(x1 - x0)>0.0001) { x0 = x1; x1 = x0 - f(x0) / f1(x0); }
通常最高效的方法:牛顿法。它是求解方程f(x)=0的一种重要方法,它的最大优点是方程在单根附近具有较高的收敛速度,且算法逻辑简单。它还可以用于求代数方程的重根、复根。但是由于牛顿法是局部收敛的,它的收敛性依赖于初值x0的选取。并且每一步迭代除了需要计算f(Xk)外,还需要计算f(Xk)的导数,当f(x)比较复杂时(缺点明显),该方法是不方便的。
4.弦截法(Secant Method)设f(x)在某个范围内改变不大,近似取某个定值M,即
f’(x)≈M那么,牛顿公式中的导数值可以用定数M来近似的取代,而将其简化成迭代公式
X(k+1)=Xk-f(Xk)/M这种简化的牛顿方法也称作平行线法,其几何意义是:用一族平行线取代切线逼近所求的根x.该方法形式简单,但其收敛性往往不能保证,因而实用价值不大.
为避开导数的计算,也可用差商(f(Xk)-f(X0))/(Xk-X0)替换牛顿公式中的导数f’(X0),得到以下离散化形式:
X(k+1)=Xk-f(Xk)/( f(Xk)- f(X0))*(Xk=X0) (1)容易看出,该公式是根据f(x)=0的等价形式
X=X-f(X)*(Xk-X0)/(f(X)- f(X0))![]()
迭代公式的几何解释如图所示,记曲线y=f(x)上横坐标为Xk的点为Pk,则差商(f(Xk)-f(X0))/(Xk-X0)表示弦线P0Pk的斜率.容易看出,按照式(1)求得的X(k+1)实际上是弦线P0Pk与x轴的交点,因此这种方法称作弦截法。
while (abs(x2 - x1) > 0.001) { x0 = x1; x1 = x2; x2 = x1 - (f(x1)*(x1 - x0)) / (f(x1) - f(x0)); }
避开复杂运算的方法:弦截法。它避开了导数计算,但在收敛方面付出了不可低估的代价。弦截法是局部收敛的,仅有线性收敛速度,收敛速度比牛顿法慢,不用求导是它的优势(优点突出)。
End