請假設一個可逆矩陣向量:
import numpy as np
a = np.arange(120).reshape((2, 2, 5, 6))
我想在定義的軸上反轉矩陣:
b = np.linalg.inv(a, axis1=0, axis2=1)
但這似乎不受支持。
如何實作這一目標?
uj5u.com熱心網友回復:
如果您知道矩陣是 2x2,您可以使用標準公式輕松完成這些矩陣的求逆;否則,我擔心唯一合理的解決方案是使用 for 回圈?例如,以下適用于任何形狀(適當修改尺寸):
b = np.stack([np.linalg.inv(a[:, :, i, j]) for i in range(a.shape[2]) for j in range(a.shape[3])], axis=2)
b = b.reshape(2, 2, 5, 6)
如檢查
for i in range(a.shape[2]):
for j in range(a.shape[3]):
assert np.allclose(np.dot(a[:,:,i,j], b[:,:,i,j]), np.eye(2))
在特定的 2x2 情況下,您可以執行以下操作,這是完全矢量化的,因此可能更快:
determinants = a[0, 0] * a[1, 1] - a[0, 1] * a[1, 0]
b = 1 / determinants * np.stack([
np.stack([a[1, 1], -a[0, 1]]),
np.stack([-a[1, 0], a[0, 0]]),
])
在特定(小)輸入大小上,第二個解決方案在我的測驗中大約快 10 倍(43us 與 537us)。
uj5u.com熱心網友回復:
inv docs 將其陣列輸入指定為:
a : (..., M, M) array_like
Matrix to be inverted.
你有一個
a = np.arange(120).reshape((2, 2, 5, 6))
(M,M,...)
尺寸順序錯誤 - 更改它們!
In [44]: a = np.arange(120).reshape((2, 2, 5, 6))
將軸更改為inv接受的順序:
In [45]: A = a.transpose(2,3,0,1)
In [46]: Ai = np.linalg.inv(A)
In [47]: Ai.shape
Out[47]: (5, 6, 2, 2)
In [48]: ai = Ai.transpose(2,3,0,1) # and back
In [49]: ai.shape
Out[49]: (2, 2, 5, 6)
我打算測驗結果,但得到了:
In [50]: x = a@ai
Traceback (most recent call last):
File "<ipython-input-50-9dfe3616745d>", line 1, in <module>
x = a@ai
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 5 is different from 6)
就像inv,matmul將最后 2 個維度視為,將前 2 個維度matrix視為“批次”:
In [51]: x = A@Ai
In [52]: x[0,0]
Out[52]:
array([[1., 0.],
[0., 1.]])
In [53]: x[0,3]
Out[53]:
array([[1.00000000e 00, 1.38777878e-17],
[4.44089210e-16, 1.00000000e 00]])
我們可以做等效的einsum:
In [55]: x = np.einsum('ijkl,jmkl->imkl',a,ai)
In [56]: x[:,:,0,0]
Out[56]:
array([[1., 0.],
[0., 1.]])
您可能希望更改原始規范以匹配inv和matmul用法。它可以讓你的生活更輕松。還要記住,在numpy尾隨維度中是最里面的維度。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/403490.html
標籤:
