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,其中至少有一个不等式是严格的。

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

xm0xl0xr0xminxmaxfactor 以及 args 的元素是(相互可广播的)数组时,此函数按元素方式工作。

参数:
f可调用对象

要对其进行区间划分的函数的根。签名必须是

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

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

f 必须是一个逐元素函数:对于所有索引 i,每个元素 f(x)[i] 都必须等于 f(x[i])。它不能改变数组 xargs 中的数组。

xm0: float array_like

区间中间点的起始猜测。

xl0, xr0: float array_like, optional

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

xmin, xmaxfloat array_like, 可选

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

factorfloat array_like,默认值:2

用于增长区间的因子。请参阅“注释”。

argsarray_like 的元组,可选

要传递给 f 的其他位置数组参数。如果需要根的可调用对象需要与 x 不可广播的参数,请使用 f 包装该可调用对象,以使 f 仅接受 x 和可广播的 *args

maxiterint,默认值:1000

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

返回:
res_RichResult

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

success布尔值数组

算法成功终止的位置(状态 0);否则为 False

status整数数组

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

  • 0:该算法生成了一个有效的区间。

  • -1:区间扩展到允许的限制。假设是单峰的,则表示极限处的端点是最小值。

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

  • -3:遇到非有限值。

  • -4None 应通过。

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

bracket浮点数数组的 3 元组

如果算法成功终止,则为区间的左、中和右点。

f_bracket浮点数数组的 3 元组

区间左、中和右点的函数值。

nfev整数数组

评估 f 的横坐标数,以找到根。这与调用 f 的次数不同,因为该函数可能在一次调用中评估多个点。

nit整数数组

执行的算法迭代次数。

注释

类似于 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)。如果右侧没有边界,则选择 wxr + factor * (xr - xm),其中 factor 由用户控制(默认为 2.0),以便步长以几何比例增加。如果存在边界,则在本例中为 xmax,则选择 wxmax - (xmax - xr)/factor,步长逐渐减小到 xmax。这种谨慎的方法可确保不会错过接近但与边界不同的最小值,同时还可以检测在有限步数后到达 xmax 时,xmax 是否为最小值。

示例

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

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

首先,我们必须找到一个有效的区间。该函数是单峰的,因此 bracket_minium 可以很容易地找到一个区间。

>>> 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.])