Python numpy.linalg.inv()是否给出了正确的矩阵逆?编辑:为什么inv()会给出数字错误?

Python numpy.linalg.inv()是否给出了正确的矩阵逆?编辑:为什么inv()会给出数字错误?,python,numpy,matrix,matrix-inverse,Python,Numpy,Matrix,Matrix Inverse,我有一个矩阵形状(40004000),我想取相反的。(我对矩阵求逆的直觉在如此大的矩阵中崩溃了。) 起始矩阵的值为e-10,具有以下值:打印矩阵给出输出 [[ 2.19885119e-10 2.16462810e-10 2.13062782e-10 ..., -2.16462810e-10 -2.19885119e-10 -2.16462810e-10] [ 2.16462810e-10 2.19885119e-10 2.16462810e-10 ..., -2

我有一个矩阵形状(40004000),我想取相反的。(我对矩阵求逆的直觉在如此大的矩阵中崩溃了。)

起始矩阵的值为
e-10
,具有以下值:
打印矩阵
给出输出

[[  2.19885119e-10   2.16462810e-10   2.13062782e-10 ...,  -2.16462810e-10
   -2.19885119e-10  -2.16462810e-10]
 [  2.16462810e-10   2.19885119e-10   2.16462810e-10 ...,  -2.13062782e-10
   -2.16462810e-10  -2.19885119e-10]
 [  2.13062782e-10   2.16462810e-10   2.19885119e-10 ...,  -2.16462810e-10
   -2.13062782e-10  -2.16462810e-10]
 ..., 
 [ -2.16462810e-10  -2.13062782e-10  -2.16462810e-10 ...,   2.19885119e-10
    2.16462810e-10   2.13062782e-10]
 [ -2.19885119e-10  -2.16462810e-10  -2.13062782e-10 ...,   2.16462810e-10
    2.19885119e-10   2.16462810e-10]
 [ -2.16462810e-10  -2.19885119e-10  -2.16462810e-10 ...,   2.13062782e-10
    2.16462810e-10   2.19885119e-10]]
然后我使用NumPy的NumPy.linalg.inv()来反转矩阵

import numpy as np
new_matrix = np.linalg.inv(matrix)
print new_matrix
这是我得到的回报:

[[  1.95176541e+25   9.66643852e+23  -1.22660930e+25 ...,  -1.96621184e+25
   -9.41413909e+24   1.33500310e+25]
 [  2.01500967e+25   1.08946558e+24  -1.25813014e+25 ...,  -2.07717912e+25
   -9.86804459e+24   1.42950556e+25]
 [  3.55575106e+25   2.11333704e+24  -2.25333936e+25 ...,  -3.68616202e+25
   -1.72651875e+25   2.51239524e+25]
 ..., 
 [  3.07255588e+25   1.61759838e+24  -1.95678425e+25 ...,  -3.15440712e+25
   -1.47472306e+25   2.13570651e+25]
 [ -7.24380790e+24  -8.63730581e+23   4.90519245e+24 ...,   8.30663797e+24
    3.70858694e+24  -5.32291734e+24]
 [ -1.95760004e+25  -1.12341031e+24   1.23820305e+25 ...,   2.01608416e+25
    9.40221886e+24  -1.37605863e+25]]
这是一个巨大的差异!怎么可能呢?大小矩阵
e-10
被转换为大小矩阵
e+25

这在数学上是正确的,还是IEEE浮点值出现了故障

如果这在数学上是正确的,有人能给我解释一下这背后的数学直觉吗

编辑:

根据下面的评论,我决定进行测试

np.dot(矩阵,新矩阵)
应该给出单位矩阵,A*A^T=identity

这是我的输出:

[[  0.   -3.  -16.  ...,  16.    8.   12. ]
 [-24.   -1.5  -8.  ...,  32.   -4.   36. ]
 [ 40.    1.  -64.  ...,  24.   20.   24. ]
 ..., 
 [ 32.   -0.5  48.  ..., -16.  -20.   16. ]
 [ 40.    7.   16.  ..., -48.  -36.  -28. ]
 [ 16.    3.   12.  ..., -80.   16.    0. ]]
为什么
numpy.linalg.inv()
会导致数字错误

np.allclose( np.dot(matrix, new_matrix), np.identity(4000) )

给出

对于两个矩阵的行列式

det(A) * det(A^{-1}) = 1
因此,如果
det(A)
很大,那么
det(A^{-1})
很小。对于2个矩阵的范数(如果选择次乘法范数),您可以:

其中| |是次乘法范数的合理选择。在这里,你可以直观地观察到数值上的结果:如果>=符号实际上是a~=,那么你可以恢复与行列式完全相同的观察结果

同样的道理适用于如果考虑产品

A * A^{-1} = 1
对于包含所有正元素的矩阵
a
。对于RHS处
1
对角线上的元素,如果
A
的元素非常大,则需要
A^{-1}
中非常小的数字

PS:但是请注意,这并不能证明这一趋势总是成立的。这只是提供了数学直觉,说明了为什么要观察这种缩放

编辑,作为对评论的答复:

最初的问题是“如果这在数学上是正确的,有人能给我解释一下这背后的数学直觉吗?”。事实上,在数学上正确且合理的是,给定一个具有小数值的矩阵,逆矩阵将具有大数值。上面我解释了为什么会这样

回答OP编辑中出现的另一个问题,这就是为什么
inv()
会导致数值错误:矩阵求逆是一个困难的问题。这就是为什么每次我们可以避免反转它们的原因。例如,对于这个问题

A x = b

我们不计算
A
的逆,而是使用其他算法(在实践中,您可以调用python作为例子)。

您的矩阵是病态的,因为

np.linalg.cond(matrix) > np.finfo(matrix.dtype).eps

根据你可以考虑使用逆矩阵。< /P>什么是行列式(<代码> NUPY.LIALG.DET(m)< /代码>)和矩阵的条件号(<代码> NUMPY.LIALG.COND(m)< /代码>)?如果矩阵的行列式为零,则它不具有逆。你真的确定A上的零行列式是错误的吗?我用400x400的随机数矩阵做了一些测试,它可以工作,但由于浮点运算,有一些小错误。@Sauruxum numpy.linalg.det()经常给出错误的答案。该操作首先执行slogdet(),然后执行指数运算。请参阅代码。同样,矩阵也有一个逆矩阵。没有理由不。@RobFoley不,是什么让你有这个想法的?Python和numpy都使用标准的IEEE浮点。您真的需要反转矩阵吗?如果你试图解一个线性方程组,那就使用

np.linag.solve
来计算解,而不是直接求逆矩阵。如果这是正确的,我的测试应该是取乘积,对吗?原始矩阵是
矩阵
。逆矩阵是新矩阵。因此,
np.dot(matrix,new_matrix)
应该给我们单位矩阵,对吗?应该,除非你碰到了数字错误。例如,从numpy.random导入rand尝试
;来自scipy.linalg进口投资部;A=兰特(4,4);打印(点(A,inv(A))
得到一个酉矩阵。看看什么是预条件。我建议不要反转矩阵,这取决于您试图解决的问题。@rth“您不能使用
scipy.linalg.solve
反转矩阵”-当然可以!事实上,
np.linalg.inv
就是这样工作的(它相当于
np.linalg.solve(A,np.eye(A.shape[0]))
)。至少在当前的numpy开发版本中,
inv
也使用
gesv
。请参阅-在
inv
中使用的
lapack\u func
gesv
-它只是传递一个身份矩阵作为“B”参数。它应该取决于数组的数据类型的epsilon(即
np.finfo(matrix).eps),它可能与
sys.float\u info.epsilon
不同,这应该是
np.finfo(matrix.dtype).eps
np.linalg.cond(matrix) > np.finfo(matrix.dtype).eps