scipy.optimize.newton

scipy.optimize.newton(func, x0, fprime=None, args=(), tol=1.48e-08, maxiter=50, fprime2=None, x1=None, rtol=0.0, full_output=False, disp=True)[源代码]

使用牛顿-拉夫森(或割线或哈雷法)求实函数或复函数的零点。

求标量值函数的零点 func 给定附近的标量起点 x0 。使用牛顿-拉夫森方法,如果导数 fprimefunc 则提供,否则使用正割方法。如果二阶导数 fprime2func 在此基础上,采用哈雷法。

If x0 is a sequence with more than one item, newton returns an array: the zeros of the function from each (scalar) starting point in x0. In this case, func must be vectorized to return a sequence or array of the same shape as its first argument. If fprime (fprime2) is given, then its return must also have the same shape: each element is the first (second) derivative of func with respect to its only variable evaluated at each element of its first argument.

newton 用于求单变量标值函数的根。有关涉及多个变量的问题,请参见 root

参数
func可调用

需要零的函数。它必须是形式的单个变量的函数 f(x,a,b,c...), where a,b,c... 是额外的参数,可以在 args 参数。

x0浮点、序列或ndarray

对应该在实际零附近的零的初步估计。如果不是标量,则 func 必须矢量化,并返回与其第一个参数形状相同的序列或数组。

fprime可调用,可选

函数的导数(如果可用且方便)。如果为None(默认值),则使用正割方法。

args元组,可选

要在函数调用中使用的额外参数。

tol浮动,可选

零值的允许误差。如果 func 是复值的,一个更大的 tol 的实部和虚部都被推荐为 x 贡献给 |x - x0|

maxiter整型,可选

最大迭代次数。

fprime2可调用,可选

函数的二阶导数(当可用且方便时)。如果为None(默认),则使用法线牛顿-拉夫森或割线方法。如果不是NONE,则使用哈雷方法。

x1浮动,可选

对零的另一个估计应该在接近实际零的某个地方。在以下情况下使用 fprime 不提供。

rtol浮动,可选

终止的容差(相对)。

full_output布尔值,可选

如果 full_output 为false(默认值),则返回根。如果为True且 x0 为标量,则返回值为 (x, r) ,在哪里 x 是根,并且 r 是一种 RootResults 对象。如果为True且 x0 为非标量,则返回值为 (x, converged, zero_der) (有关详细信息,请参阅退货部分)。

disp布尔值,可选

如果为True,则在算法不收敛时引发RuntimeError,并显示包含迭代次数和当前函数值的错误消息。否则,收敛状态将记录在 RootResults 返回对象。如果出现以下情况,则忽略 x0 不是标量。 Note: this has little to do with displaying, however, the `disp` keyword cannot be renamed for backwards compatibility.

退货
root浮点、序列或ndarray

函数为零的估计位置。

rRootResults ,可选RootResults,可选

在以下情况下出席 full_output=Truex0 是标量的。对象,该对象包含有关收敛的信息。具体地说, r.converged 如果例程收敛,则为True。

convergedndarray of bool,可选

在以下情况下出席 full_output=Truex0 是非标量的。对于向量函数,指示哪些元素成功收敛。

zero_derndarray of bool,可选

在以下情况下出席 full_output=Truex0 是非标量的。对于向量函数,指示哪些元素具有零导数。

参见

root_scalar

标量函数的根求解器接口

root

用于多输入、多输出函数的根求解器接口

注意事项

牛顿-拉夫森方法的收敛速度是二次的,哈雷法是三次的,割线法是次二次的。这意味着如果函数表现良好,第n次迭代后估计的零中的实际误差大约是第(n-1)步之后误差的平方(哈雷为立方体)。但是,这里使用的停止标准是步长,并且不能保证找到零。因此,结果应该得到验证。较安全的算法有Brentq、Brense、Ridder和二等分,但它们都要求首先将根括在函数更改符号的区间内。当找到这样的区间时,推荐在一维问题中普遍使用Brentq算法。

什么时候 newton 与数组一起使用时,它最适合以下类型的问题:

  • 最初的猜测是, x0 ,与根部的距离都是相对相同的。

  • 一些或全部额外的论据, args ,也是数组,这样一类类似的问题就可以一起解决。

  • 最初猜测的大小, x0 ,大于O(100)元素。否则,朴素循环的性能可能与向量一样好,甚至更好。

示例

>>> from scipy import optimize
>>> import matplotlib.pyplot as plt
>>> def f(x):
...     return (x**3 - 1)  # only one real root at x = 1

fprime 未提供,请使用Sucant方法:

>>> root = optimize.newton(f, 1.5)
>>> root
1.0000000000000016
>>> root = optimize.newton(f, 1.5, fprime2=lambda x: 6 * x)
>>> root
1.0000000000000016

仅限 fprime ,则使用牛顿-拉夫森方法:

>>> root = optimize.newton(f, 1.5, fprime=lambda x: 3 * x**2)
>>> root
1.0

两者都有 fprime2fprime ,请使用哈雷的方法:

>>> root = optimize.newton(f, 1.5, fprime=lambda x: 3 * x**2,
...                        fprime2=lambda x: 6 * x)
>>> root
1.0

当我们想要为一组相关的起始值和/或函数参数查找零时,我们可以将它们作为输入数组提供:

>>> f = lambda x, a: x**3 - a
>>> fder = lambda x, a: 3 * x**2
>>> rng = np.random.default_rng()
>>> x = rng.standard_normal(100)
>>> a = np.arange(-50, 50)
>>> vec_res = optimize.newton(f, x, fprime=fder, args=(a, ), maxiter=200)

上面的内容等同于为中的每个值求解 (x, a) 在for循环中单独运行,速度更快:

>>> loop_res = [optimize.newton(f, x0, fprime=fder, args=(a0,))
...             for x0, a0 in zip(x, a)]
>>> np.allclose(vec_res, loop_res)
True

绘制找到的所有值的结果 a

>>> analytical_result = np.sign(a) * np.abs(a)**(1/3)
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> ax.plot(a, analytical_result, 'o')
>>> ax.plot(a, vec_res, '.')
>>> ax.set_xlabel('$a$')
>>> ax.set_ylabel('$x$ where $f(x, a)=0$')
>>> plt.show()
../../_images/scipy-optimize-newton-1.png