2017-01-25 15 views
3

Мой друг и я выполнил эти строки кода в Python 2 и Python 3:Numpy инвертирует необратимая матрица

import numpy as np 
mat = np.array([[1,0,0],[-1,3,3],[1,2,2]]) 
np.linalg.inv(mat) 

который возвращает:

array([[ 1.00000000e+00, 0.00000000e+00, 0.00000000e+00], 
    [ 1.50119988e+16, 6.00479950e+15, -9.00719925e+15], 
    [ -1.50119988e+16, -6.00479950e+15, 9.00719925e+15]]) 

Что странно Дано:

np.linalg.matrix_rank(mat) 

возвращает 2, что указывает на то, что матрица равна не обратимый.

Я понимаю из этой темы, что, вероятно, связано с тем, как numpy и python обрабатывают числа с плавающей запятой, хотя моя матрица состоит из целых чисел.

Есть ли какая-то особая причина, почему mat нарушает обратную реализацию numpy?

+0

Просьба уточнить: Вы имеете в виду «матрица _invertible_» или «матрица не _invertible_»? – DyZ

ответ

1

Звание = 2 означает, что матрица не обратимо. Для матрицы 3х3 обратимым, его ранг должен быть 3.

+1

Возможно, это была опечатка на части OPs. Похоже, что возникает вопрос: почему Python инвертирует матрицу с не полным ранга? – Akavall

+1

@Akavall Непонятно. На самом деле, NumPy 1.10.4 не инвертирует его: 'numpy.linalg.linalg.LinAlgError: Singular matrix' – DyZ

+1

Интересно, что я смог воспроизвести результаты OP с' 1.12.0' – Akavall

2

Как DYZ отметил, матрица не является обратимым, потому что это ранг 2 не 3.

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

Обратите внимание, что произведенное «инверсное» не в порядке. Поэтому, если вы попытаетесь использовать его для решения систем линейных уравнений, это, скорее всего, даст вам множество NaN и Infs.

Я думаю, что numpy не проверяет качество результатов, которое является общим для библиотек высокой производительности. Вы можете сделать такую ​​проверку очень дешево, умножив исходную матрицу на предполагаемый обратный и проверив, близки ли цифры по диагонали к 1, а другие числа - нулями. Они не обязательно будут в точности равны нулю или одному из-за характера вычислений с плавающей точкой

Поскольку DSM указал, что ваша матрица действительно высока, condition number.

Таким образом, вы теряете 16 цифр точности из-за такой плохо подготовленной матрицы. Помимо ошибок, вызванных неточностями с плавающей запятой.

Кстати, как другие указывали выше ваш пример не работает в Numpy 1.12.0

>>> import numpy as np 
>>> np.version.version 
'1.12.0' 

>>> import numpy as np 
>>> mat = np.array([[1,0,0],[-1,3,3],[1,2,2]]) 
>>> np.linalg.inv(mat) 
Traceback (most recent call last): 
    File "/Users/vlad/.pyenv/versions/CourseraDL/lib/python3.4/site-packages/numpy/linalg/linalg.py", line 90, in _raise_linalgerror_singular 
    raise LinAlgError("Singular matrix") 
numpy.linalg.linalg.LinAlgError: Singular matrix 
>>> 
+1

Возможно, также стоит упомянуть номер условия, который очень велик для этой матрицы. – DSM