Python inverse van een matrix

Hoe krijg ik de inverse van een matrix in python? Ik heb het zelf geïmplementeerd, maar het is pure python en ik vermoed dat er snellere modules zijn om het te doen.


Antwoord 1, autoriteit 100%

Je zou numpymoeten bekijken als je matrixmanipulatie uitvoert. Dit is een module die voornamelijk in C is geschreven en die veel sneller zal zijn dan programmeren in pure python. Hier is een voorbeeld van hoe u een matrix kunt omkeren en andere matrixmanipulatie kunt uitvoeren.

from numpy import matrix
from numpy import linalg
A = matrix( [[1,2,3],[11,12,13],[21,22,23]]) # Creates a matrix.
x = matrix( [[1],[2],[3]] )                  # Creates a matrix (like a column vector).
y = matrix( [[1,2,3]] )                      # Creates a matrix (like a row vector).
print A.T                                    # Transpose of A.
print A*x                                    # Matrix multiplication of A and x.
print A.I                                    # Inverse of A.
print linalg.solve(A, x)     # Solve the linear equation system.

Je kunt ook de module arraybekijken, een veel efficiëntere implementatie van lijsten wanneer u met slechts één gegevenstype te maken heeft.


Antwoord 2, autoriteit 52%

Zorg ervoor dat u de matrix echt moet omkeren. Dit is vaak niet nodig en kan numeriek instabiel zijn. Wanneer de meeste mensen vragen hoe ze een matrix moeten omkeren, willen ze echt weten hoe ze Ax = b kunnen oplossen waarbij A een matrix is ​​en x en b vectoren zijn. Het is efficiënter en nauwkeuriger om code te gebruiken die de vergelijking Ax = b voor x direct oplost dan om A-inverse te berekenen en vervolgens de inverse met B te vermenigvuldigen. Zelfs als u Ax = b voor veel b-waarden moet oplossen, is het geen goed idee om A om te keren. Als je het systeem moet oplossen voor meerdere b-waarden, sla dan de Cholesky-factorisatie van A op, maar keer het niet om.

Zie Keer die matrix niet om.


Antwoord 3, autoriteit 9%

Het is jammer dat de gekozen matrix, hier nogmaals herhaald, ofwel enkelvoudig ofwel slecht geconditioneerd is:

A = matrix( [[1,2,3],[11,12,13],[21,22,23]])

Per definitie moet de inverse van A, vermenigvuldigd met de matrix A zelf, een eenheidsmatrix opleveren. De in de veelgeprezen uitleg gekozen A doet dat niet. In feite geeft alleen al het kijken naar de inverse een aanwijzing dat de inversie niet correct werkte. Kijk naar de omvang van de afzonderlijke termen – ze zijn erg, erg groot vergeleken met de termen van de originele A-matrix…

Het is opmerkelijk dat de mensen bij het kiezen van een voorbeeld van een matrix er zo vaak in slagen om een ​​enkelvoudige matrix te kiezen!

Ik had wel een probleem met de oplossing, dus heb ik er verder naar gekeken. Op het ubuntu-kubuntu-platform heeft het debian-pakket numpy niet de matrix en de linalg-subpakketten, dus naast het importeren van numpy, moet scipy ook worden geïmporteerd.

Als de diagonale termen van A worden vermenigvuldigd met een factor die groot genoeg is, zeg 2, zal de matrix hoogstwaarschijnlijk ophouden singulier of bijna singulier te zijn. Dus

A = matrix( [[2,2,3],[11,24,13],[21,22,46]])

wordt noch enkelvoud, noch bijna enkelvoud en het voorbeeld geeft zinvolle resultaten… Bij het omgaan met zwevende getallen moet men oppassen voor de effecten van onvermijdelijke afrondingsfouten.


Antwoord 4, autoriteit 6%

Voor degenen zoals ik, die op zoek waren naar een pure Python-oplossing zonder dat pandasof numpyerbij betrokken waren, bekijk dan het volgende GitHub-project: https://github.com/ThomIves/MatrixInverse.

Het biedt genereus een zeer goede uitleg van hoe het proces er “achter de schermen” uitziet. De auteur heeft de stapsgewijze aanpak mooi beschreven en enkele praktische voorbeelden gegeven, allemaal gemakkelijk te volgen.

Dit is slechts een klein stukje code om de aanpak heel kort te illustreren (AMis de bronmatrix, IMis de identiteitsmatrix van dezelfde grootte):

def invert_matrix(AM, IM):
    for fd in range(len(AM)):
        fdScaler = 1.0 / AM[fd][fd]
        for j in range(len(AM)):
            AM[fd][j] *= fdScaler
            IM[fd][j] *= fdScaler
        for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
            crScaler = AM[i][fd]
            for j in range(len(AM)):
                AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
                IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
    return IM

Maar volg alsjeblieft het hele verhaal, je leert veel meer dan alleen deze code kopiëren en plakken!Er is trouwens ook een Jupyter-notebook.

Ik hoop dat het iemand helpt, ik vond het persoonlijk buitengewoon nuttig voor mijn zeer specifieke taak (Markov-keten absorberen) waar ik geen niet-standaard pakketten kon gebruiken.


Antwoord 5, autoriteit 6%

Je zou de determinant van de matrix kunnen berekenen die recursief is
en vorm dan de aangrenzende matrix

Hier is een korte tutorial

Ik denk dat dit alleen werkt voor vierkante matrices

Een andere manier om deze te berekenen is gram-schmidt-orthogonalisatie en vervolgens het transponeren van de matrix, de transponering van een orthogonale matrix is ​​zijn inverse!


Antwoord 6, autoriteit 5%

Numpy is geschikt voor de meeste mensen, maar je kunt ook matrices maken in Sympy

Probeer deze commando’s uit te voeren op http://live.sympy.org/

M = Matrix([[1, 3], [-2, 3]])
M
M**-1

Probeer voor de lol M**(1/2)


Antwoord 7

Als je numpy haat, stop dan met RPy en je lokale exemplaar van R, en gebruik het in plaats daarvan.

(Ik zou ook willen herhalen dat je de matrix echt moet omkeren. In R bijvoorbeeld, doen linalg.solve en de functie solve() niet echt een volledige inversie, omdat het niet nodig is.)

Other episodes