scipy.optimize.elementwise.

bracket_minimum#

scipy.optimize.elementwise.bracket_minimum(f, xm0, *, xl0=None, xr0=None, xmin=None, xmax=None, factor=None, args=(), maxiter=1000)[源]#

为一个实变量的单峰实值函数包围最小值。

对于 f 输出的每个元素,bracket_minimum 寻找标量包围点 xl < xm < xr,使得 fl >= fm <= fr,其中一个不等式是严格的。

如果函数是强单峰的,则保证函数能找到有效包围,但在其他条件下也可能找到包围。

xm0xl0xr0xminxmaxfactorargs 的元素是(相互可广播的)数组时,此函数逐元素工作。

参数:
f可调用对象

要包围根的函数。签名必须是

f(x: array, *args) -> array

其中 x 的每个元素都是有限实数,args 是一个元组,可能包含任意数量与 x 可广播的数组。

f 必须是逐元素函数:对于所有索引 if(x)[i] 必须等于 f(x[i])。它不得修改数组 xargs 中的数组。

xm0: float array_like

包围中间点的初始猜测。

xl0, xr0: float array_like, 可选

包围的左端点和右端点的初始猜测。必须与其他所有数组输入可广播。

xmin, xmaxfloat array_like, 可选

包围的最小和最大允许端点,包含。必须与其他所有数组输入可广播。

factorfloat array_like, 默认值: 2

用于扩大包围的因子。参见“注释”。

argstuple of array_like, 可选

要传递给 f 的附加位置数组参数。如果所需的根函数需要与 x 不可广播的参数,则将该可调用函数用 f 包装,使 f 仅接受 x 和可广播的 *args

maxiterint, 默认值: 1000

算法执行的最大迭代次数。

返回:
res_RichResult

一个类似于 scipy.optimize.OptimizeResult 实例的对象,具有以下属性。描述写得像值将是标量一样;但是,如果 f 返回一个数组,则输出将是相同形状的数组。

successbool array

如果算法成功终止(状态 0),则为 True;否则为 False

statusint array

表示算法退出状态的整数。

  • 0 : 算法生成了一个有效的包围。

  • -1 : 包围扩展到允许的限制。假设单峰性,这意味着在限制处的端点是一个极小点。

  • -2 : 达到了最大迭代次数。

  • -3 : 遇到了非有限值。

  • -4 : None 将通过。

  • -5 : 初始包围不满足 xmin <= xl0 < xm0 < xr0 <= xmax

bracket3-tuple of float arrays

包围的左、中、右点,如果算法成功终止。

f_bracket3-tuple of float arrays

函数在包围的左、中、右点的值。

nfevint array

为找到根而评估 f 的横坐标数量。这与 f调用的次数不同,因为函数可能在单次调用中在多个点进行评估。

nitint array

算法执行的迭代次数。

注释

类似于 scipy.optimize.bracket,此函数旨在找到实点 xl < xm < xr,使得 f(xl) >= f(xm)f(xr) >= f(xm),其中至少一个不等式是严格的。与 scipy.optimize.bracket 不同,此函数可以在数组输入上以向量化方式操作,只要输入数组彼此可广播。此外,与 scipy.optimize.bracket 不同,用户可以为所需的包围指定最小和最大端点。

给定初始的三点 xl = xl0xm = xm0xr = xr0,算法检查这些点是否已给出有效包围。如果不是,则在“下坡”方向上选择一个新端点 wxm 成为新的对侧端点,并且 xlxr 成为新的中间点,具体取决于下坡方向。算法从这里重复。

新端点 w 的选择方式取决于在下坡方向是否设置了边界 xminxmax。不失一般性,假设下坡方向向右,使得 f(xl) > f(xm) > f(xr)。如果右侧没有边界,则 w 被选择为 xr + factor * (xr - xm),其中 factor 由用户控制(默认为 2.0),以便步长呈几何比例增加。如果存在边界,在本例中为 xmax,则 w 被选择为 xmax - (xmax - xr)/factor,步长在 xmax 处逐渐停止。这种谨慎的方法确保了不会错过靠近但与边界不同的最小值,同时也能在有限步数达到 xmax 时检测 xmax 是否是极小点。

示例

假设我们希望最小化以下函数。

>>> def f(x, c=1):
...     return (x - c)**2 + 2

首先,我们必须找到一个有效的包围。函数是单峰的,因此 bracket_minimum 将很容易找到一个包围。

>>> from scipy.optimize import elementwise
>>> res_bracket = elementwise.bracket_minimum(f, 0)
>>> res_bracket.success
True
>>> res_bracket.bracket
(0.0, 0.5, 1.5)

实际上,包围点是有序的,并且中间包围点的函数值小于周围点。

>>> xl, xm, xr = res_bracket.bracket
>>> fl, fm, fr = res_bracket.f_bracket
>>> (xl < xm < xr) and (fl > fm <= fr)
True

一旦我们有了有效的包围,就可以使用 find_minimum 来提供极小值的估计。

>>> res_minimum = elementwise.find_minimum(f, res_bracket.bracket)
>>> res_minimum.x
1.0000000149011612

bracket_minimumfind_minimum 接受数组作为大多数参数。例如,要一次找到参数 c 的几个值的极小点和极小值

>>> import numpy as np
>>> c = np.asarray([1, 1.5, 2])
>>> res_bracket = elementwise.bracket_minimum(f, 0, args=(c,))
>>> res_bracket.bracket
(array([0. , 0.5, 0.5]), array([0.5, 1.5, 1.5]), array([1.5, 2.5, 2.5]))
>>> res_minimum = elementwise.find_minimum(f, res_bracket.bracket, args=(c,))
>>> res_minimum.x
array([1.00000001, 1.5       , 2.        ])
>>> res_minimum.f_x
array([2., 2., 2.])