Start | matriser
 

matriser



Vad är en matris

Matriser är centralt inom t.ex. datorgrafik, artificiell intelligens eller avancerad fysik. Matematiken som introducerar detta kallas linjär algebra.

matriser


Det är inte så svårt som det låter. En matris är en låda med siffror, i rader och kolumner. Siffrorna kallas element.





Om en matris bara är 1x2 eller 1x3 brukar det kallas vektor (eller radvektor) och kan t.ex. representera en punkt eller vektor i ett 2D -plan eller 3D -rum.




klass för matriser


Vi kan väl skapa lite kod för att representera en matris. Exakt hur man vill göra detta beror på diverse, men ett sätt kan vara som nedan. I vår initiering (konstruktorn) hämtar vi in ett argument i form av en lista av listor. Det verkar vettigt, då en matris är en 2D -lista, dvs en lista av listor. För att se vad vi håller på med, så vill vi också kunna skriva ut en matris enkelt. Vi använder dundermetoden __str__ för att kunna använda print().
class Matrix: def __init__(self, I): self.I = I self.w = len(self.I[0]) self.h = len(self.I) def __str__(self): s = str(self.h)+'x'+str(self.w)+"\n" for i in range(self.h): for j in range(self.w): s = s + "{:>4}".format(self.I[i][j]) s = s + "\n" return(s) T = Matrix([ [1,2], [3,4], [5,1] ]) U = Matrix([ [2], [4] ]) V = Matrix([ [21,2,13], [3,14,5], [15,1,7] ]) print(T) print(U) print(V)

transponat

Om du spegelvänder en matris längs diagonalen får du matrisens transponat. Ta en matris och rad för rad skriver du om matrisen så att det blir kolumn för kolumn.

Vi kan skapa en metod transponat som gör detta. Det är bara att möblera om så att element (i,j) i matrisen får position (j,i).
class Matrix: def __init__(self, I): self.I = I self.w = len(self.I[0]) self.h = len(self.I) def __str__(self): s = str(self.h)+'x'+str(self.w)+"\n" for i in range(self.h): for j in range(self.w): s = s + "{:>4}".format(self.I[i][j]) s = s + "\n" return(s) def transponat(self): T = [[0]*self.h for i in range(self.w)] for i in range(self.h): for j in range(self.w): T[j][i] = self.I[i][j] return(Matrix(T)) T = Matrix([ [1,2], [3,4], [5,1] ]) U = Matrix([ [2], [4] ]) V = Matrix([ [21,2,13], [3,14,5], [15,1,7] ]) print("Orginal") print(T) print("Transponat") print(T.transponat()) print("Orginal") print(U) print("Transponat") print(U.transponat()) print("Orginal") print(V) print("Transponat") print(V.transponat())

enhetsmatrisen

En enhetsmatris består av nollor på alla positioner utom diagonalen, där vi sätter 1:or.

Låt oss resonera lite. Vi kanske vill skapa en enhetsmatris ur ingenting. Då vill vi egentligen bara ange en storlek. Vi kan skriva vår initiering av Matrix så att den kan ta antingen en int, vilket då tolkas som en storlek av en tom matris, eller en lista av listor, som då tolkas som en matris med värden. I fallet där vi vill ha en ehnhetsmatris på 3x3 så initierar vi Matrix(3) och sedan begär vi enhetsmatrisen. Det kan väl fungera?
class Matrix: def __init__(self, I=None): if(isinstance(I,int)): self.I = [[0]*I for i in range(I)] else: self.I = I if I: self.w = len(self.I[0]) self.h = len(self.I) def __str__(self): s = str(self.h)+'x'+str(self.w)+"\n" for i in range(self.h): for j in range(self.w): s = s + "{:>4}".format(self.I[i][j]) s = s + "\n" return(s) def transponat(self): T = [[0]*self.h for i in range(self.w)] for i in range(self.h): for j in range(self.w): T[j][i] = self.I[i][j] return(Matrix(T)) def enhetsmatris(self, dim=None): if(dim!=None): self.__init__(dim) for i in range(self.h): for j in range(self.w): self.I[i][j]=1 if i==j else 0 return(Matrix(self.I)) V = Matrix(3) print("Enhetsmatrisen") print(V.enhetsmatris())

addition och subtraktion

För att kunna addera och subtrahera 2 matriser, så måste de vara av samma sort (storlek). Vidare, så adderar eller subraherar vi position för position i de 2 matriserna. Kör koden nedan och titta på resultatet så förstår du direkt.

Vi kan använda pythons dundermetoder för att göra det möjligt använda plus och minus -operatorn på vår klass.
class Matrix: def __init__(self, I): self.I = I self.w = len(self.I[0]) self.h = len(self.I) def __str__(self): s = str(self.h)+'x'+str(self.w)+"\n" for i in range(self.h): for j in range(self.w): s = s + "{:>4}".format(self.I[i][j]) s = s + "\n" return(s) def transponat(self): T = [[0]*self.h for i in range(self.w)] for i in range(self.h): for j in range(self.w): T[j][i] = self.I[i][j] return(Matrix(T)) def enhetsmatris(self, dim=None): if(dim!=None): self.h = dim self.w = dim self.I = [[0]*dim for i in range(dim)] for i in range(self.h): for j in range(self.w): self.I[i][j]=1 if i==j else 0 return(Matrix(self.I)) def add(self,B): C = [[0]*B.w for i in range(self.h)] for i in range(self.w): for j in range(self.h): C[j][i]= self.I[j][i] + B.I[j][i] return(Matrix(C)) def __add__(self,B): return(self.add(B)) def sub(self,B): C = [[0]*B.w for i in range(self.h)] for i in range(self.w): for j in range(self.h): C[j][i]= self.I[j][i] - B.I[j][i] return(Matrix(C)) def __sub__(self,B): return(self.sub(B)) A = Matrix( [[1,1]]) B = Matrix( [[-2, 0]]) T = Matrix( [[1,2], [3,4], [5,1]]) U = Matrix( [[3,4], [4,5], [2,2]]) print(A) print(B) print("A + B") print(A + B) print(T) print(U) print("T + U") print(T + U) print("T - U") print(T - U)
Om det är två stycken vektorer 2x1 som vi adderar, kan det visualiseras såhär, men principen gäller oavsett dimension. Dock är det lite svårare visualisera hur det ser ut om man adderar 2 stycken matriser av högre dimension (vilket sker t.ex. i en AI).



multiplicera med skalär

Multiplicera med skalär görs helt enkelt så att elementvis multipliceras skalären med elementen. Så, en multiplikation med 2, då får vi en matris där alla elementen är dubbelt så höga som tidigare. Skalären ställs framför matrisen. Kör koden nedan och titta på resultatet, så förstår du direkt.
class Matrix: def __init__(self, I): self.I = I self.w = len(self.I[0]) self.h = len(self.I) def __str__(self): s = str(self.h)+'x'+str(self.w)+"\n" for i in range(self.h): for j in range(self.w): s = s + "{:>4}".format(self.I[i][j]) s = s + "\n" return(s) def transponat(self): T = [[0]*self.h for i in range(self.w)] for i in range(self.h): for j in range(self.w): T[j][i] = self.I[i][j] return(Matrix(T)) def enhetsmatris(self, dim=None): if(dim!=None): self.h = dim self.w = dim self.I = [[0]*dim for i in range(dim)] for i in range(self.h): for j in range(self.w): self.I[i][j]=1 if i==j else 0 return(Matrix(self.I)) def add(self,B): C = [[0]*self.w for i in range(self.h)] for i in range(self.w): for j in range(self.h): C[j][i]= self.I[j][i] + B.I[j][i] return(Matrix(C)) def __add__(self,B): return(self.add(B)) def sub(self,B): C = [[0]*self.w for i in range(self.h)] for i in range(self.w): for j in range(self.h): C[j][i]= self.I[j][i] - B.I[j][i] return(Matrix(C)) def __sub__(self,B): return(self.sub(B)) def __rmul__(self,K): C = [[0]*self.w for i in range(self.h)] for i in range(self.w): for j in range(self.h): C[j][i]= self.I[j][i] * K return(Matrix(C)) T = Matrix( [[1,2], [3,4], [5,1]]) U = Matrix( [[3,4], [4,5], [2,2]]) print(T) print("Skala upp med 2") print(2 * T) print(U) print("Skala upp med 3") print(3 * U)

multiplicera 2 matriser

Detta är pyttelite krångligare förklara, så hur du ska multiplicera matriser, det ligger på en egen sida.
class Matrix: def __init__(self, I): self.I = I self.w = len(self.I[0]) self.h = len(self.I) def __str__(self): s = str(self.h)+'x'+str(self.w)+"\n" for i in range(self.h): for j in range(self.w): s = s + "{:>4}".format(self.I[i][j]) s = s + "\n" return(s) def enhetsmatris(self): for i in range(self.h): for j in range(self.w): self.I[i][j]=1 if i==j else 0 return(Matrix(self.I)) def multiplyWith(self,B): C = [[0]*B.w for i in range(self.h)] for i in range(B.w): for j in range(self.h): for s in range(B.h): C[j][i]+= self.I[j][s] * B.I[s][i] return(Matrix(C)) def __matmul__(self,B): return(self.multiplyWith(B)) T = Matrix( [[1,2], [3,4], [5,1]]) U = Matrix( [[2], [4]]) print(T) print(U) V = T @ U print(V)
14.855146408081 ms