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 。使用牛顿-拉夫森方法,如果导数 fprime 的 func 则提供,否则使用正割方法。如果二阶导数 fprime2 的 func 在此基础上,采用哈雷法。

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

函数为零的估计位置。

r : RootResults ,可选RootResults,可选

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

convergedndarray of bool,可选

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

zero_derndarray of bool,可选

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

参见

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

两者都有 fprime2 和 fprime ,请使用哈雷的方法:

>>> 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