(在你告诉我之前,是的,我知道你应该从不反转矩阵。不幸的是我的计算,我有一个矩阵,我已经构建了,它必须以某种方式反转。)< / p>
我有一个很大的矩阵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)
但是,因为我的矩阵是所以大而所以病态,np.linalg.solve()
不会给出“确切的解决方案”。我需要另一种方法来反转矩阵。
任何建议都表示赞赏。谢谢!
答案 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