6

The matrix below is singular, and AFAIK attempting to invert it should result in

numpy.linalg.linalg.LinAlgError: Singular matrix

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]])```
smci
  • 32,567
  • 20
  • 113
  • 146
niklas
  • 81
  • 1
  • 4

2 Answers2

7

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

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.

Apart from that you should never ever invert a matrix if you are multiplying with other matrices but instead solve for AX=B.

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]])
percusse
  • 3,006
  • 1
  • 14
  • 28
3

One note from the numpy team:

The de-facto convention in the field is that errors in matrix inversion are mostly silently ignored --- it is assumed that the user knows if this is something that needs to be checked for (implying that a more controlled approximate inversion method needs to be used --- the regularization is problem-dependent).

https://github.com/numpy/numpy/issues/2074

Seems to give an error on 1.13.0 however

ionox0
  • 1,101
  • 2
  • 14
  • 21
  • Very relevant, thanks. Based on that thread, it does sound like a precision-related issue, though that makes me wonder under what circumstances numpy will successfully detect a singular matrix, and why this specific (and small) matrix fails... – niklas Sep 09 '17 at 03:26