没有使用lu分解来求解奇异方阵?

时间:2017-10-03 22:19:04

标签: python scipy linear-algebra matrix-factorization

我有奇异矩阵A(10 * 10),它是秩不足的(秩= 9),我有矢量b,它在A的范围空间中。现在我对Ax = b的某些解决方案感兴趣。具体来说,这是我的A

array([[ 0.        ,  0.        ,  0.        ,  0.86826141,  0.        ,
             0.        ,  0.88788426,  0.        ,  0.4089203 ,  0.88134901],
           [ 0.        ,  0.        ,  0.46416372,  0.        ,  0.        ,
             0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  0.        ,  0.        ,  0.        ,  0.31303966,
             0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
             0.        ,  0.3155742 ,  0.        ,  0.64059294,  0.        ],
           [ 0.        ,  0.        ,  0.        ,  0.        ,  0.51349938,
             0.        ,  0.        ,  0.        ,  0.53593509,  0.        ],
           [ 0.        ,  0.01252787,  0.        ,  0.6870415 ,  0.        ,
             0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
             0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.        ,  0.        ,  0.        ,  0.16643105,  0.        ,
             0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
           [ 0.08626592,  0.        ,  0.        ,  0.        ,  0.        ,
             0.        ,  0.        ,  0.        ,  0.        ,  0.66939531],
           [ 0.43694586,  0.        ,  0.        ,  0.        ,  0.        ,
             0.95941661,  0.        ,  0.52936733,  0.79687149,  0.81463887]])

b使用A.dot(np.ones(10))生成。现在我想用lu分解来解决这个问题,为此我在

之后做了这个
lu_fac=scipy.linalg.lu_factor(X)
scipy.linalg.lu_solve(lu_fac,b)

哪个给出了

array([ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan])

在这种情况下,lu_factor似乎工作得很好(有时它会给运行时警告说"对角线数字%d正好为零。奇异矩阵" )。为了完整起见,从lu_factor验证PLU的代码与A:

相同
L=np.tril(lu_fac[0])
np.fill_diagonal(L,1)
U=np.triu(lu_fac[0])
perm=np.arange(10)
ipiv=lu_factor[1]
for i in range(10):
  temp=perm[i]
  perm[i]=perm[ipiv[i]]
  perm[ipiv[i]]=temp
np.allclose(X[perm,:],L.dot(U))

现在我知道我的矩阵是单数的,我的问题有很多解决方案。但是我对任何解决方案感兴趣而且我很困惑为什么lu分解失败,是否可以将自由变量设置为0并找到一些解决方案,因为我们被教导了?还有什么是运行时警告的处理"对角线数字%d恰好为零。奇异矩阵" 。注意我对svd / qr方法没有兴趣解决这个问题,我只是想知道为什么lu失败了奇异矩阵。任何建议都非常感谢。感谢。

2 个答案:

答案 0 :(得分:1)

0 / lu_fac[0][9, 9]

返回nan,因为该条目 - U的最后一个对角线条目为零。所以这个nan成为第9个变量的值。然后它在上面的等式中被替换,当然,其余部分也以nan出现。 SciPy的LU代码,或者更确切地说是它包含的Fortran代码,不是为缺乏秩的矩阵而设计的,所以它不会为无法确定的变量组成值。

  

还有什么是运行时警告的处理“对角线数字%d恰好为零。奇异矩阵”。

警告很明显:算法检测到一个奇异矩阵,这是不期望的。它还告诉您,该实现不适用于奇异矩阵。

  

具有在范围空间A

中的向量b

理论上这是。在实践中,由于浮点算术中固有的错误,人们不能确定任何位于秩缺陷矩阵的范围空间中的东西。您可以计算b = A.dot(...),然后尝试解决Ax = b,并且由于操作浮点数时引入的错误,将不会有解决方案。

顺便说一下:你提到每个方阵都存在PLU因子分解,但SciPy并不一定是为计算它而设计的。例如,

scipy.linalg.lu_factor(np.array([[0, 1], [0, 0]]))

返回带有NaN的矩阵。在您的情况下,NaN在尝试找到解决方案并遇到因子U的零对角线元素时会出现。

答案 1 :(得分:0)

如上所述here,当且仅当rank(A11) + k >= rank([A11 A12]) + rank([A11 A21])时,矩阵具有LU分解。在您的情况下,rank(A11) = 3k = 5,  和rank([A11 A12]) + rank([A11 A21]) = 9。因此,矩阵不满足条件,并且没有LU分解。