2017-01-25 1 views
3

Mon ami et moi exécuté ces lignes de code dans Python 2 et Python 3:Numpy intervertit une matrice non inversible

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

qui retourne:

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

Ce qui est étrange donné:

np.linalg.matrix_rank(mat) 

renvoie 2, indiquant ainsi que la matrice est pas inversible. Je comprends de ce fil qui est probablement dû à la façon dont numpy et python manipulent des nombres de virgule flottante, bien que ma matrice soit composée de nombres entiers.

Y a-t-il une raison particulière pour laquelle mat casse l'implémentation inverse de numpy? Rang = 2 signifie que la matrice est et non inversible

+0

S'il vous plaît préciser: voulez-vous dire « matrice est _invertible_ » ou « matrice n'est pas _invertible_ »? – DyZ

Répondre

1

Pour une matrice 3x3 soit inversible, son rang doit être 3.

+1

C'était probablement une faute de frappe sur la partie OPs. Il semble que la question est la suivante: pourquoi Python inverse-t-il une matrice sans rang complet? – Akavall

+1

@Akavall Pas clair. En fait, NumPy 1.10.4 ne l'inverse pas: 'numpy.linalg.linalg.LinAlgError: Singular matrix' – DyZ

+1

Intéressant, j'ai été capable de reproduire les résultats OP avec' 1.12.0' – Akavall

2

Comme DYZ a souligné la matrice est pas inversible, car il est le rang est 2 pas 3.

La raison pour laquelle vous obtenez ces résultats est parce que numpy est en utilisant LU decomposition pour calculer l'inverse. Cet algorithme peut donner des résultats même dans les cas où votre matrice est singulière. Lire l'article wikipedia lié si vous êtes intéressé par les détails.

Notez que 'inverse' produit est détraqué. Donc, si vous essayez de l'utiliser pour résoudre des systèmes d'équations linéaires, il vous donnera probablement beaucoup de NaNs et d'Infs.

Je suppose que numpy ne vérifie pas la qualité des résultats qui est commune pour les bibliothèques haute performance. Vous pouvez le faire vous-même à très bon marché en multipliant votre matrice originale par l'inverse supposé et en vérifiant si les nombres en diagonale sont proches de 1 et les autres nombres sont des zéros. Ils ne seront pas nécessairement égaux à zéro ou un à cause de la nature du calcul en virgule flottante

Comme l'a souligné DSM, le condition number de votre matrice est vraiment élevé. Donc, vous perdez 16 chiffres de précision dus à cette matrice mal conditionnée. En plus de l'erreur provoquée par l'imprécision en virgule flottante.

D'ailleurs que d'autres ont souligné ci-dessus votre exemple ne fonctionne pas dans 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

Pourrait également mentionner le numéro de condition, qui est très grand pour cette matrice. – DSM