-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomplex_mat.py
More file actions
198 lines (130 loc) · 4.47 KB
/
complex_mat.py
File metadata and controls
198 lines (130 loc) · 4.47 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import numpy as np
from complex_frac import ComplexFrac
from tabulate import tabulate
from functools import wraps
class ComplexMat:
def __init__(self, *M):
self.M = np.array([[ComplexFrac(col) for col in line] for line in M])
@staticmethod
def diagonal(vec):
largo = len(vec)
ret = np.array(
[[(vec[n] if m == n else 0)
for m in range(largo)]
for n in range(largo)
])
return ComplexMat(*ret)
@property
def shape(self):
return self.M.shape
def __getitem__(self, *args, **kwargs):
return self.M.__getitem__(*args, **kwargs)
def __setitem__(self, *args, **kwargs):
self.M.__setitem__(*args, **kwargs)
def __eq__(self, other):
return self.M == other.M
def __mul__(self, other):
M1 = self.M
lines1, cols1 = M1.shape
if isinstance(other, ComplexMat):
M2 = other.M
lines2, cols2 = M2.shape
assert cols1 == lines2
res = np.zeros((lines1, cols2), dtype='object')
for l in np.arange(lines1):
for c in np.arange(cols2):
res[l][c] = ComplexFrac(0)
for k in np.arange(cols1):
res[l][c] += M1[l, k] * M2[k, c]
return ComplexMat(*res)
elif isinstance(other, ComplexFrac) or isinstance(other, int):
res = np.zeros((lines1, cols1), dtype='object')
for l in np.arange(lines1):
for c in np.arange(cols1):
res[l, c] = M1[l, c] * other
return ComplexMat(*res)
else:
raise ValueError('Not implemented')
def __add__(self, other):
M1 = self.M
M2 = other.M
lines1, cols1 = M1.shape
lines2, cols2 = M2.shape
assert lines1 == lines2 and cols1 == cols2
res = np.zeros((lines1, cols1), dtype='object')
for l in np.arange(lines1):
for c in np.arange(cols2):
res[l][c] = M1[l, c] + M2[l, c]
return ComplexMat(*res)
def __sub__(self, other):
return self.__add__(-other)
def __neg__(self):
M = self.M
lines, cols = M.shape
res = np.zeros((lines, cols), dtype='object')
for l in np.arange(lines):
for c in np.arange(cols):
res[l, c] = -M[l, c]
return ComplexMat(*res)
@property
def T(self):
lines, cols = self.M.shape
t = [[self.M[line, col] for line in np.arange(lines)] for col in np.arange(cols)]
return ComplexMat(*t)
def __repr__(self):
"""
╒ ╕
│ 1 2 │
│ 3 4 │
╘ ╛
"""
num_columns = self.M.shape[1]
max_col_len = [0] * num_columns
content_list = []
for line in self.M:
column_list = []
for i, col in enumerate(line):
col_string = str(col)
if len(col_string) > max_col_len[i]:
max_col_len[i] = len(col_string)
column_list.append(col_string)
content_list.append(column_list)
spaces_between_cols = 5
str_sbc = ' ' * spaces_between_cols
content_len = sum(max_col_len) + (num_columns - 1) * spaces_between_cols + 2
space = ' ' * content_len
first = f'╒{space}╕'
middle_list = []
for column_list in content_list:
line = []
for col, col_length in zip(column_list, max_col_len):
col_padded = col.rjust(col_length)
line.append(col_padded)
middle_list.append(f'│ {str_sbc.join(line)} │')
middle = '\n'.join(middle_list)
last = f'╘{space}╛'
full_matrix = f'{first}\n{middle}\n{last}'
return full_matrix
operators_to_override = (
'__truediv__',
)
for name in operators_to_override:
@wraps(getattr(np.ndarray, name))
def method(self, *args, _method_name=name, **kwargs):
original_method = getattr(self.M, _method_name)
ret = original_method(*args, **kwargs)
if ret is not None:
return ComplexMat(*ret)
setattr(ComplexMat, name, method)
if __name__ == '__main__':
M = ComplexMat(
[1, "2/5", -123],
[30, -75, 12]
)
Mt = ComplexMat(
[1, 30],
["2/5", -75],
[-123, 12],
)
assert M.shape == (2, 3)
assert np.all(M.T == Mt)