scipy.optimize.

root#

scipy.optimize.root(fun, x0, args=(), method='hybr', jac=None, tol=None, callback=None, options=None)[source]#

尋找向量函數的根。

參數:
funcallable

要尋找根的向量函數。

假設 callable 具有簽名 f0(x, *my_args, **my_kwargs),其中 my_argsmy_kwargs 是必要的位置和關鍵字參數。與其傳遞 f0 作為 callable,不如將其包裝為僅接受 x;例如,傳遞 fun=lambda x: f0(x, *my_args, **my_kwargs) 作為 callable,其中 my_args (tuple) 和 my_kwargs (dict) 已在此函數調用之前收集。

x0ndarray

初始猜測值。

argstuple, optional

傳遞給目標函數及其 Jacobian 的額外參數。

methodstr, optional

求解器類型。應為下列其中之一

jacbool 或 callable, optional

如果 jac 是布林值且為 True,則假設 fun 除了目標函數外還會傳回 Jacobian 的值。如果為 False,則將以數值方式估計 Jacobian。jac 也可以是傳回 fun 的 Jacobian 的 callable。在這種情況下,它必須接受與 fun 相同的參數。

tolfloat, optional

終止容忍度。若要進行詳細控制,請使用求解器特定的選項。

callbackfunction, optional

選用的回呼函數。它在每次迭代時都會以 callback(x, f) 的形式調用,其中 x 是目前的解,而 f 是對應的殘差。適用於 ‘hybr’ 和 ‘lm’ 以外的所有方法。

optionsdict, optional

求解器選項的字典。例如,xtolmaxiter,請參閱 show_options() 以取得詳細資訊。

返回:
solOptimizeResult

OptimizeResult 物件表示的解。重要的屬性包括:x 解陣列、success 布林旗標,指示演算法是否成功退出,以及 message 描述終止原因。請參閱 OptimizeResult 以取得其他屬性的說明。

另請參閱

show_options

求解器接受的其他選項

筆記

本節說明可透過 ‘method’ 參數選擇的可用求解器。預設方法為 hybr

方法 hybr 使用 MINPACK [1] 中實作的 Powell 混合方法的修改版本。

方法 lm 使用 MINPACK [1] 中實作的 Levenberg-Marquardt 演算法的修改版本,以最小平方意義求解非線性方程式系統。

方法 df-sane 是一種無導數譜方法。[3]

方法 broyden1broyden2andersonlinearmixingdiagbroydenexcitingmixingkrylov 是不精確的牛頓法,具有回溯或完整線搜索 [2]。每種方法都對應於特定的 Jacobian 近似。

  • 方法 broyden1 使用 Broyden 的第一個 Jacobian 近似,它被稱為 Broyden 的好方法。

  • 方法 broyden2 使用 Broyden 的第二個 Jacobian 近似,它被稱為 Broyden 的壞方法。

  • 方法 anderson 使用(擴展的)Anderson 混合。

  • 方法 Krylov 使用 Krylov 近似來逼近逆 Jacobian。它適用於大規模問題。

  • 方法 diagbroyden 使用對角 Broyden Jacobian 近似。

  • 方法 linearmixing 使用純量 Jacobian 近似。

  • 方法 excitingmixing 使用調整後的對角 Jacobian 近似。

警告

為方法 diagbroydenlinearmixingexcitingmixing 實作的演算法可能適用於特定問題,但它們是否有效可能很大程度上取決於問題。

在 0.11.0 版本中新增。

參考文獻

[1] (1,2)

More, Jorge J.、Burton S. Garbow 和 Kenneth E. Hillstrom。1980 年。《MINPACK-1 使用者指南》。

[2]

C. T. Kelley。1995 年。《線性與非線性方程式的迭代方法》。工業與應用數學學會。 <https://archive.siam.org/books/kelley/fr16/>

[3]
  1. La Cruz, J.M. Martinez, M. Raydan。數學計算 75, 1429 (2006)。

範例

以下函數定義了非線性方程式系統及其 Jacobian。

>>> import numpy as np
>>> def fun(x):
...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
...             0.5 * (x[1] - x[0])**3 + x[1]]
>>> def jac(x):
...     return np.array([[1 + 1.5 * (x[0] - x[1])**2,
...                       -1.5 * (x[0] - x[1])**2],
...                      [-1.5 * (x[1] - x[0])**2,
...                       1 + 1.5 * (x[1] - x[0])**2]])

可以透過以下方式獲得解。

>>> from scipy import optimize
>>> sol = optimize.root(fun, [0, 0], jac=jac, method='hybr')
>>> sol.x
array([ 0.8411639,  0.1588361])

大型問題

假設我們需要在正方形 \([0,1]\times[0,1]\) 上求解以下積分微分方程式

\[\nabla^2 P = 10 \left(\int_0^1\int_0^1\cosh(P)\,dx\,dy\right)^2\]

邊界條件為 \(P(x,1) = 1\),在正方形邊界的其他位置 \(P=0\)

可以使用 method='krylov' 求解器找到解

>>> from scipy import optimize
>>> # parameters
>>> nx, ny = 75, 75
>>> hx, hy = 1./(nx-1), 1./(ny-1)
>>> P_left, P_right = 0, 0
>>> P_top, P_bottom = 1, 0
>>> def residual(P):
...    d2x = np.zeros_like(P)
...    d2y = np.zeros_like(P)
...
...    d2x[1:-1] = (P[2:]   - 2*P[1:-1] + P[:-2]) / hx/hx
...    d2x[0]    = (P[1]    - 2*P[0]    + P_left)/hx/hx
...    d2x[-1]   = (P_right - 2*P[-1]   + P[-2])/hx/hx
...
...    d2y[:,1:-1] = (P[:,2:] - 2*P[:,1:-1] + P[:,:-2])/hy/hy
...    d2y[:,0]    = (P[:,1]  - 2*P[:,0]    + P_bottom)/hy/hy
...    d2y[:,-1]   = (P_top   - 2*P[:,-1]   + P[:,-2])/hy/hy
...
...    return d2x + d2y - 10*np.cosh(P).mean()**2
>>> guess = np.zeros((nx, ny), float)
>>> sol = optimize.root(residual, guess, method='krylov')
>>> print('Residual: %g' % abs(residual(sol.x)).max())
Residual: 5.7972e-06  # may vary
>>> import matplotlib.pyplot as plt
>>> x, y = np.mgrid[0:1:(nx*1j), 0:1:(ny*1j)]
>>> plt.pcolormesh(x, y, sol.x, shading='gouraud')
>>> plt.colorbar()
>>> plt.show()
../../_images/scipy-optimize-root-1.png