PyCMatrix 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- matrix/__init__.py +3 -0
- matrix/arithmetic.py +216 -0
- matrix/bool.py +91 -0
- matrix/constructors.py +115 -0
- matrix/exceptions.py +0 -0
- matrix/manipulation.py +145 -0
- matrix/matrix.py +396 -0
- matrix/operations.py +187 -0
- matrix/validators.py +46 -0
- pycmatrix-1.0.0.dist-info/METADATA +862 -0
- pycmatrix-1.0.0.dist-info/RECORD +14 -0
- pycmatrix-1.0.0.dist-info/WHEEL +5 -0
- pycmatrix-1.0.0.dist-info/licenses/LICENSE +9 -0
- pycmatrix-1.0.0.dist-info/top_level.txt +1 -0
matrix/matrix.py
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from .validators import (
|
|
3
|
+
check_matrix,
|
|
4
|
+
is_equal_order,
|
|
5
|
+
is_valid_index,
|
|
6
|
+
is_multiplicable,
|
|
7
|
+
is_approx_equal,
|
|
8
|
+
)
|
|
9
|
+
from .operations import (
|
|
10
|
+
transpose,
|
|
11
|
+
minor,
|
|
12
|
+
cofactor,
|
|
13
|
+
determinant,
|
|
14
|
+
matrix_of_minors,
|
|
15
|
+
matrix_of_cofactors,
|
|
16
|
+
trace,
|
|
17
|
+
adjoint,
|
|
18
|
+
inverse,
|
|
19
|
+
rank,
|
|
20
|
+
solve,
|
|
21
|
+
)
|
|
22
|
+
from .constructors import (
|
|
23
|
+
one,
|
|
24
|
+
zero,
|
|
25
|
+
identity,
|
|
26
|
+
constant,
|
|
27
|
+
diagonal,
|
|
28
|
+
random_matrix,
|
|
29
|
+
elementwise,
|
|
30
|
+
from_string,
|
|
31
|
+
random_uniform,
|
|
32
|
+
seed
|
|
33
|
+
)
|
|
34
|
+
from .bool import (
|
|
35
|
+
is_square,
|
|
36
|
+
is_diagonal,
|
|
37
|
+
is_column,
|
|
38
|
+
is_row,
|
|
39
|
+
is_scalar,
|
|
40
|
+
is_identity,
|
|
41
|
+
is_zero,
|
|
42
|
+
is_symmetric,
|
|
43
|
+
is_skew_symmetric,
|
|
44
|
+
is_invertible,
|
|
45
|
+
is_singular,
|
|
46
|
+
is_non_singular
|
|
47
|
+
)
|
|
48
|
+
from .manipulation import (
|
|
49
|
+
insert_row,
|
|
50
|
+
insert_col,
|
|
51
|
+
delete_row,
|
|
52
|
+
delete_col,
|
|
53
|
+
get_row,
|
|
54
|
+
get_col,
|
|
55
|
+
flatten,
|
|
56
|
+
reshape,
|
|
57
|
+
swap_cols,
|
|
58
|
+
swap_rows,
|
|
59
|
+
)
|
|
60
|
+
from .arithmetic import (
|
|
61
|
+
add,
|
|
62
|
+
subtract,
|
|
63
|
+
multiply,
|
|
64
|
+
divide,
|
|
65
|
+
negate,
|
|
66
|
+
power,
|
|
67
|
+
elementwise_multiply,
|
|
68
|
+
apply,
|
|
69
|
+
exp,
|
|
70
|
+
log,
|
|
71
|
+
sqrt,
|
|
72
|
+
abs,
|
|
73
|
+
sin,
|
|
74
|
+
cos,
|
|
75
|
+
tan,
|
|
76
|
+
sinh,
|
|
77
|
+
cosh,
|
|
78
|
+
tanh,
|
|
79
|
+
sum,
|
|
80
|
+
mean,
|
|
81
|
+
min,
|
|
82
|
+
max,
|
|
83
|
+
prod,
|
|
84
|
+
norm_squared,
|
|
85
|
+
norm
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
class Matrix:
|
|
89
|
+
def __init__(self,m):
|
|
90
|
+
val = check_matrix(m)
|
|
91
|
+
if val == True:
|
|
92
|
+
pass
|
|
93
|
+
else:
|
|
94
|
+
raise ValueError(f"Invalid Format! len({val}) is not matched with first one.")
|
|
95
|
+
self.m = m
|
|
96
|
+
|
|
97
|
+
def __repr__(self):
|
|
98
|
+
return '{}'.format(self.m)
|
|
99
|
+
|
|
100
|
+
def __str__(self):
|
|
101
|
+
return "{}".format(self.m)
|
|
102
|
+
|
|
103
|
+
def __eq__(self, other):
|
|
104
|
+
if not self.isEqualOrder(other):
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
r,l = self.order
|
|
108
|
+
for i in range(r):
|
|
109
|
+
for j in range(l):
|
|
110
|
+
if not self[i,j] == other[i,j]:
|
|
111
|
+
return False
|
|
112
|
+
else:
|
|
113
|
+
return True
|
|
114
|
+
|
|
115
|
+
def __add__(self, other):
|
|
116
|
+
return add(self, other)
|
|
117
|
+
|
|
118
|
+
def __sub__(self, other):
|
|
119
|
+
return subtract(self, other)
|
|
120
|
+
|
|
121
|
+
def __mul__(self, other):
|
|
122
|
+
return multiply(self, other)
|
|
123
|
+
|
|
124
|
+
def elementwise_multiply(self, other):
|
|
125
|
+
return elementwise_multiply(self, other)
|
|
126
|
+
|
|
127
|
+
def apply(self, function):
|
|
128
|
+
return apply(self, function)
|
|
129
|
+
|
|
130
|
+
def exp(self):
|
|
131
|
+
return exp(self)
|
|
132
|
+
|
|
133
|
+
def log(self):
|
|
134
|
+
return log(self)
|
|
135
|
+
|
|
136
|
+
def sqrt(self):
|
|
137
|
+
return sqrt(self)
|
|
138
|
+
|
|
139
|
+
def abs(self):
|
|
140
|
+
return abs(self)
|
|
141
|
+
|
|
142
|
+
def sin(self):
|
|
143
|
+
return sin(self)
|
|
144
|
+
|
|
145
|
+
def cos(self):
|
|
146
|
+
return cos(self)
|
|
147
|
+
|
|
148
|
+
def tan(self):
|
|
149
|
+
return tan(self)
|
|
150
|
+
|
|
151
|
+
def sinh(self):
|
|
152
|
+
return sinh(self)
|
|
153
|
+
|
|
154
|
+
def cosh(self):
|
|
155
|
+
return cosh(self)
|
|
156
|
+
|
|
157
|
+
def tanh(self):
|
|
158
|
+
return tanh(self)
|
|
159
|
+
|
|
160
|
+
def sum(self):
|
|
161
|
+
return sum(self)
|
|
162
|
+
|
|
163
|
+
def mean(self):
|
|
164
|
+
return mean(self)
|
|
165
|
+
|
|
166
|
+
def min(self):
|
|
167
|
+
return min(self)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def max(self):
|
|
171
|
+
return max(self)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def prod(self):
|
|
175
|
+
return prod(self)
|
|
176
|
+
|
|
177
|
+
def norm_squared(matrix):
|
|
178
|
+
return norm_squared(matrix)
|
|
179
|
+
|
|
180
|
+
def norm(self):
|
|
181
|
+
return norm(self)
|
|
182
|
+
|
|
183
|
+
def copy(self):
|
|
184
|
+
return type(self)(copy.deepcopy(self.m))
|
|
185
|
+
|
|
186
|
+
def __truediv__(self, other):
|
|
187
|
+
return divide(self, other)
|
|
188
|
+
|
|
189
|
+
def __neg__(self):
|
|
190
|
+
return negate(self)
|
|
191
|
+
|
|
192
|
+
def __rmul__(self, other):
|
|
193
|
+
return self.__mul__(other)
|
|
194
|
+
|
|
195
|
+
def __pow__(self, raisedTo):
|
|
196
|
+
return power(self, raisedTo)
|
|
197
|
+
|
|
198
|
+
def __getitem__(self, index):
|
|
199
|
+
if self.isValidIndex(index):
|
|
200
|
+
row, col = index
|
|
201
|
+
return self.m[row][col]
|
|
202
|
+
|
|
203
|
+
def __setitem__(self, key, value):
|
|
204
|
+
r,c = key
|
|
205
|
+
self.m[r][c] = value
|
|
206
|
+
|
|
207
|
+
def __iter__(self):
|
|
208
|
+
for row in self.m:
|
|
209
|
+
yield row
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def order(self):
|
|
213
|
+
return (len(self.m),len(self.m[0]))
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def shape(self):
|
|
217
|
+
return self.order
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def transpose(self):
|
|
221
|
+
return transpose(self)
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def traverse(self):
|
|
225
|
+
l = (x for lists in self.m for x in lists)
|
|
226
|
+
return l
|
|
227
|
+
|
|
228
|
+
def insertRow(self, rowMat):
|
|
229
|
+
return insert_row(self, rowMat)
|
|
230
|
+
|
|
231
|
+
def insertCol(self, colMat):
|
|
232
|
+
return insert_col(self, colMat)
|
|
233
|
+
|
|
234
|
+
def delRow(self, rowIndex, inplace=False):
|
|
235
|
+
return delete_row(self, rowIndex, inplace)
|
|
236
|
+
|
|
237
|
+
def delCol(self, colIndex, inplace=False):
|
|
238
|
+
return delete_col(self, colIndex, inplace)
|
|
239
|
+
|
|
240
|
+
def getRow(self, rowIndex):
|
|
241
|
+
return get_row(self, rowIndex)
|
|
242
|
+
|
|
243
|
+
def getCol(self, colIndex):
|
|
244
|
+
return get_col(self, colIndex)
|
|
245
|
+
|
|
246
|
+
def flatten(self):
|
|
247
|
+
return flatten(self)
|
|
248
|
+
|
|
249
|
+
def reshape(self, rows, cols):
|
|
250
|
+
return reshape(self, rows, cols)
|
|
251
|
+
|
|
252
|
+
def swapCols(self, col1, col2, inplace=False):
|
|
253
|
+
return swap_cols(self, col1, col2, inplace)
|
|
254
|
+
|
|
255
|
+
def swapRows(self, row1, row2, inplace=False):
|
|
256
|
+
return swap_rows(self, row1, row2, inplace)
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
def isSqrMatrix(self):
|
|
260
|
+
return is_square(self)
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def isDiagMatrix(self):
|
|
264
|
+
return is_diagonal(self)
|
|
265
|
+
|
|
266
|
+
@property
|
|
267
|
+
def isColMatrix(self):
|
|
268
|
+
return is_column(self)
|
|
269
|
+
|
|
270
|
+
@property
|
|
271
|
+
def isRowMatrix(self):
|
|
272
|
+
return is_row(self)
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def isSclrMatrix(self):
|
|
276
|
+
return is_scalar(self)
|
|
277
|
+
|
|
278
|
+
@property
|
|
279
|
+
def isIdntMatrix(self):
|
|
280
|
+
return is_identity(self)
|
|
281
|
+
|
|
282
|
+
@property
|
|
283
|
+
def isZeroMatrix(self):
|
|
284
|
+
return is_zero(self)
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def isSymtMatrix(self):
|
|
288
|
+
return is_symmetric(self)
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def isSkewSymtMatrix(self):
|
|
292
|
+
return is_skew_symmetric(self)
|
|
293
|
+
|
|
294
|
+
@property
|
|
295
|
+
def isInvertible(self):
|
|
296
|
+
return is_invertible(self)
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def isSingularMatrix(self):
|
|
300
|
+
return is_singular(self)
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def isNonSingularMatrix(self):
|
|
304
|
+
return is_non_singular(self)
|
|
305
|
+
|
|
306
|
+
def isValidIndex(self, index):
|
|
307
|
+
return is_valid_index(self, index)
|
|
308
|
+
|
|
309
|
+
def isEqualOrder(self, other):
|
|
310
|
+
return is_equal_order(self, other)
|
|
311
|
+
|
|
312
|
+
def isMultiplicable(self, other):
|
|
313
|
+
return is_multiplicable(self, other)
|
|
314
|
+
|
|
315
|
+
def isApproxEqual(self, other, tolerance=1e-9):
|
|
316
|
+
return is_approx_equal(self, other, tolerance)
|
|
317
|
+
|
|
318
|
+
def minor(self,rowIndex, colIndex):
|
|
319
|
+
return minor(self, rowIndex, colIndex)
|
|
320
|
+
|
|
321
|
+
def cofactor(self,rowIndex, colIndex):
|
|
322
|
+
return cofactor(self,rowIndex, colIndex)
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def matrixOfMinors(self):
|
|
326
|
+
return matrix_of_minors(self)
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def matrixOfCofactors(self):
|
|
330
|
+
return matrix_of_cofactors(self)
|
|
331
|
+
|
|
332
|
+
@property
|
|
333
|
+
def determinant(self):
|
|
334
|
+
return determinant(self)
|
|
335
|
+
|
|
336
|
+
@property
|
|
337
|
+
def trace(self):
|
|
338
|
+
return trace(self)
|
|
339
|
+
|
|
340
|
+
@property
|
|
341
|
+
def adjoint(self):
|
|
342
|
+
return adjoint(self)
|
|
343
|
+
|
|
344
|
+
@property
|
|
345
|
+
def inverse(self):
|
|
346
|
+
return inverse(self)
|
|
347
|
+
|
|
348
|
+
def rank(self):
|
|
349
|
+
return rank(self)
|
|
350
|
+
|
|
351
|
+
def solve(self, other):
|
|
352
|
+
return solve(self, other)
|
|
353
|
+
|
|
354
|
+
@classmethod
|
|
355
|
+
def one(cls, rows, cols=None):
|
|
356
|
+
return one(cls, rows, cols)
|
|
357
|
+
|
|
358
|
+
@classmethod
|
|
359
|
+
def zero(cls, rows, cols=None):
|
|
360
|
+
return zero(cls, rows, cols)
|
|
361
|
+
|
|
362
|
+
@classmethod
|
|
363
|
+
def identity(cls, n):
|
|
364
|
+
return identity(cls, n)
|
|
365
|
+
|
|
366
|
+
@classmethod
|
|
367
|
+
def constant(cls, rows, cols=None, value=0):
|
|
368
|
+
return constant(cls, rows, cols, value)
|
|
369
|
+
|
|
370
|
+
@classmethod
|
|
371
|
+
def diagonal(cls, diag_list):
|
|
372
|
+
return diagonal(cls, diag_list)
|
|
373
|
+
|
|
374
|
+
@classmethod
|
|
375
|
+
def random(cls, rows, cols=None, low=0, high=10):
|
|
376
|
+
return random_matrix(cls, rows, cols, low, high)
|
|
377
|
+
|
|
378
|
+
@classmethod
|
|
379
|
+
def elementwise(cls, rows, cols=None, func=lambda i, j: 0):
|
|
380
|
+
return elementwise(cls, rows, cols, func)
|
|
381
|
+
|
|
382
|
+
@classmethod
|
|
383
|
+
def from_string(cls, my_string, dtype=float,row_sep='\n'):
|
|
384
|
+
return from_string(cls, my_string, dtype,row_sep)
|
|
385
|
+
|
|
386
|
+
@classmethod
|
|
387
|
+
def random_uniform(cls, rows, cols=None, low=-1.0, high=1.0):
|
|
388
|
+
return random_uniform(cls, rows, cols, low, high)
|
|
389
|
+
|
|
390
|
+
@classmethod
|
|
391
|
+
def random_uniform(cls, rows, cols=None, low=-1.0, high=1.0):
|
|
392
|
+
return random_uniform(cls, rows, cols, low, high)
|
|
393
|
+
|
|
394
|
+
@classmethod
|
|
395
|
+
def seed(cls, value=None):
|
|
396
|
+
seed(value)
|
matrix/operations.py
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
def transpose(matrix):
|
|
2
|
+
rows, cols = matrix.order
|
|
3
|
+
|
|
4
|
+
result = [
|
|
5
|
+
[matrix.m[j][i] for j in range(rows)]
|
|
6
|
+
for i in range(cols)
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
return type(matrix)(result)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def minor(matrix, row_index, col_index):
|
|
13
|
+
return matrix.delRow(row_index).delCol(col_index)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def cofactor(matrix, row_index, col_index):
|
|
17
|
+
return ((-1) ** (row_index + col_index)) * determinant(
|
|
18
|
+
minor(matrix, row_index, col_index)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def determinant(matrix):
|
|
23
|
+
rows, cols = matrix.order
|
|
24
|
+
|
|
25
|
+
if rows != cols:
|
|
26
|
+
raise ValueError()
|
|
27
|
+
|
|
28
|
+
if rows == 1:
|
|
29
|
+
return matrix.m[0][0]
|
|
30
|
+
|
|
31
|
+
if rows == 2:
|
|
32
|
+
m = matrix.m
|
|
33
|
+
return m[0][0] * m[1][1] - m[0][1] * m[1][0]
|
|
34
|
+
|
|
35
|
+
return sum(
|
|
36
|
+
matrix.m[0][i] * cofactor(matrix, 0, i)
|
|
37
|
+
for i in range(cols)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def matrix_of_minors(matrix):
|
|
42
|
+
rows, cols = matrix.order
|
|
43
|
+
|
|
44
|
+
result = [
|
|
45
|
+
[
|
|
46
|
+
determinant(minor(matrix, i, j))
|
|
47
|
+
for j in range(cols)
|
|
48
|
+
]
|
|
49
|
+
for i in range(rows)
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
return type(matrix)(result)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def matrix_of_cofactors(matrix):
|
|
56
|
+
rows, cols = matrix.order
|
|
57
|
+
|
|
58
|
+
result = [
|
|
59
|
+
[
|
|
60
|
+
cofactor(matrix, i, j)
|
|
61
|
+
for j in range(cols)
|
|
62
|
+
]
|
|
63
|
+
for i in range(rows)
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
return type(matrix)(result)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def trace(self):
|
|
70
|
+
r,c = self.order
|
|
71
|
+
if not r == c:
|
|
72
|
+
raise ValueError()
|
|
73
|
+
return sum(self.m[i][i] for i in range(r))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def adjoint(matrix):
|
|
77
|
+
return matrix_of_cofactors(matrix).transpose
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def inverse(matrix):
|
|
81
|
+
if not matrix.isInvertible:
|
|
82
|
+
raise ValueError()
|
|
83
|
+
|
|
84
|
+
return adjoint(matrix) * (1 / determinant(matrix))
|
|
85
|
+
|
|
86
|
+
def rank(matrix):
|
|
87
|
+
values = [
|
|
88
|
+
[matrix.m[i][j] for j in range(matrix.order[1])]
|
|
89
|
+
for i in range(matrix.order[0])
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
rows, cols = matrix.order
|
|
93
|
+
rank = 0
|
|
94
|
+
tolerance = 1e-12
|
|
95
|
+
|
|
96
|
+
for col in range(cols):
|
|
97
|
+
pivot = None
|
|
98
|
+
|
|
99
|
+
for row in range(rank, rows):
|
|
100
|
+
if abs(values[row][col]) > tolerance:
|
|
101
|
+
pivot = row
|
|
102
|
+
break
|
|
103
|
+
|
|
104
|
+
if pivot is None:
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
values[rank], values[pivot] = (
|
|
108
|
+
values[pivot],
|
|
109
|
+
values[rank]
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
pivot_value = values[rank][col]
|
|
113
|
+
|
|
114
|
+
for row in range(rank + 1, rows):
|
|
115
|
+
factor = values[row][col] / pivot_value
|
|
116
|
+
|
|
117
|
+
for j in range(col, cols):
|
|
118
|
+
values[row][j] -= factor * values[rank][j]
|
|
119
|
+
|
|
120
|
+
rank += 1
|
|
121
|
+
|
|
122
|
+
if rank == rows:
|
|
123
|
+
break
|
|
124
|
+
|
|
125
|
+
return rank
|
|
126
|
+
|
|
127
|
+
def solve(matrix, other):
|
|
128
|
+
rows, cols = matrix.order
|
|
129
|
+
|
|
130
|
+
if rows != cols:
|
|
131
|
+
raise ValueError("coefficient matrix must be square")
|
|
132
|
+
|
|
133
|
+
if other.order[0] != rows:
|
|
134
|
+
raise ValueError("incompatible dimensions")
|
|
135
|
+
|
|
136
|
+
n = rows
|
|
137
|
+
|
|
138
|
+
augmented = [
|
|
139
|
+
[
|
|
140
|
+
matrix.m[i][j]
|
|
141
|
+
for j in range(cols)
|
|
142
|
+
] + [
|
|
143
|
+
other.m[i][j]
|
|
144
|
+
for j in range(other.order[1])
|
|
145
|
+
]
|
|
146
|
+
for i in range(rows)
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
rhs_cols = other.order[1]
|
|
150
|
+
tolerance = 1e-12
|
|
151
|
+
|
|
152
|
+
for col in range(n):
|
|
153
|
+
pivot = max(
|
|
154
|
+
range(col, n),
|
|
155
|
+
key=lambda row: abs(augmented[row][col])
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if abs(augmented[pivot][col]) <= tolerance:
|
|
159
|
+
raise ValueError("matrix is singular")
|
|
160
|
+
|
|
161
|
+
augmented[col], augmented[pivot] = (
|
|
162
|
+
augmented[pivot],
|
|
163
|
+
augmented[col]
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
pivot_value = augmented[col][col]
|
|
167
|
+
|
|
168
|
+
for j in range(col, n + rhs_cols):
|
|
169
|
+
augmented[col][j] /= pivot_value
|
|
170
|
+
|
|
171
|
+
for row in range(n):
|
|
172
|
+
if row == col:
|
|
173
|
+
continue
|
|
174
|
+
|
|
175
|
+
factor = augmented[row][col]
|
|
176
|
+
|
|
177
|
+
for j in range(col, n + rhs_cols):
|
|
178
|
+
augmented[row][j] -= (
|
|
179
|
+
factor * augmented[col][j]
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
result = [
|
|
183
|
+
augmented[i][n:n + rhs_cols]
|
|
184
|
+
for i in range(n)
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
return type(matrix)(result)
|
matrix/validators.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import builtins
|
|
2
|
+
|
|
3
|
+
def check_matrix(m):
|
|
4
|
+
n = len(m[0])
|
|
5
|
+
for i in m:
|
|
6
|
+
if len(i) != n :
|
|
7
|
+
return i
|
|
8
|
+
else:
|
|
9
|
+
return True
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def is_equal_order(self, other):
|
|
13
|
+
return self.order == other.order
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def is_valid_index(self, index):
|
|
17
|
+
if not len(index) == 2:
|
|
18
|
+
return False
|
|
19
|
+
|
|
20
|
+
r, c = index
|
|
21
|
+
rows, cols = self.order
|
|
22
|
+
|
|
23
|
+
return 0 <= r < rows and 0 <= c < cols
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def is_multiplicable(self, other):
|
|
27
|
+
if self.order[1] == other.order[0]:
|
|
28
|
+
return True
|
|
29
|
+
else:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
def is_approx_equal(matrix, other, tolerance=1e-9):
|
|
33
|
+
if not matrix.isEqualOrder(other):
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
if tolerance < 0:
|
|
37
|
+
raise ValueError("tolerance must be non-negative")
|
|
38
|
+
|
|
39
|
+
rows, cols = matrix.order
|
|
40
|
+
|
|
41
|
+
for i in range(rows):
|
|
42
|
+
for j in range(cols):
|
|
43
|
+
if builtins.abs(matrix.m[i][j] - other.m[i][j]) > tolerance:
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
return True
|