【问题标题】:Matrix Inversion Methods矩阵求逆方法
【发布时间】:2017-11-24 21:17:24
【问题描述】:

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

可以对 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 提供了一个此类问题的示例。

【问题讨论】:

  • 我认为这篇文章属于math stack-exchange。 SO 用于编程问题。
  • 我确实想知道。但是,由于在代码中实现此类矩阵方程时存在数值稳定性问题,我觉得它适合这里。在纸上处理这样的矩阵方程时,逆是可以接受的(有时是不可避免的)。因此,我认为这是一个编程问题。
  • 我不记得听说过矩阵逆是一个不适定问题,计算逆然后将逆乘以矩阵(或向量)的效率较低。当然,某些矩阵是病态的(可以通过它们的条件数来估计),但是对于这些矩阵,您根本无能为力。
  • 好的,那么对于条件良好的矩阵,反演就可以了吗?

标签: linear-algebra numerical-methods scientific-computing matrix-inverse


【解决方案1】:

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

为了找到矩阵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 上计算一次分解并将其重复用于两个反向替换步骤,这可能比显式计算逆更有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2011-08-30
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多