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/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