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/__init__.py
ADDED
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
|
+
|