Python numpy.linalg.inv()是否给出了正确的矩阵逆?编辑:为什么inv()会给出数字错误?
我有一个矩阵形状(40004000),我想取相反的。(我对矩阵求逆的直觉在如此大的矩阵中崩溃了。) 起始矩阵的值为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
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