购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.5 求解方程

许多数学问题最终都会归结为求解形式为 f ( x )=0的方程,其中 f 是单变量函数。在这里,我们试图找到一个使方程成立的 x 值。使方程成立的 x 值有时称为方程的根。有许多算法可以找到这种形式的方程的解。在本例中,我们将使用牛顿法和割线法(secant method)求解形为 f ( x )=0的方程。

牛顿法和割线法是很好的标准求根算法,几乎适用于任何情况。它们都是迭代法,从根的近似值开始,迭代改进该近似值,直到它落在给定的容差范围内。

为了演示这些技术,我们将使用SymPy中的符号微分和积分函数,该函数由以下公式定义:

f ( x ) = ( x 2 -2 x )exp(3- x )

这个定义适用于 x 的所有实数值,并且正好有两个根,一个在 x= 0处,另一个在 x= 2处。

3.5.1 准备工作

SciPy软件包中含有求解方程的例程以及许多具有其他功能的例程。求根例程可以在SciPy包的optimize模块中找到。像往常一样,我们将NumPy导入为np。

3.5.2 实现方法

optimize软件包提供了用于数值求根的例程。以下说明介绍了如何使用该模块中的newton例程:

1.optimize模块未在scipy命名空间中列出,因此必须单独导入:

2.然后,我们必须在Python中定义这个函数及其导数:

3.该函数的导数在前面的例子中已经计算过了:

4.对于牛顿法和割线法,我们都使用optimize中的newton例程。牛顿法和割线法都要求将函数作为第一个参数,将初始近似值x0作为第二个参数。要使用牛顿法,我们必须使用fprime关键字参数提供 f 的导数:

5.要使用割线法,只需要提供函数作为参数,但必须提供根的前两个近似值,第二个近似值用x1关键字参数来提供:

注意

无论是牛顿法还是割线法,都不能保证收敛到真正的根。该方法的迭代完全可能只是在多个点上循环(周期性地)或剧烈波动(混沌)。

3.5.3 原理解析

具有导数 f′ x )和初始近似值 x 0 的函数 f x ),使用牛顿法迭代求根的公式定义如下:

对于每个大于0的整数 i ,从几何角度看,如果 f ( x i ) 0,则梯度方向为负(因此,函数是递减的);如果 f ( x i ) 0,则梯度方向为正(因此,函数是递增的),从而得出这个公式。

割线法以牛顿法为基础,但用以下近似值代替了一阶导数:

x i -x i -1 足够小的时候,如果方法收敛,这就是一个很好的近似值。不需要函数 f 的导数的代价是,我们需要额外的初始猜测值来启动该方法。该方法的公式如下:

一般来说,如果给定的初始猜测值和根足够接近,那么这两种方法都会收敛到该根。如果在一次迭代中导数为零,牛顿法也会失效,在这种情况下,公式的定义并不完善。

3.5.4 更多内容

本例中提到的方法是通用方法,但在某些情况下,其他方法可能会更快或更准确。广义上讲,求根算法可分为两类:一类是在每次迭代时使用函数梯度信息的算法(如牛顿法、割线法、Halley迭代法),另一类是需要对根的位置进行约束的算法(如二分法、Regula-Falsi法、Brent法)。到目前为止,我们讨论的算法都属于第一类,虽然通常它们的速度相当快,但可能无法收敛。

第二类算法是已知根存在于指定区间 a x b 的算法。我们可以通过检查 f a )和 f b )是否有不同的符号来确定根是否在这样的区间内,即 f a 0 <f b )或 f b 0 <f a )中的一个为真(当然,前提是函数是连续的,实际中的函数往往是如此连续的)。这类算法中最基本的是二分法,即反复对区间进行平分,直到找到足够好的根近似值为止。其基本前提是在 a b 之间的中点处分割区间,并选择函数符号发生变化的区间。该算法不断重复,直到区间非常小为止。以下是该算法在Python中的基本实现:

这种方法会保证收敛,因为每走一步, b-a 的长度就减半。不过,与牛顿法或割线法相比,该方法可能需要更多次的迭代。在optimize模块中也可以找到二分法的对应版本。这个版本是用C语言实现的,比这里介绍的版本效率高得多,但在大多数情况下,二分法并不是最快的方法。

Brent法是对二分法的改进,在optimize模块中以brentq的形式提供。它结合使用了二分法和插值法,可以快速找到方程的根:

值得注意的是,涉及区间界定的技术(bisection、regula-falsi、Brent)不能用于复变函数求解,而不使用区间界定的方法(牛顿法、割线法、Halley法)则可以用于这样的函数求解。

最后,有些方程的形式不完全是 f ( x )=0,但仍可使用这些技巧求解。这是通过重新排列方程,使其具有所需的形式来完成的(如果有必要,重新命名函数)。这通常并不困难,只需将等式右边的项移到左边即可。例如,如果你想找到一个函数的不动点,即 g ( x )= x ,那么我们就可以将此方法应用于相关函数,即 f ( x )= g ( x )- x EgBEyG2UzC50UL+MqGLBDZr4v39u8BDPuv4Ox3MyW6tXSzkg3KiN2PSQzZ9U4+Zp

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开