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

How to invert numpy matrices using Singular Value Decomposition?

(在你告诉我之前,是的,我知道你应该 永远不要 反转矩阵。不幸的是,对于我的计算,我有一个我构建的矩阵,它必须是以某种方式颠倒了。)

我有一个很大的矩阵 M,它是病态的。 numpy.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)

但是,因为我的矩阵 so 大而 so 病态,np.linalg.solve() 不会给出 "exact solution"。我需要另一种方法来反转矩阵。

  1. 用 SVD 实现这种逆的标准方法是什么?
  2. 我怎样才能使这个病态矩阵....定义明确?

如有任何建议,我们将不胜感激。谢谢!

由于 SVD 将矩阵 A 分解为 U*S*V,其中 S是对角线,UV是正交的,它的逆是V'*inv(S)*U',对角矩阵的逆就是主对角线上数字的逆。

>>> 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()))

考虑一下矩阵的 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

点积的第一个参数应该是v.transpose():

import numpy as np
from numpy.linalg import inv

def svdsolve(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(temp))
>>> True

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