2015-03-18 1 views
1

J'essaie de générer la matrice inverse en utilisant le paquetage numpy dans python. Malheureusement, je ne reçois pas les réponses que j'attendais.Comment calculer l'inverse en utilisant la règle de cramer en python?

matrice d'origine:

([17 17 5] [21 18 21] [2 2 19])

originale inversion de la matrice par la règle de Cramer donne:

([4 9 15] [15 17 6] [24 0 17])

Apparemment en utilisant numpy.linalg.inv() donne

-3.19488818e-01,3.80191693e-01,-6.38977636e-03, 3.33333333e-01, -3.33333333e-01, 2.26123699e-18, -2.84345048e-01, 2.68370607e-01, 5.43130990e-02n

Je pensais que multiplier la matrice originale et l'inverse aurait donné une matrice d'identité mais comme vous pouvez le voir, je donne une matrice remplie de points flottants.

Où peut-être le problème?

+0

Je ne pense pas que votre application de la règle de Cramer puisse avoir donné la matrice inverse correcte ici (qu'obtenez-vous si vous la multipliez par la matrice originale?) – xnx

+0

'array ([[1.00000000e + 00, 0.00000000e +00, 1,05471187e-15], [1.11022302e-16, 1.00000000e + 00, -7.21644966e-16], [1.38235777e-17, 5.65818009e-18, 1.00000000e + 00]]) ' – She

Répondre

0

Je pense que vous avez peut-être fait une erreur en inversant la matrice à la main.

Quand j'effectuez les opérations suivantes

import numpy as np 

a = np.array([[17, 17, 5], [21, 18, 21], [2, 2, 19]], dtype=np.float) 
inv = np.linalg.inv(a) 

print np.dot(inv, a) 

Je reçois

array([[ 1.00000000e+00, 0.00000000e+00, 1.05471187e-15], 
     [ 1.11022302e-16, 1.00000000e+00, -7.21644966e-16], 
     [ 1.38235777e-17, 5.65818009e-18, 1.00000000e+00]]) 

Ce qui est bien, notez que tous les éléments diagonaux sont à peu près zéro à la précision de la machine de sorte qu'il ressemble numpy fait une ok travail avec celui-ci! Rappelez-vous que les nombres à virgule flottante ne fonctionnent pas comme les nombres réels et vous pouvez vous attendre à ce que de petites erreurs d'arrondi se glissent dans vos calculs, sauf si vous faites attention.


Si vous voulez faire exactement ont un oeil à sympy qui sera en mesure de faire le calcul avec les mathématiques exactes (au détriment de celui-ci étant un peu plus lent).

import sympy as sp 

a = sp.Matrix([[17, 17,5],[21,18,21],[2,2,19]]) 
inv = a.inv() 

print inv 
print a * inv 

qui donne exactement l'inverse

Matrix([ 
[-100/313, 1/3, -89/313], 
[ 119/313, -1/3, 84/313], 
[ -2/313, 0, 17/313]]) 

qui, lorsqu'il est multiplié par la matrice d'origine donne l'identité exacte que vous attendez

Matrix([ 
[1, 0, 0], 
[0, 1, 0], 
[0, 0, 1]]) 
+0

i suis dans une situation où j'effectue result = matrice * vectorA et résultat * inverse (matrice) devrait donner vectorA exactement (chose de chiffrement-déchiffrement). Mais ce n'est pas le cas en raison des nombres à virgule flottante. Y at-il une alternative? – She

+0

Numpy effectuera uniquement des calculs matriciels sur des nombres à virgule flottante. Il semble que vous ayez besoin de le calculer en utilisant des rationnels. Jetez un oeil à [sympy] (http://www.sympy.org/en/index.html) qui devrait être en mesure de le faire pour vous. –

+0

J'ai édité ma réponse pour donner un exemple de faire la même chose en sympy pour vous. –

0

linalg est à droite et vous avez tort.

La matrice qu'il vous a donné est en effet l'inverse. Toutefois, si vous utilisez np.array au lieu de np.matrix, l'opérateur de multiplication ne fonctionne pas comme prévu, car il calcule le produit par composant.

Dans ce cas, vous devez faire mat.dot(inv(mat)).

En tout cas, ce que vous obtiendrez ne sera pas une matrice d'identité parfaite en raison d'erreurs d'arrondi (quand je l'ai essayé, les entrées matricielles hors diagonales étaient de l'ordre de 10 ** (-16)).

+0

je suppose mais j'ai besoin de ceci pour des fins de décryptage de chiffrage. En raison des nombres de virgule flottante mes résultats dévient beaucoup. – She

0

Votre supposé inverse est évidemment faux; les uns ne peuvent être atteints que si certaines entrées de la matrice inverse sont inférieures à un et les zéros seulement si certaines entrées sont négatives. Je n'ai pas vu ce que tu fais de mal, alors je donne un exemple. En utilisant Cramer's rule vous avez par exemple. pour la première entrée (18 * 19 - 2 * 21)/(- 939) = -0,319 ... - exactement ce que l'on a trouvé.