矩阵求逆方法

Matrix Inversion Methods

当遇到矩阵与向量的逆乘问题时,例如:

可以对 A 进行 Cholesky 分解并反向代入 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]])

使用Moore-Penrose Pseudoinverse时,结果如下(您可能会注意到,显示的精度,结果与直接反演的结果相同):

>>> 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.

中的另一个示例提供了此类问题的示例

避免逆矩阵的原因只与效率有关。直接求解线性系统更快。如果您对链接问题中的问题有一点不同的看法,您可以应用相同的原则。

为了找到矩阵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 是对称的。 (可能有一种方法可以有效地从 K 得到 T(K) 的分解,但我不知道)

如果 K 是对称的,那么您可以在 K 上计算一次分解并将其重复用于两个反向替换步骤,这可能比显式计算逆运算更有效。