numpy.linalg.inv возвращает инверсию для сингулярной матрицы

Приведенная ниже матрица является сингулярной, и AFAIK попытка инвертировать ее должна привести к

numpy.linalg.linalg.LinAlgError: Singular matrix

но вместо этого я получаю некоторую выходную матрицу. Обратите внимание, что выходная матрица - это бессмысленный результат, потому что в ней есть строка нулей (что невозможно, поскольку обратная матрица сама должна быть обратимой)!

Мне здесь не хватает чего-то, связанного с точностью с плавающей запятой или вычислением псевдообратного, а не истинного обратного?

$ 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]])```

person niklas    schedule 09.09.2017    source источник
comment
Я получаю numpy.linalg.linalg.LinAlgError: Singular matrix (numpy 1.11.3).   -  person DYZ    schedule 09.09.2017


Ответы (2)


За кулисами NumPy и SciPy (и многие другие программы) возвращаются к реализациям LAPACK (или переводам на C) решателей линейных уравнений (в данном случае GESV).

Поскольку GESV сначала выполняет разложение LU, а затем проверяет диагональ матрицы U на наличие точных нулей, очень трудно найти точные нули в разложениях. Вот почему вы не получаете сингулярную матричную ошибку.

Кроме того, вы никогда не должны инвертировать матрицу, если вы умножаете ее на другие матрицы, а вместо этого решаете для AX=B.

В SciPy, начиная с версии 0.19, scipy.linalg.solve использует «экспертный» драйвер GESVX из GESV, который также сообщает номер условия и выдает предупреждение. Это похоже на поведение Matlab в случае пропуска особенности.

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]])
person percusse    schedule 09.09.2017

Одно замечание от команды numpy:

Де-факто соглашение в этой области состоит в том, что ошибки в инверсии матрицы в основном игнорируются - предполагается, что пользователь знает, нужно ли это проверять (подразумевая, что необходимо использовать более контролируемый приближенный метод инверсии). использовано --- регуляризация зависит от проблемы).

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

Кажется, выдает ошибку на 1.13.0, однако

person ionox0    schedule 09.09.2017
comment
Очень актуально, спасибо. Основываясь на этом потоке, это действительно похоже на проблему, связанную с точностью, хотя это заставляет меня задаться вопросом, при каких обстоятельствах numpy успешно обнаружит сингулярную матрицу и почему эта конкретная (и небольшая) матрица не работает ... - person niklas; 09.09.2017