1

當一個具有與載體基質逆乘法的一個問題,因爲這樣的:矩陣求逆方法

Ax=b

一個可利用一個Cholesky分解甲和backsubstitute b找到產生的矢量x。但是,如果不像上面那樣制定問題,有時需要矩陣求逆。我的問題是處理這種情況的最佳方式是什麼。下面,我比較了各種方式(使用numpy的)反轉正定矩陣:

首先,生成矩陣:

>>> A = np.random.rand(5,5) 
>>> A 
array([[ 0.13516074, 0.2532381 , 0.61169708, 0.99678563, 0.32895589], 
     [ 0.35303998, 0.8549499 , 0.39071336, 0.32792806, 0.74723177], 
     [ 0.4016188 , 0.93897663, 0.92574706, 0.93468798, 0.90682809], 
     [ 0.03181169, 0.35059435, 0.10857948, 0.36422977, 0.54525 ], 
     [ 0.64871162, 0.37809219, 0.35742865, 0.7154568 , 0.56028468]]) 
>>> A = np.dot(A.transpose(), A) 
>>> A 
array([[ 0.72604206, 0.96959581, 0.82773451, 1.10159817, 1.05327233], 
     [ 0.96959581, 1.94261607, 1.53140854, 1.80864185, 1.9766411 ], 
     [ 0.82773451, 1.53140854, 1.52338262, 1.89841402, 1.59213299], 
     [ 1.10159817, 1.80864185, 1.89841402, 2.61930178, 2.01999385], 
     [ 1.05327233, 1.9766411 , 1.59213299, 2.01999385, 2.10012097]]) 

爲直接反演的方法的結果如下:

>>> np.linalg.inv(A) 
array([[ 5.49746838, -1.92540877, 2.24730018, -2.20242449, 
     -0.53025806], 
     [ -1.92540877, 95.34219156, -67.93144606, 50.16450952, 
     -85.52146331], 
     [ 2.24730018, -67.93144606, 57.0739859 , -40.56297863, 
     58.55694127], 
     [ -2.20242449, 50.16450952, -40.56297863, 30.6441555 , 
     -44.83400183], 
     [ -0.53025806, -85.52146331, 58.55694127, -44.83400183, 
     79.96573405]]) 

當使用摩爾 - Penrose逆,結果如下(你可能會注意到,在顯示精度,結果是一樣的直接倒置):

>>> np.linalg.pinv(A) 
array([[ 5.49746838, -1.92540877, 2.24730018, -2.20242449, 
     -0.53025806], 
     [ -1.92540877, 95.34219156, -67.93144606, 50.16450952, 
     -85.52146331], 
     [ 2.24730018, -67.93144606, 57.0739859 , -40.56297863, 
     58.55694127], 
     [ -2.20242449, 50.16450952, -40.56297863, 30.6441555 , 
     -44.83400183], 
     [ -0.53025806, -85.52146331, 58.55694127, -44.83400183, 
     79.96573405]]) 

最後,單位矩陣解決時:再次

>>> np.linalg.solve(A, np.eye(5)) 
array([[ 5.49746838, -1.92540877, 2.24730018, -2.20242449, 
     -0.53025806], 
     [ -1.92540877, 95.34219156, -67.93144606, 50.16450952, 
     -85.52146331], 
     [ 2.24730018, -67.93144606, 57.0739859 , -40.56297863, 
     58.55694127], 
     [ -2.20242449, 50.16450952, -40.56297863, 30.6441555 , 
     -44.83400183], 
     [ -0.53025806, -85.52146331, 58.55694127, -44.83400183, 
     79.96573405]]) 

,您可能會注意到一個粗略的檢查,結果是一樣的前兩種方法。

衆所周知,由於數值不穩定,矩陣求逆是一個病態問題,應儘可能避免。但是,在不可避免的情況下,最好的方法是什麼?爲什麼?爲了澄清,我指的是在軟件中實現這些方程時的最佳方法。

my questions的另一個提供了這樣的問題的一個例子。

+1

我認爲這篇文章屬於[數學堆棧交換](https://math.stackexchange.com/)。 SO是編程問題。 – litelite

+0

我確實在想。但是,由於數值穩定性問題是在代碼中實現這樣的矩陣方程時出現的,所以我覺得它適用於此。當在紙上操縱這樣的矩陣方程時,倒數是可接受的(有時不可避免)。因此,我認爲這是一個編程問題。 –

+0

我不記得聽說矩陣求逆是一個不適定的問題,它計算逆矩陣然後乘以矩陣(或向量)的效率就不那麼高效了。當然,某些矩陣是有條件的(正如可以通過條件編號估計的那樣),但是對於這些矩陣根本就沒有太多的辦法。 – SirGuy

回答

0

避免反轉矩陣的原因只與效率有關。直接求解線性系統速度更快。如果您在關聯問題中思考問題有點不同,那麼您可以應用相同的原則。

爲了找到矩陣inv(K) * Y * T(Y) * inv(K) - D * inv(K)可以解方程的以下系統:

K * R * K = Y * T(Y) 

你可以解決它分爲兩個部分:

R2 * K = R1 
K * R1 = Y * T(Y) 

所以,你先解決了R1你通常的方法,然後解決R2(承認你可以解決T(K) * T(R2) = T(R1)如果你必須)。

但是,在這一點上,我不知道這是否比明確計算逆矩陣更有效,除非K是對稱的。(有可能是一種有效地得到T(K)K分解,但我不知道不加思索)

如果K是對稱的,那麼你可以計算在K您分解一次,重複使用兩個回代步驟,它可能比明確計算逆矩陣更有效。