jacobian#
- scipy.differentiate.jacobian(f, x, *, tolerances=None, maxiter=10, order=8, initial_step=0.5, step_factor=2.0, step_direction=0)[原始碼]#
數值評估函數的 Jacobian 矩陣。
- 參數:
- fcallable
想要計算 Jacobian 矩陣的函數。簽名必須是
f(xi: ndarray) -> ndarray
其中
xi
的每個元素都是有限實數。如果要微分的函數接受額外參數,請將其包裝(例如使用functools.partial
或lambda
),並將包裝後的 callable 傳遞給jacobian
。f 不得改變陣列xi
。請參閱關於向量化以及輸入和輸出維度的註解。- xfloat array_like
評估 Jacobian 矩陣的點。必須至少有一個維度。請參閱關於維度和向量化的註解。
- tolerancesdictionary of floats, optional
絕對和相對容差。字典的有效鍵為
atol
- 導數的絕對容差rtol
- 導數的相對容差
當
res.error < atol + rtol * abs(res.df)
時,迭代將停止。預設的 atol 是適當 dtype 的最小正規數,而預設的 rtol 是適當 dtype 精度的平方根。- maxiterint, default: 10
要執行的演算法最大迭代次數。請參閱註解。
- orderint, default: 8
要使用的有限差分公式的(正整數)階數。奇數將四捨五入到下一個偶數。
- initial_stepfloat array_like, default: 0.5
有限差分導數近似的(絕對)初始步長。必須可與 x 和 step_direction 廣播。
- step_factorfloat, default: 2.0
每次迭代中步長減小的因子;即,迭代 1 中的步長為
initial_step/step_factor
。如果step_factor < 1
,則後續步驟將大於初始步驟;如果小於某個閾值的步驟是不希望的(例如,由於減法消去誤差),這可能很有用。- step_directioninteger array_like
表示有限差分步長方向的陣列(例如,當 x 接近函數域的邊界時使用。)必須可與 x 和 initial_step 廣播。其中 0(預設值),使用中心差分;其中為負數(例如 -1),步長為非正數;其中為正數(例如 1),所有步長為非負數。
- 返回:
- res_RichResult
類似於
scipy.optimize.OptimizeResult
實例的物件,具有以下屬性。描述的寫法就好像這些值將是純量;但是,如果 f 返回一個陣列,則輸出將是相同形狀的陣列。- successbool array
演算法成功終止的地方為
True
(狀態0
);否則為False
。- statusint array
表示演算法退出狀態的整數。
0
: 演算法收斂到指定的容差。-1
: 錯誤估計值增加,因此迭代終止。-2
: 已達到最大迭代次數。-3
: 遇到非有限值。
- dffloat array
如果演算法成功終止,則為 f 在 x 處的 Jacobian 矩陣。
- errorfloat array
錯誤估計值:Jacobian 矩陣的當前估計值與前一次迭代中的估計值之間的差異量級。
- nitint array
執行的演算法迭代次數。
- nfevint array
評估 f 的點數。
屬性的每個元素都與 df 的對應元素相關聯。例如, nfev 的元素
i
是為了計算 df 的元素i
而評估 f 的點數。
另請參閱
註解
假設我們希望評估函數 \(f: \mathbf{R}^m \rightarrow \mathbf{R}^n\) 的 Jacobian 矩陣。將正整數值 \(m\) 和 \(n\) 分別賦給變數
m
和n
,並讓...
表示整數的任意元組。如果我們希望在單個點評估 Jacobian 矩陣,則引數 x 必須是形狀為
(m,)
的陣列引數 f 必須向量化以接受形狀為
(m, ...)
的陣列。第一個軸表示 \(f\) 的 \(m\) 個輸入;其餘部分用於在單次呼叫中評估多個點的函數。引數 f 必須返回形狀為
(n, ...)
的陣列。第一個軸表示 \(f\) 的 \(n\) 個輸出;其餘部分用於評估多個點的函數結果。結果物件的屬性
df
將是形狀為(n, m)
的陣列,即 Jacobian 矩陣。
此函數也以 Jacobian 矩陣可以在單次呼叫中評估
k
個點的意義上進行向量化。在這種情況下, x 將是形狀為(m, k)
的陣列, f 將接受形狀為(m, k, ...)
的陣列並返回形狀為(n, k, ...)
的陣列,並且結果的df
屬性將具有形狀(n, m, k)
。假設所需的 callable
f_not_vectorized
未向量化;它只能接受形狀為(m,)
的陣列。滿足所需介面的簡單解決方案是將f_not_vectorized
包裝如下def f(x): return np.apply_along_axis(f_not_vectorized, axis=0, arr=x)
或者,假設所需的 callable
f_vec_q
已向量化,但僅適用於形狀為(m, q)
的 2D 陣列。為了滿足所需的介面,請考慮def f(x): m, batch = x.shape[0], x.shape[1:] # x.shape is (m, ...) x = np.reshape(x, (m, -1)) # `-1` is short for q = prod(batch) res = f_vec_q(x) # pass shape (m, q) to function n = res.shape[0] return np.reshape(res, (n,) + batch) # return shape (n, ...)
然後將包裝後的 callable
f
作為jacobian
的第一個引數傳遞。參考文獻
[1]Jacobian 矩陣和行列式, 維基百科, https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant
範例
Rosenbrock 函數從 \(\mathbf{R}^m \rightarrow \mathbf{R}\) 映射;SciPy 實作
scipy.optimize.rosen
已向量化以接受形狀為(m, p)
的陣列並返回形狀為p
的陣列。假設我們希望在[0.5, 0.5, 0.5]
處評估 Jacobian 矩陣(又稱梯度,因為函數返回純量)。>>> import numpy as np >>> from scipy.differentiate import jacobian >>> from scipy.optimize import rosen, rosen_der >>> m = 3 >>> x = np.full(m, 0.5) >>> res = jacobian(rosen, x) >>> ref = rosen_der(x) # reference value of the gradient >>> res.df, ref (array([-51., -1., 50.]), array([-51., -1., 50.]))
作為具有多個輸出的函數範例,請考慮 [1] 中的範例 4。
>>> def f(x): ... x1, x2, x3 = x ... return [x1, 5*x3, 4*x2**2 - 2*x3, x3*np.sin(x1)]
真實的 Jacobian 矩陣由下式給出
>>> def df(x): ... x1, x2, x3 = x ... one = np.ones_like(x1) ... return [[one, 0*one, 0*one], ... [0*one, 0*one, 5*one], ... [0*one, 8*x2, -2*one], ... [x3*np.cos(x1), 0*one, np.sin(x1)]]
在任意點評估 Jacobian 矩陣。
>>> rng = np.random.default_rng() >>> x = rng.random(size=3) >>> res = jacobian(f, x) >>> ref = df(x) >>> res.df.shape == (4, 3) True >>> np.allclose(res.df, ref) True
在單次呼叫中評估 10 個任意點的 Jacobian 矩陣。
>>> x = rng.random(size=(3, 10)) >>> res = jacobian(f, x) >>> ref = df(x) >>> res.df.shape == (4, 3, 10) True >>> np.allclose(res.df, ref) True