numpy.linalg.inv返回奇异矩阵的逆函数
下面的矩阵是单数,并且AFAIK尝试将其求反应该导致
The matrix below is singular, and AFAIK attempting to invert it should result in
numpy.linalg.linalg.LinAlgError: Singular matrix
但是,我得到了一些输出矩阵.请注意,输出矩阵是无意义的结果,因为它具有一行0(这是不可能的,因为矩阵的逆本身应该是可逆的)!
but instead, I do get some output matrix. Note that output matrix is a non-sensical result, because it has a row of 0's (which is impossible, since an inverse of a matrix should itself be invertible)!
我在这里是否缺少一些与浮点精度有关的东西,或者是与真实逆相反的伪逆的计算?
Am I missing something here related to floating point precision, or the computation of a pseudoinverse as opposed to a true inverse?
$ np.__version__
'1.13.1'
$ np.linalg.inv(np.array([[2,7,7],[7,7,7],[8,7,7]]))
array([[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 3.43131400e+15, -2.05878840e+16, 1.71565700e+16],
[ -3.43131400e+15, 2.05878840e+16, -1.71565700e+16]])```
在后台,NumPy和SciPy(以及许多其他软件)都退回到线性方程求解器的LAPACK实现(或C转换)(在本例中为
Behind the scenes, NumPy and SciPy (and many other software) fall back to LAPACK implementations (or C translations) of linear equation solvers (in this case GESV
).
由于GESV
首先执行LU分解,然后检查U
矩阵的对角线是否有确切的零,因此很难在分解中达到完全零.这就是为什么您不会遇到奇异矩阵错误的原因.
Since GESV
first performs a LU decomposition and then checks the diagonal of U
matrix for exact zeros, it is very difficult to hit perfect zeros in the decompositions. That's why you don't get a singular matrix error.
此外,如果要与其他矩阵相乘,则永远不要求逆矩阵,而是求解AX=B
.
Apart from that you should never ever invert a matrix if you are multiplying with other matrices but instead solve for AX=B
.
在SciPy自0.19版本开始,scipy.linalg.solve
使用GESV
的专家"驱动程序GESVX
,该驱动程序还会报告条件编号并发出警告.如果缺少奇点,这类似于matlab的行为.
In SciPy since version 0.19, scipy.linalg.solve
uses the "expert" driver GESVX
of GESV
which also reports back condition number and a warning is emitted. This is similar to matlab behavior in case the singularity is missed.
In [7]: sp.linalg.solve(np.array([[2,7,7],[7,7,7],[8,7,7]]), np.eye(3))
...\lib\site-packages\scipy\linalg\basic.py:223: RuntimeWarning: scipy.linalg.solve
Ill-conditioned matrix detected. Result is not guaranteed to be accurate.
Reciprocal condition number: 1.1564823173178713e-18
' condition number: {}'.format(rcond), RuntimeWarning)
Out[7]:
array([[ 0.00000000e+00, -1.00000000e+00, 1.50000000e+00],
[ 3.43131400e+15, -2.05878840e+16, 1.71565700e+16],
[ -3.43131400e+15, 2.05878840e+16, -1.71565700e+16]])