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您分解一次,重复使用两个回代步骤,它可能比明确计算逆矩阵更有效。