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 ADDED
@@ -0,0 +1,3 @@
1
+ from .matrix import Matrix
2
+
3
+ __all__ = ["Matrix"]
matrix/arithmetic.py ADDED
@@ -0,0 +1,216 @@
1
+ from math import (
2
+ exp as mathexp,
3
+ log as mathlog,
4
+ sqrt as mathsqrt,
5
+ sin as mathsin,
6
+ cos as mathcos,
7
+ tan as mathtan,
8
+ sinh as mathsinh,
9
+ cosh as mathcosh,
10
+ tanh as mathtanh
11
+
12
+ )
13
+ import builtins
14
+
15
+ def add(matrix, other):
16
+ if not matrix.isEqualOrder(other):
17
+ raise ValueError()
18
+
19
+ rows, cols = matrix.order
20
+
21
+ result = [
22
+ [
23
+ matrix.m[i][j] + other.m[i][j]
24
+ for j in range(cols)
25
+ ]
26
+ for i in range(rows)
27
+ ]
28
+
29
+ return type(matrix)(result)
30
+
31
+
32
+ def subtract(matrix, other):
33
+ if not matrix.isEqualOrder(other):
34
+ raise ValueError()
35
+
36
+ rows, cols = matrix.order
37
+
38
+ result = [
39
+ [
40
+ matrix.m[i][j] - other.m[i][j]
41
+ for j in range(cols)
42
+ ]
43
+ for i in range(rows)
44
+ ]
45
+
46
+ return type(matrix)(result)
47
+
48
+
49
+ def multiply(matrix, other):
50
+ # Scalar multiplication
51
+ if isinstance(other, (int, float, complex)):
52
+ return type(matrix)(
53
+ [
54
+ [matrix.m[i][j] * other for j in range(matrix.order[1])]
55
+ for i in range(matrix.order[0])
56
+ ]
57
+ )
58
+
59
+ if not matrix.isMultiplicable(other):
60
+ raise ValueError()
61
+
62
+ rows = matrix.order[0]
63
+ cols = other.order[1]
64
+
65
+ result = [
66
+ [
67
+ builtins.sum(
68
+ matrix.m[i][k] * other.m[k][j]
69
+ for k in range(matrix.order[1])
70
+ )
71
+ for j in range(cols)
72
+ ]
73
+ for i in range(rows)
74
+ ]
75
+
76
+ return type(matrix)(result)
77
+
78
+
79
+ def elementwise_multiply(matrix, other):
80
+ if not matrix.isEqualOrder(other):
81
+ raise ValueError()
82
+
83
+ rows, cols = matrix.order
84
+
85
+ result = [
86
+ [
87
+ matrix.m[i][j] * other.m[i][j]
88
+ for j in range(cols)
89
+ ]
90
+ for i in range(rows)
91
+ ]
92
+
93
+ return type(matrix)(result)
94
+
95
+
96
+ def divide(matrix, other):
97
+ if other == 0:
98
+ raise ZeroDivisionError("division by zero")
99
+
100
+ return type(matrix)(
101
+ [
102
+ [matrix.m[i][j] / other for j in range(matrix.order[1])]
103
+ for i in range(matrix.order[0])
104
+ ]
105
+ )
106
+
107
+
108
+ def negate(matrix):
109
+ return type(matrix)(
110
+ [
111
+ [-matrix.m[i][j] for j in range(matrix.order[1])]
112
+ for i in range(matrix.order[0])
113
+ ]
114
+ )
115
+
116
+
117
+ def power(matrix, raised_to):
118
+ if isinstance(raised_to, int) and raised_to > 0:
119
+ I = type(matrix).identity(matrix.order[0])
120
+
121
+ for _ in range(raised_to):
122
+ I = I * matrix
123
+
124
+ return I
125
+
126
+
127
+ def apply(matrix, function):
128
+ rows, cols = matrix.order
129
+
130
+ result = [
131
+ [
132
+ function(matrix.m[i][j])
133
+ for j in range(cols)
134
+ ]
135
+ for i in range(rows)
136
+ ]
137
+
138
+ return type(matrix)(result)
139
+
140
+
141
+ def exp(matrix):
142
+ return apply(matrix, mathexp)
143
+
144
+ def log(matrix):
145
+ return apply(matrix, mathlog)
146
+
147
+ def sqrt(matrix):
148
+ return apply(matrix, mathsqrt)
149
+
150
+ def abs(matrix):
151
+ return apply(matrix, builtins.abs)
152
+
153
+ def sin(matrix):
154
+ return apply(matrix, mathsin)
155
+
156
+ def cos(matrix):
157
+ return apply(matrix, mathcos)
158
+
159
+ def tan(matrix):
160
+ return apply(matrix, mathtan)
161
+
162
+ def sinh(matrix):
163
+ return apply(matrix, mathsinh)
164
+
165
+ def cosh(matrix):
166
+ return apply(matrix, mathcosh)
167
+
168
+ def tanh(matrix):
169
+ return apply(matrix, mathtanh)
170
+
171
+ def sum(matrix):
172
+ return builtins.sum(
173
+ matrix.m[i][j]
174
+ for i in range(matrix.order[0])
175
+ for j in range(matrix.order[1])
176
+ )
177
+
178
+ def mean(matrix):
179
+ rows, cols = matrix.order
180
+ return matrix.sum() / (rows * cols)
181
+
182
+ def min(matrix):
183
+ return builtins.min(
184
+ matrix.m[i][j]
185
+ for i in range(matrix.order[0])
186
+ for j in range(matrix.order[1])
187
+ )
188
+
189
+
190
+ def max(matrix):
191
+ return builtins.max(
192
+ matrix.m[i][j]
193
+ for i in range(matrix.order[0])
194
+ for j in range(matrix.order[1])
195
+ )
196
+
197
+
198
+ def prod(matrix):
199
+ result = 1
200
+
201
+ for i in range(matrix.order[0]):
202
+ for j in range(matrix.order[1]):
203
+ result *= matrix.m[i][j]
204
+
205
+ return result
206
+
207
+
208
+ def norm_squared(matrix):
209
+ return builtins.sum(
210
+ matrix.m[i][j] ** 2
211
+ for i in range(matrix.order[0])
212
+ for j in range(matrix.order[1])
213
+ )
214
+
215
+ def norm(matrix):
216
+ return mathsqrt(norm_squared(matrix))
matrix/bool.py ADDED
@@ -0,0 +1,91 @@
1
+ def is_square(matrix):
2
+ rows, cols = matrix.order
3
+ return rows == cols
4
+
5
+
6
+ def is_diagonal(matrix):
7
+ if not is_square(matrix):
8
+ return False
9
+
10
+ rows, cols = matrix.order
11
+
12
+ values = {
13
+ matrix.m[i][j]
14
+ for i in range(rows)
15
+ for j in range(cols)
16
+ if i != j
17
+ }
18
+
19
+ return values == {0}
20
+
21
+
22
+ def is_column(matrix):
23
+ return matrix.order[1] == 1
24
+
25
+
26
+ def is_row(matrix):
27
+ return matrix.order[0] == 1
28
+
29
+
30
+ def is_scalar(matrix):
31
+ if not is_diagonal(matrix):
32
+ return False
33
+
34
+ rows, cols = matrix.order
35
+
36
+ values = {
37
+ matrix.m[i][j]
38
+ for i in range(rows)
39
+ for j in range(cols)
40
+ if i == j
41
+ }
42
+
43
+ return len(values) == 1
44
+
45
+
46
+ def is_identity(matrix):
47
+ if not is_diagonal(matrix):
48
+ return False
49
+
50
+ rows, cols = matrix.order
51
+
52
+ values = {
53
+ matrix.m[i][j]
54
+ for i in range(rows)
55
+ for j in range(cols)
56
+ if i == j
57
+ }
58
+
59
+ return values == {1}
60
+
61
+
62
+ def is_zero(matrix):
63
+ rows, cols = matrix.order
64
+
65
+ values = {
66
+ matrix.m[i][j]
67
+ for i in range(rows)
68
+ for j in range(cols)
69
+ }
70
+
71
+ return values == {0}
72
+
73
+
74
+ def is_symmetric(matrix):
75
+ return matrix == matrix.transpose
76
+
77
+
78
+ def is_skew_symmetric(matrix):
79
+ return -1 * matrix == matrix.transpose
80
+
81
+
82
+ def is_invertible(matrix):
83
+ return matrix.isSqrMatrix and matrix.determinant != 0
84
+
85
+
86
+ def is_singular(matrix):
87
+ return matrix.determinant == 0
88
+
89
+
90
+ def is_non_singular(matrix):
91
+ return matrix.determinant != 0
matrix/constructors.py ADDED
@@ -0,0 +1,115 @@
1
+ import random
2
+ _rng = random.Random()
3
+
4
+ def one(matrix_class, rows, cols=None):
5
+ if cols is None:
6
+ cols = rows
7
+
8
+ return matrix_class([
9
+ [1 for _ in range(cols)]
10
+ for _ in range(rows)
11
+ ])
12
+
13
+
14
+ def zero(matrix_class, rows, cols=None):
15
+ if cols is None:
16
+ cols = rows
17
+
18
+ return matrix_class([
19
+ [0 for _ in range(cols)]
20
+ for _ in range(rows)
21
+ ])
22
+
23
+
24
+ def identity(matrix_class, n):
25
+ return matrix_class([
26
+ [1 if i == j else 0 for j in range(n)]
27
+ for i in range(n)
28
+ ])
29
+
30
+
31
+ def constant(matrix_class, rows, cols=None, value=0):
32
+ if cols is None:
33
+ cols = rows
34
+
35
+ return matrix_class([
36
+ [value for _ in range(cols)]
37
+ for _ in range(rows)
38
+ ])
39
+
40
+ def diagonal(matrix_class, diag_list):
41
+ n = len(diag_list)
42
+
43
+ return matrix_class([
44
+ [diag_list[i] if i == j else 0 for j in range(n)]
45
+ for i in range(n)
46
+ ])
47
+
48
+ def random_matrix(matrix_class, rows, cols=None, low=0, high=10):
49
+ if cols is None:
50
+ cols = rows
51
+
52
+ return matrix_class([
53
+ [random.randint(low, high) for _ in range(cols)]
54
+ for _ in range(rows)
55
+ ])
56
+
57
+ def elementwise(matrix_class, rows, cols=None, func=lambda i, j: 0):
58
+ if cols is None:
59
+ cols = rows
60
+
61
+ return matrix_class([
62
+ [func(i, j) for j in range(cols)]
63
+ for i in range(rows)
64
+ ])
65
+
66
+ def from_string(
67
+ matrix_class,
68
+ my_string,
69
+ dtype=float,
70
+ row_sep='\n'
71
+ ):
72
+ s = my_string.strip()
73
+
74
+ char_list = [
75
+ char
76
+ for char in s
77
+ if char.isdigit() or char in ' .+-j' + row_sep
78
+ ]
79
+
80
+ clean_string = "".join(char_list)
81
+
82
+ matrix_data = [
83
+ [
84
+ dtype(value)
85
+ for value in row.split()
86
+ if value
87
+ ]
88
+ for row in clean_string.split(row_sep)
89
+ if row.strip()
90
+ ]
91
+
92
+ return matrix_class(matrix_data)
93
+
94
+
95
+ def random_uniform(cls, rows, cols=None, low=-1.0, high=1.0):
96
+ if cols is None:
97
+ cols = rows
98
+
99
+ if rows <= 0 or cols <= 0:
100
+ raise ValueError("matrix dimensions must be positive")
101
+
102
+ if low >= high:
103
+ raise ValueError("low must be less than high")
104
+
105
+ return cls([
106
+ [
107
+ _rng.uniform(low, high)
108
+ for _ in range(cols)
109
+ ]
110
+ for _ in range(rows)
111
+ ])
112
+
113
+ def seed(value=None):
114
+ _rng.seed(value)
115
+
matrix/exceptions.py ADDED
File without changes
matrix/manipulation.py ADDED
@@ -0,0 +1,145 @@
1
+ import copy
2
+
3
+ def insert_row(matrix, row_mat):
4
+ cols = matrix.order[1]
5
+
6
+ if len(row_mat) == cols:
7
+ matrix.m.append(row_mat)
8
+ else:
9
+ raise ValueError(
10
+ "Length Error! length of rowMat is not suitable for this Matrix."
11
+ )
12
+
13
+
14
+ def insert_col(matrix, col_mat):
15
+ rows = matrix.order[0]
16
+
17
+ if len(col_mat) == rows:
18
+ for i in range(rows):
19
+ matrix.m[i].append(col_mat[i])
20
+ else:
21
+ raise ValueError(
22
+ "Length Error! length of colMat is not suitable for this Matrix."
23
+ )
24
+
25
+
26
+ def delete_row(matrix, row_index, inplace=False):
27
+ rows = matrix.order[0]
28
+ result = copy.deepcopy(matrix.m)
29
+
30
+ if 0 <= row_index < rows:
31
+ result.pop(row_index)
32
+
33
+ if inplace:
34
+ matrix.m = result
35
+ else:
36
+ return type(matrix)(result)
37
+ else:
38
+ raise ValueError(
39
+ f"Index Error! index out of range {row_index} for 0 to {rows}"
40
+ )
41
+
42
+
43
+ def delete_col(matrix, col_index, inplace=False):
44
+ rows, cols = matrix.order
45
+ result = copy.deepcopy(matrix.m)
46
+
47
+ if 0 <= col_index < cols:
48
+ for row in range(rows):
49
+ result[row].pop(col_index)
50
+
51
+ if inplace:
52
+ matrix.m = result
53
+ else:
54
+ return type(matrix)(result)
55
+ else:
56
+ raise ValueError(
57
+ f"Index Error! index out of range {col_index} for 0 to {cols}"
58
+ )
59
+
60
+
61
+ def get_row(matrix, row_index):
62
+ rows = matrix.order[0]
63
+
64
+ if 0 <= row_index < rows:
65
+ return matrix.m[row_index]
66
+ else:
67
+ raise ValueError()
68
+
69
+
70
+ def get_col(matrix, col_index):
71
+ rows, cols = matrix.order
72
+
73
+ if 0 <= col_index < cols:
74
+ return [matrix.m[i][col_index] for i in range(rows)]
75
+ else:
76
+ raise ValueError()
77
+
78
+ def flatten(matrix):
79
+ result = [
80
+ value
81
+ for row in matrix.m
82
+ for value in row
83
+ ]
84
+
85
+ return type(matrix)([result])
86
+
87
+ def reshape(matrix, rows, cols):
88
+ if rows <= 0 or cols <= 0:
89
+ raise ValueError("matrix dimensions must be positive")
90
+
91
+ if rows * cols != matrix.order[0] * matrix.order[1]:
92
+ raise ValueError(
93
+ "cannot reshape matrix: element count must remain unchanged"
94
+ )
95
+
96
+ values = [
97
+ value
98
+ for row in matrix.m
99
+ for value in row
100
+ ]
101
+
102
+ result = [
103
+ values[i * cols:(i + 1) * cols]
104
+ for i in range(rows)
105
+ ]
106
+
107
+ return type(matrix)(result)
108
+
109
+ def swap_rows(matrix, row1, row2, inplace=False):
110
+ rows, cols = matrix.order
111
+
112
+ if not 0 <= row1 < rows:
113
+ raise IndexError("invalid row index")
114
+
115
+ if not 0 <= row2 < rows:
116
+ raise IndexError("invalid row index")
117
+
118
+ target = matrix if inplace else type(matrix)(copy.deepcopy(matrix.m))
119
+
120
+ target.m[row1], target.m[row2] = (
121
+ target.m[row2],
122
+ target.m[row1]
123
+ )
124
+
125
+ return target
126
+
127
+ def swap_cols(matrix, col1, col2, inplace=False):
128
+ rows, cols = matrix.order
129
+
130
+ if not 0 <= col1 < cols:
131
+ raise IndexError("invalid column index")
132
+
133
+ if not 0 <= col2 < cols:
134
+ raise IndexError("invalid column index")
135
+
136
+ target = matrix if inplace else type(matrix)(copy.deepcopy(matrix.m))
137
+
138
+ for i in range(rows):
139
+ target.m[i][col1], target.m[i][col2] = (
140
+ target.m[i][col2],
141
+ target.m[i][col1]
142
+ )
143
+
144
+ return target
145
+