如何使用奇异值分解反转numpy矩阵?

时间:2015-07-06 17:07:34

标签: python numpy matrix linear-algebra

(在你告诉我之前,是的,我知道你应该从不反转矩阵。不幸的是我的计算,我有一个矩阵,我已经构建了,它必须以某种方式反转。)< / p>

我有一个很大的矩阵Mnumpy.linalg.cond(M)输出幅度为e+22的值。矩阵M的形状为(1000,1000)

当然,numpy.linalg.inv()会导致许多精度错误。所以,我使用numpy.linalg.solve()来反转矩阵。

考虑矩阵逆A^{-1}A * A^{-1} = Identity定义。 numpy.linalg.solve()计算确定的,即满秩,线性矩阵方程ax = b的“精确”解x。

所以,我定义了单位矩阵:

import numpy as np
iddmatrix = np.identity(100)

并解决:

inverse = np.linalg.solve(M, iddmatrix)

但是,因为我的矩阵是所以大而所以病态,np.linalg.solve()不会给出“确切的解决方案”。我需要另一种方法来反转矩阵。

  1. 用SVD实现这种反转的标准方法是什么?
  2. 我怎么能制作这种病态的矩阵......定义明确?
  3. 任何建议都表示赞赏。谢谢!

3 个答案:

答案 0 :(得分:2)

由于SVD将矩阵 A 分解为 U * S * V ,其中 S 为对角线, U V 是正交的,它的逆是 V&#39; * inv(S)* U&#39; ,而对角矩阵的逆是数字的倒数在主对角线上。

>>> A=np.random.rand(1000,1000)
>>> u,s,v=np.linalg.svd(A)
>>> Ainv=np.dot(v.transpose(),np.dot(np.diag(s**-1),u.transpose()))

答案 1 :(得分:2)

@mescalinium有一个错误:点积的第一个参数应该是v.transponse()

import numpy as np
from numpy.linalg import inv

def mysolve(A):
    u, s, v = np.linalg.svd(A)
    Ainv = np.dot (v.transpose(), np.dot(np.diag(s**-1),u.transpose()))
    return(Ainv)

    temp = np.random.rand(1000,1000)
    np.allclose(svdsolve(temp) , inv(prova[2]))
>>> True

np.linalg.solve将初始矩阵分解为A = USV,因此倒数只是V'S ^( - 1)U'

答案 2 :(得分:1)

考虑采用矩阵的SVD实际意味着什么。这意味着对于某些矩阵M,我们可以将其表示为M=UDV*(这里让我们让*表示转置,因为我没有看到在堆栈溢出中这样做的好方法。)

if M=UDV*:
  then: M^-1 = (UDV*)^-1 = (V*^-1)(D^-1)(U^-1)

但是由于U列是MM*V列的特征值是M\*M的特征值,因此这些矩阵的逆是这样的。是他们自己的转座(因为特征向量是正交的)。所以我们得到:M^-1 = V(D^-1)U*。采用对角矩阵的逆矩阵就像采用每个元素的乘法逆矩阵一样容易。

更好的排版(种类):http://adrianboeing.blogspot.com/2010/05/inverting-matrix-svd-singular-value.html