scipy.optimize.elementwise.

find_root#

scipy.optimize.elementwise.find_root(f, init, /, *, args=(), tolerances=None, maxiter=None, callback=None)[原始碼]#

尋找實數變數的單調實值函數的根。

對於 f 的輸出的每個元素,find_root 尋找使元素為 0 的純量根。此函數目前使用 Chandrupatla 的括號演算法 [1],因此需要參數 init 提供根的括號:兩個端點的函數值必須具有相反的符號。

在提供有效括號的情況下,如果函數在括號內是連續的,則 find_root 保證收斂到滿足提供的 tolerances 的解。

initargs 包含(可廣播)陣列時,此函數以元素方式運作。

參數:
f可呼叫物件

想要尋找根的函數。簽名必須是

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

其中 x 的每個元素都是有限實數,而 args 是一個元組,其中可能包含任意數量的可與 x 廣播的陣列。

f 必須是元素級函數:對於所有索引 i,每個元素 f(x)[i] 必須等於 f(x[i])。它不得改變陣列 xargs 中的陣列。

find_root 尋找陣列 x,使得 f(x) 是一個零陣列。

init浮點數類陣列的 2 元組

包圍所需根的括號的下限和上限端點。如果陣列 xl, xr = init 以元素方式滿足 xl < xrsign(f(xl)) == -sign(f(xr)),則括號有效。陣列可以彼此和 args 廣播。

args陣列類元組,選用

要傳遞給 f 的其他位置陣列引數。陣列必須彼此和 init 的陣列廣播。如果想要尋找根的可呼叫物件需要無法與 x 廣播的引數,請使用 f 包裝該可呼叫物件,使得 f 僅接受 x 和可廣播的 *args

tolerances浮點數字典,選用

根和函數值的絕對和相對容差。字典的有效鍵為

  • xatol - 根的絕對容差

  • xrtol - 根的相對容差

  • fatol - 函數值的絕對容差

  • frtol - 函數值的相對容差

請參閱「注意事項」以取得預設值和明確的終止條件。

maxiter整數,選用

要執行的演算法的最大迭代次數。預設值是相關 dtype 的(正常)浮點數中可能的最大二等分次數。

callback可呼叫物件,選用

要在第一次迭代之前和每次迭代之後呼叫的選用使用者提供函數。呼叫方式為 callback(res),其中 res 是類似於 find_root 傳回的 _RichResult(但包含所有變數的目前迭代值)。如果 callback 引發 StopIteration,則演算法將立即終止,而 find_root 將傳回結果。callback 不得改變 res 或其屬性。

傳回值:
res_RichResult

類似於 scipy.optimize.OptimizeResult 實例的物件,具有下列屬性。描述的撰寫方式就好像值將是純量;但是,如果 f 傳回陣列,則輸出將是相同形狀的陣列。

success布林陣列

True 演算法成功終止的位置(狀態 0);否則為 False

status整數陣列

表示演算法結束狀態的整數。

  • 0 : 演算法收斂到指定的容差。

  • -1 : 初始括號無效。

  • -2 : 已達到最大迭代次數。

  • -3 : 遇到非有限值。

  • -4 : 迭代已由 callback 終止。

  • 1 : 演算法正常進行中(僅在 callback 中)。

x浮點數陣列

函數的根,如果演算法成功終止。

f_x浮點數陣列

fx 評估時的值。

nfev整數陣列

為了尋找根而評估 f 的橫座標數目。這與 f呼叫的次數不同,因為函數可能會在單次呼叫中在多個點評估。

nit整數陣列

執行的演算法迭代次數。

bracket浮點數陣列的元組

最終括號的下限和上限端點。

f_bracket浮點數陣列的元組

f 在括號的下限和上限端點評估時的值。

另請參閱

bracket_root

注意事項

根據 Chandrupatla 的原始論文 [1] 實作。

  • a, b = init 為初始括號的左端點和右端點,

  • xlxr 為最終括號的左端點和右端點,

  • xmin = xl if abs(f(xl)) <= abs(f(xr)) else xr 為函數值較小的最終括號端點,且

  • fmin0 = min(f(a), f(b)) 為在初始括號端點評估的函數的兩個值中的最小值。

然後,當

  • abs(xr - xl) < xatol + abs(xmin) * xrtol

  • fun(xmin) <= fatol + abs(fmin0) * frtol.

時,演算法被視為已收斂。這等效於 [1] 中描述的終止條件,其中 xrtol = 4e-10xatol = 1e-5,且 fatol = frtol = 0。但是,tolerances 字典的預設值為 xatol = 4*tinyxrtol = 4*epsfrtol = 0,以及 fatol = tiny,其中 epstiny 是函數輸入和輸出的結果 dtype 的精確度和最小正常數。

參考文獻

[1] (1,2,3)

Chandrupatla, Tirupathi R. “A new hybrid quadratic/bisection algorithm for finding the zero of a nonlinear function without using derivatives”. Advances in Engineering Software, 28(3), 145-149. https://doi.org/10.1016/s0965-9978(96)00051-8

範例

假設我們想要尋找以下函數的根。

>>> def f(x, c=5):
...     return x**3 - 2*x - c

首先,我們必須找到有效的括號。該函數不是單調的,但 bracket_root 可能能夠提供括號。

>>> from scipy.optimize import elementwise
>>> res_bracket = elementwise.bracket_root(f, 0)
>>> res_bracket.success
True
>>> res_bracket.bracket
(2.0, 4.0)

事實上,括號端點的函數值具有相反的符號。

>>> res_bracket.f_bracket
(-1.0, 51.0)

一旦我們有了有效的括號,就可以使用 find_root 來提供精確的根。

>>> res_root = elementwise.find_root(f, res_bracket.bracket)
>>> res_root.x
2.0945514815423265

最終括號僅幾個 ULP 寬,因此此值與真根之間的誤差在雙精度算術中可表示的值內不會小很多。

>>> import numpy as np
>>> xl, xr = res_root.bracket
>>> (xr - xl) / np.spacing(xl)
2.0
>>> res_root.f_bracket
(-8.881784197001252e-16, 9.769962616701378e-15)

bracket_rootfind_root 接受大多數引數的陣列。例如,要一次尋找參數 c 的幾個值的根

>>> c = np.asarray([3, 4, 5])
>>> res_bracket = elementwise.bracket_root(f, 0, args=(c,))
>>> res_bracket.bracket
(array([1., 1., 2.]), array([2., 2., 4.]))
>>> res_root = elementwise.find_root(f, res_bracket.bracket, args=(c,))
>>> res_root.x
array([1.8932892 , 2.        , 2.09455148])