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 的解。當 init 和 args 包含(可廣播)陣列時,此函數以元素方式運作。
- 參數:
- f可呼叫物件
想要尋找根的函數。簽名必須是
f(x: array, *args) -> array
其中
x
的每個元素都是有限實數,而args
是一個元組,其中可能包含任意數量的可與x
廣播的陣列。f 必須是元素級函數:對於所有索引
i
,每個元素f(x)[i]
必須等於f(x[i])
。它不得改變陣列x
或args
中的陣列。find_root
尋找陣列x
,使得f(x)
是一個零陣列。- init浮點數類陣列的 2 元組
包圍所需根的括號的下限和上限端點。如果陣列
xl, xr = init
以元素方式滿足xl < xr
且sign(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浮點數陣列
f 在 x 評估時的值。
- nfev整數陣列
為了尋找根而評估 f 的橫座標數目。這與 f 被呼叫的次數不同,因為函數可能會在單次呼叫中在多個點評估。
- nit整數陣列
執行的演算法迭代次數。
- bracket浮點數陣列的元組
最終括號的下限和上限端點。
- f_bracket浮點數陣列的元組
f 在括號的下限和上限端點評估時的值。
另請參閱
注意事項
根據 Chandrupatla 的原始論文 [1] 實作。
令
a, b = init
為初始括號的左端點和右端點,xl
和xr
為最終括號的左端點和右端點,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-10
、xatol = 1e-5
,且fatol = frtol = 0
。但是,tolerances 字典的預設值為xatol = 4*tiny
、xrtol = 4*eps
、frtol = 0
,以及fatol = tiny
,其中eps
和tiny
是函數輸入和輸出的結果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_root
和find_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])