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...)
, wherea,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()