-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmatrix.py
81 lines (76 loc) · 3.18 KB
/
matrix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from functools import reduce
import twobytwo
def dot(a,b):
return sum([x*y for x,y in zip(a,b)])
def addPart(array):
return [sum([array[k][i] for k in range(len(array))]) for i in range(len(array[0]))]
class Matrix:
def __init__(self, rows):
self.row = rows
def __repr__(self):
return '\n'.join([str(i) for i in self.row])
def __round__(self,n = 0):
return Matrix([[round(self.row[r][column],n) for column in range(len(self.row[0]))] for r in range(len(self.row))])
def __abs__(self):
if len(self.row) > 2:
a = 0
for replace, place in enumerate(self.row[0]):
sec = Matrix([[i for n,i in enumerate(self.row[j]) if (n != replace)] for j in range(1, len(self.row))])
a += (-1)**replace * place * abs(sec)
return a
elif len(self.row) == 2:
return (self.row[0][0] * self.row[1][1]) - (self.row[0][1] * self.row[1][0])
else:
return self.row[0][0]
def __mul__(self, other):
if type(other) == Matrix:
return Matrix([[round(dot(i, [other.row[k][j] for k in range(len(other.row))]),4) for j in range(len(other.row[0]))] for i in self.row])
return Matrix.scalar(self, other)
def __add__ (self, other):
return Matrix([[self.row[k][i] + other.row[k][i] for i in range(len(self.row[0]))] for k in range(len(self.row))])
def __neg__(self):
return Matrix([[-1 * i for i in j] for j in self.row])
def __sub__(self,other):
return Matrix([self + -other])
def __truediv__(self, other):
return Matrix(self * ~other)
def transpose(self):
return Matrix([[self.row[k][i] for k in range(len(self.row[0]))] for i in range(len(self.row))])
def scalar(self, number):
return Matrix([[round(number * i,4) for i in j] for j in self.row])
def __pow__(self, power):
g = [self for i in range(power)]
return reduce(lambda x,y: x * y, g)
def __invert__(self):
try:
determinant = abs(self)
except:
return self #Returns, if invertible
news = Matrix.transpose(self)
news = [[(-1) ** (column + row) * abs(Matrix([[news.row[k][i] for i in range(len(self.row[0])) if i != column] for k in range(len(self.row)) if k != row])) for column in range(len(self.row[0]))] for row in range(len(self.row))]
return Matrix.scalar( Matrix(news),1/determinant)
def ref(self): #row-eschilon form
if len(self.row) == 2:
return Matrix(twobytwo.func(self.row))
else:
array = twobytwo.toPos(self.row, 0)
Barray = Matrix.ref(Matrix([i[1:] for i in array[1:]]))
array = [array[0]] + [[0] + Barray[i] for i in range(len(Barray.row))] #For n x m array, it solves the bottom right (n-1) x (m-1)
for i in range(1,len(array)): #Can't do it inline
array[0] = addPart([array[0], twobytwo.multList(-array[0][i],array[i])]) #Solves for one, but it still won't be simplified
array[0] = twobytwo.multList(1/array[0][0], array[0]) #simplify
return Matrix(array)
def solve(self):
a = Matrix.ref(self)
b = '(' + ','.join([str(i[-1]) for i in a.row]) + ")"
return b
def __getitem__(self, item):
return self.row[item]
mat = Matrix([[1,2,0,0],[0,1,9,0],[8,0,1,0],[4,3,5,1]])
a = Matrix([[1,2],[3,4]])
b = Matrix([[4,3],[2,1]])
g = [a-b,~a * abs(a), a ** 15, a * b, b * a, (b * a)[0], a / b]
x = Matrix([[1,3,7],[2,4,10]])
print(x.solve())
print()
print('\n\n'.join([str(i) for i in g]))