matrixcea 0.1.0__tar.gz
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.
- matrixcea-0.1.0/CHANGELOG.txt +7 -0
- matrixcea-0.1.0/LICENCE.txt +12 -0
- matrixcea-0.1.0/MANIFEST.in +1 -0
- matrixcea-0.1.0/PKG-INFO +87 -0
- matrixcea-0.1.0/README.md +64 -0
- matrixcea-0.1.0/__init__.py +469 -0
- matrixcea-0.1.0/matrix.py +469 -0
- matrixcea-0.1.0/matrixcea.egg-info/PKG-INFO +87 -0
- matrixcea-0.1.0/matrixcea.egg-info/SOURCES.txt +11 -0
- matrixcea-0.1.0/matrixcea.egg-info/dependency_links.txt +1 -0
- matrixcea-0.1.0/matrixcea.egg-info/top_level.txt +1 -0
- matrixcea-0.1.0/setup.cfg +4 -0
- matrixcea-0.1.0/setup.py +19 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Krishna Bhat U
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
[...rest of MIT text, standard from https://opensource.org/licenses/MIT]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
global-include *.txt *.md *.py
|
matrixcea-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: matrixcea
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Matrix operations and methods
|
|
5
|
+
Home-page: https://github.com/krx7h/matxforge
|
|
6
|
+
Author: Krishna Bhat U
|
|
7
|
+
Author-email: krxshna8@gmail.com
|
|
8
|
+
Keywords: matrixops
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENCE.txt
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: keywords
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# matrixcea
|
|
25
|
+
|
|
26
|
+
**matrixcea** is a simple Python library for performing matrix operations.
|
|
27
|
+
It supports basic linear algebra operations, including addition, subtraction, multiplication, determinant, transpose, reshaping, and even negative powers (using matrix inverse).
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## **Features**
|
|
32
|
+
|
|
33
|
+
- Create matrices from lists of lists or single row.
|
|
34
|
+
- Matrix addition, subtraction, scalar multiplication, and matrix multiplication.
|
|
35
|
+
- Transpose, flatten, and reshape matrices.
|
|
36
|
+
- Determinant calculation for square matrices.
|
|
37
|
+
- Check for square, identity, symmetric, or zero matrices.
|
|
38
|
+
- Raise a matrix to a positive or negative integer power.
|
|
39
|
+
- Compute matrix inverse (for square, non-singular matrices).
|
|
40
|
+
- Element-wise division by a scalar.
|
|
41
|
+
- Operator overloading for Pythonic syntax:
|
|
42
|
+
```python
|
|
43
|
+
A + B
|
|
44
|
+
A - B
|
|
45
|
+
A @ B # matrix multiplication
|
|
46
|
+
A * 3 # scalar multiplication
|
|
47
|
+
3 * A # scalar multiplication
|
|
48
|
+
A ** -1 # matrix inverse
|
|
49
|
+
A ** 3 # matrix power
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## **Usage example**:
|
|
53
|
+
```python
|
|
54
|
+
|
|
55
|
+
from matxxforgex import matrix
|
|
56
|
+
```
|
|
57
|
+
# Create matrices
|
|
58
|
+
```python
|
|
59
|
+
A = matrix([[1, 2], [3, 4]])
|
|
60
|
+
B = matrix([[5, 6], [7, 8]])
|
|
61
|
+
```
|
|
62
|
+
# Arithmetic operations
|
|
63
|
+
```python
|
|
64
|
+
C = A + B
|
|
65
|
+
D = A - B
|
|
66
|
+
E = A @ B
|
|
67
|
+
F = A * 2
|
|
68
|
+
G = 2 * A
|
|
69
|
+
H = A / 2
|
|
70
|
+
```
|
|
71
|
+
# Properties
|
|
72
|
+
```python
|
|
73
|
+
print(A.is_square()) # True
|
|
74
|
+
print(A.is_identity()) # False
|
|
75
|
+
print(A.is_symmetric()) # False
|
|
76
|
+
print(A.is_zero()) # False
|
|
77
|
+
```
|
|
78
|
+
# Advanced
|
|
79
|
+
```python
|
|
80
|
+
det = A.determinant()
|
|
81
|
+
A_inv = A.inverse()
|
|
82
|
+
A_pow = A ** 3
|
|
83
|
+
A_neg = A ** -1
|
|
84
|
+
A_T = A.transpose()
|
|
85
|
+
flat = A.flatten()
|
|
86
|
+
reshaped = A.reshape(1, 4)
|
|
87
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# matrixcea
|
|
2
|
+
|
|
3
|
+
**matrixcea** is a simple Python library for performing matrix operations.
|
|
4
|
+
It supports basic linear algebra operations, including addition, subtraction, multiplication, determinant, transpose, reshaping, and even negative powers (using matrix inverse).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## **Features**
|
|
9
|
+
|
|
10
|
+
- Create matrices from lists of lists or single row.
|
|
11
|
+
- Matrix addition, subtraction, scalar multiplication, and matrix multiplication.
|
|
12
|
+
- Transpose, flatten, and reshape matrices.
|
|
13
|
+
- Determinant calculation for square matrices.
|
|
14
|
+
- Check for square, identity, symmetric, or zero matrices.
|
|
15
|
+
- Raise a matrix to a positive or negative integer power.
|
|
16
|
+
- Compute matrix inverse (for square, non-singular matrices).
|
|
17
|
+
- Element-wise division by a scalar.
|
|
18
|
+
- Operator overloading for Pythonic syntax:
|
|
19
|
+
```python
|
|
20
|
+
A + B
|
|
21
|
+
A - B
|
|
22
|
+
A @ B # matrix multiplication
|
|
23
|
+
A * 3 # scalar multiplication
|
|
24
|
+
3 * A # scalar multiplication
|
|
25
|
+
A ** -1 # matrix inverse
|
|
26
|
+
A ** 3 # matrix power
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## **Usage example**:
|
|
30
|
+
```python
|
|
31
|
+
|
|
32
|
+
from matxxforgex import matrix
|
|
33
|
+
```
|
|
34
|
+
# Create matrices
|
|
35
|
+
```python
|
|
36
|
+
A = matrix([[1, 2], [3, 4]])
|
|
37
|
+
B = matrix([[5, 6], [7, 8]])
|
|
38
|
+
```
|
|
39
|
+
# Arithmetic operations
|
|
40
|
+
```python
|
|
41
|
+
C = A + B
|
|
42
|
+
D = A - B
|
|
43
|
+
E = A @ B
|
|
44
|
+
F = A * 2
|
|
45
|
+
G = 2 * A
|
|
46
|
+
H = A / 2
|
|
47
|
+
```
|
|
48
|
+
# Properties
|
|
49
|
+
```python
|
|
50
|
+
print(A.is_square()) # True
|
|
51
|
+
print(A.is_identity()) # False
|
|
52
|
+
print(A.is_symmetric()) # False
|
|
53
|
+
print(A.is_zero()) # False
|
|
54
|
+
```
|
|
55
|
+
# Advanced
|
|
56
|
+
```python
|
|
57
|
+
det = A.determinant()
|
|
58
|
+
A_inv = A.inverse()
|
|
59
|
+
A_pow = A ** 3
|
|
60
|
+
A_neg = A ** -1
|
|
61
|
+
A_T = A.transpose()
|
|
62
|
+
flat = A.flatten()
|
|
63
|
+
reshaped = A.reshape(1, 4)
|
|
64
|
+
```
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
class matrix:
|
|
2
|
+
"""
|
|
3
|
+
A simple matrix class supporting basic matrix operations such as addition,
|
|
4
|
+
subtraction, multiplication, transpose, reshaping, flattening, and determinant
|
|
5
|
+
calculation. Also provides checks for square, identity, symmetric, and zero matrices.
|
|
6
|
+
|
|
7
|
+
Attributes:
|
|
8
|
+
matrix (list of lists): 2D list representing the matrix elements.
|
|
9
|
+
rows (int): Number of rows in the matrix.
|
|
10
|
+
columns (int): Number of columns in the matrix.
|
|
11
|
+
"""
|
|
12
|
+
def __init__(self,matrix):
|
|
13
|
+
"""
|
|
14
|
+
Initializes a matrix object.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
matrix (list of lists or list of numbers): Input matrix as a 2D list or
|
|
18
|
+
a single row vector as a list.
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
TypeError: If the input is not a list or contains incompatible types.
|
|
22
|
+
"""
|
|
23
|
+
if isinstance(matrix[0], (int, float)):
|
|
24
|
+
matrix = [matrix]
|
|
25
|
+
self.matrix = matrix
|
|
26
|
+
self.rows = len(matrix)
|
|
27
|
+
self.columns = len(matrix[0])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
"""
|
|
32
|
+
Returns a string representation of the matrix.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
str: A string where each row of the matrix is on a new line.
|
|
36
|
+
"""
|
|
37
|
+
matrix = ""
|
|
38
|
+
for row in self.matrix:
|
|
39
|
+
matrix += f"{row}\n"
|
|
40
|
+
return matrix
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def __eq__(self,other):
|
|
44
|
+
"""
|
|
45
|
+
Checks if two matrices are equal.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
other (matrix): Another matrix to compare.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
bool: True if matrices have the same shape and elements, False otherwise.
|
|
52
|
+
"""
|
|
53
|
+
if not isinstance(other, matrix):
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
if self.rows != other.rows or self.columns != other.columns:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
for i in range(self.rows):
|
|
60
|
+
for j in range(self.columns):
|
|
61
|
+
if self.matrix[i][j] != other.matrix[i][j]:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def __getitem__(self,index):
|
|
68
|
+
"""
|
|
69
|
+
Retrieves a row of the matrix by index.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
index (int): Index of the row to retrieve.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
list: The requested row.
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
IndexError: If index is out of range.
|
|
79
|
+
"""
|
|
80
|
+
try:
|
|
81
|
+
return self.matrix[index]
|
|
82
|
+
except:
|
|
83
|
+
return IndexError("Index out of range.")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def __add__(self,other):
|
|
87
|
+
"""
|
|
88
|
+
Adds two matrices element-wise.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
other (matrix): The matrix to add.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
matrix: New matrix representing the sum.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
ValueError: If matrices have different dimensions.
|
|
98
|
+
"""
|
|
99
|
+
r1,c1 = self.rows,self.columns
|
|
100
|
+
r2,c2 = other.rows,other.columns
|
|
101
|
+
if r1 != r2 or c1 != c2:
|
|
102
|
+
raise ValueError("Addition cannot be performed.(Size Mismatch)")
|
|
103
|
+
else:
|
|
104
|
+
sum = [[0 for _ in range(c1)] for _ in range(r1)]
|
|
105
|
+
for i in range(r1):
|
|
106
|
+
for j in range(c1):
|
|
107
|
+
sum[i][j] = self.matrix[i][j] + other.matrix[i][j]
|
|
108
|
+
return matrix(sum)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def __matmul__(self,other):
|
|
112
|
+
"""
|
|
113
|
+
Performs matrix multiplication using the '@' operator.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
other (matrix): The matrix to multiply.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
matrix: New matrix representing the product.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
ValueError: If number of columns in self does not match number of rows in other.
|
|
123
|
+
"""
|
|
124
|
+
if self.columns != other.rows:
|
|
125
|
+
raise ValueError("Matrix multiplication not possible")
|
|
126
|
+
|
|
127
|
+
result = [[0 for _ in range(other.columns)] for _ in range(self.rows)]
|
|
128
|
+
|
|
129
|
+
for i in range(self.rows):
|
|
130
|
+
for j in range(other.columns):
|
|
131
|
+
for k in range(self.columns):
|
|
132
|
+
result[i][j] += self.matrix[i][k] * other.matrix[k][j]
|
|
133
|
+
|
|
134
|
+
return matrix(result)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def __sub__(self,other):
|
|
138
|
+
"""
|
|
139
|
+
Subtracts one matrix from another element-wise.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
other (matrix): The matrix to subtract.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
matrix: New matrix representing the difference.
|
|
146
|
+
|
|
147
|
+
Raises:
|
|
148
|
+
ValueError: If matrices have different dimensions.
|
|
149
|
+
"""
|
|
150
|
+
r1,c1 = self.rows,self.columns
|
|
151
|
+
r2,c2 = other.rows,other.columns
|
|
152
|
+
if r1 != r2 or c1 != c2:
|
|
153
|
+
raise ValueError("Addition cannot be performed.(Size Mismatch)")
|
|
154
|
+
else:
|
|
155
|
+
sub = [[0 for _ in range(c1)] for _ in range(r1)]
|
|
156
|
+
for i in range(r1):
|
|
157
|
+
for j in range(c1):
|
|
158
|
+
sub[i][j] = self.matrix[i][j] - other.matrix[i][j]
|
|
159
|
+
return matrix(sub)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def __mul__(self, scalar):
|
|
163
|
+
"""
|
|
164
|
+
Multiplies the matrix by a scalar.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
scalar (int or float): The scalar value to multiply.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
matrix: New matrix with elements multiplied by scalar.
|
|
171
|
+
"""
|
|
172
|
+
if isinstance(scalar, (int, float)):
|
|
173
|
+
return matrix([[x * scalar for x in row] for row in self.matrix])
|
|
174
|
+
return NotImplemented
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def __rmul__(self, scalar):
|
|
178
|
+
"""
|
|
179
|
+
Enables scalar multiplication from the left.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
scalar (int or float): The scalar value to multiply.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
matrix: New matrix with elements multiplied by scalar.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
return self.__mul__(scalar)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def transpose(self):
|
|
192
|
+
"""
|
|
193
|
+
Transposes the matrix (rows become columns and vice versa).
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
matrix: New matrix representing the transpose.
|
|
197
|
+
"""
|
|
198
|
+
transpose = [[0 for i in range(self.rows)] for i in range(self.columns)]
|
|
199
|
+
for i in range(self.columns):
|
|
200
|
+
for j in range(self.rows):
|
|
201
|
+
transpose[i][j] = self.matrix[j][i]
|
|
202
|
+
return matrix(transpose)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def reshape(self,new_rows,new_cols):
|
|
206
|
+
"""
|
|
207
|
+
Reshapes the matrix to new dimensions.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
new_rows (int): New number of rows.
|
|
211
|
+
new_cols (int): New number of columns.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
matrix: New reshaped matrix.
|
|
215
|
+
|
|
216
|
+
Raises:
|
|
217
|
+
ValueError: If total elements do not match.
|
|
218
|
+
"""
|
|
219
|
+
if (self.rows * self.columns) != (new_rows * new_cols):
|
|
220
|
+
raise ValueError("Size Mismatch.")
|
|
221
|
+
else:
|
|
222
|
+
flat = []
|
|
223
|
+
for i in range(self.rows):
|
|
224
|
+
for j in range(self.columns):
|
|
225
|
+
flat.append(self.matrix[i][j])
|
|
226
|
+
reshape = [[0 for i in range(new_cols)] for i in range(new_rows)]
|
|
227
|
+
num = 0
|
|
228
|
+
for i in range(new_rows):
|
|
229
|
+
for j in range(new_cols):
|
|
230
|
+
reshape[i][j] = flat[num]
|
|
231
|
+
num += 1
|
|
232
|
+
return matrix(reshape)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def flatten(self):
|
|
236
|
+
"""
|
|
237
|
+
Flattens the matrix into a single list.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
list: List of all elements row-wise.
|
|
241
|
+
"""
|
|
242
|
+
flat = []
|
|
243
|
+
for i in range(self.rows):
|
|
244
|
+
for j in range(self.columns):
|
|
245
|
+
flat.append(self.matrix[i][j])
|
|
246
|
+
return flat
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def determinant(self):
|
|
250
|
+
"""
|
|
251
|
+
Calculates the determinant of a square matrix.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
int or float: Determinant value.
|
|
255
|
+
|
|
256
|
+
Raises:
|
|
257
|
+
ValueError: If the matrix is not square.
|
|
258
|
+
"""
|
|
259
|
+
# must be square
|
|
260
|
+
if self.rows != self.columns:
|
|
261
|
+
raise ValueError("Determinant only defined for square matrices")
|
|
262
|
+
|
|
263
|
+
# 1×1 matrix
|
|
264
|
+
if self.rows == 1:
|
|
265
|
+
return self.matrix[0][0]
|
|
266
|
+
|
|
267
|
+
# 2×2 matrix
|
|
268
|
+
if self.rows == 2:
|
|
269
|
+
return (self.matrix[0][0] * self.matrix[1][1] -
|
|
270
|
+
self.matrix[0][1] * self.matrix[1][0])
|
|
271
|
+
|
|
272
|
+
# larger matrices (recursive expansion)
|
|
273
|
+
det = 0
|
|
274
|
+
for col in range(self.columns):
|
|
275
|
+
# build minor matrix
|
|
276
|
+
minor = []
|
|
277
|
+
for i in range(1, self.rows):
|
|
278
|
+
row = []
|
|
279
|
+
for j in range(self.columns):
|
|
280
|
+
if j != col:
|
|
281
|
+
row.append(self.matrix[i][j])
|
|
282
|
+
minor.append(row)
|
|
283
|
+
|
|
284
|
+
sign = (-1) ** col
|
|
285
|
+
det += sign * self.matrix[0][col] * matrix(minor).determinant()
|
|
286
|
+
|
|
287
|
+
return det
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def is_square(self):
|
|
291
|
+
"""
|
|
292
|
+
Checks if the matrix is square.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
bool: True if rows == columns, else False.
|
|
296
|
+
"""
|
|
297
|
+
if (self.rows == self.columns):
|
|
298
|
+
return True
|
|
299
|
+
else:
|
|
300
|
+
return False
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def is_identity(self):
|
|
304
|
+
"""
|
|
305
|
+
Checks if the matrix is an identity matrix.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
bool: True if identity, else False.
|
|
309
|
+
"""
|
|
310
|
+
if self.rows != self.columns:
|
|
311
|
+
return False
|
|
312
|
+
|
|
313
|
+
for i in range(self.rows):
|
|
314
|
+
for j in range(self.columns):
|
|
315
|
+
if i == j:
|
|
316
|
+
if self.matrix[i][j] != 1:
|
|
317
|
+
return False
|
|
318
|
+
else:
|
|
319
|
+
if self.matrix[i][j] != 0:
|
|
320
|
+
return False
|
|
321
|
+
return True
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def is_symmetric(self):
|
|
325
|
+
"""
|
|
326
|
+
Checks if the matrix is symmetric.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
bool: True if symmetric, else False.
|
|
330
|
+
"""
|
|
331
|
+
if (self == self.transpose()):
|
|
332
|
+
return True
|
|
333
|
+
else:
|
|
334
|
+
return False
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def is_zero(self):
|
|
338
|
+
"""
|
|
339
|
+
Checks if the matrix is a zero matrix.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
bool: True if all elements are zero, else False.
|
|
343
|
+
"""
|
|
344
|
+
for i in range(self.rows):
|
|
345
|
+
for j in range(self.columns):
|
|
346
|
+
if self.matrix[i][j] != 0:
|
|
347
|
+
return False
|
|
348
|
+
return True
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def __truediv__(self, scalar):
|
|
352
|
+
"""
|
|
353
|
+
Divides the matrix by a scalar.
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
scalar (int or float): The scalar to divide by.
|
|
357
|
+
|
|
358
|
+
Returns:
|
|
359
|
+
matrix: New matrix with elements divided by scalar.
|
|
360
|
+
|
|
361
|
+
Raises:
|
|
362
|
+
ValueError: If scalar is not a number.
|
|
363
|
+
ZeroDivisionError: If scalar is zero.
|
|
364
|
+
"""
|
|
365
|
+
if not isinstance(scalar, (int, float)):
|
|
366
|
+
raise ValueError("Can only divide by a scalar")
|
|
367
|
+
if scalar == 0:
|
|
368
|
+
raise ZeroDivisionError("Division by zero is not allowed")
|
|
369
|
+
|
|
370
|
+
# multiply each element by 1/scalar
|
|
371
|
+
new_matrix = [[x / scalar for x in row] for row in self.matrix]
|
|
372
|
+
return matrix(new_matrix)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def inverse(self):
|
|
376
|
+
"""
|
|
377
|
+
Returns the inverse of a square, non-singular matrix.
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
matrix: The inverse of the matrix.
|
|
381
|
+
|
|
382
|
+
Raises:
|
|
383
|
+
ValueError: If the matrix is not square or singular (determinant is 0).
|
|
384
|
+
"""
|
|
385
|
+
if not self.is_square():
|
|
386
|
+
raise ValueError("Only square matrices can have an inverse.")
|
|
387
|
+
|
|
388
|
+
det = self.determinant()
|
|
389
|
+
if det == 0:
|
|
390
|
+
raise ValueError("Singular matrix; inverse does not exist.")
|
|
391
|
+
|
|
392
|
+
# 1x1 matrix
|
|
393
|
+
if self.rows == 1:
|
|
394
|
+
return matrix([[1 / self.matrix[0][0]]])
|
|
395
|
+
|
|
396
|
+
# 2x2 matrix
|
|
397
|
+
if self.rows == 2:
|
|
398
|
+
a, b = self.matrix[0]
|
|
399
|
+
c, d = self.matrix[1]
|
|
400
|
+
inv = [[d / det, -b / det],
|
|
401
|
+
[-c / det, a / det]]
|
|
402
|
+
return matrix(inv)
|
|
403
|
+
|
|
404
|
+
# NxN matrix: use adjugate method
|
|
405
|
+
cofactors = []
|
|
406
|
+
for i in range(self.rows):
|
|
407
|
+
cofactor_row = []
|
|
408
|
+
for j in range(self.columns):
|
|
409
|
+
# Build minor matrix by removing row i and column j
|
|
410
|
+
minor = [[self.matrix[m][n] for n in range(self.columns) if n != j]
|
|
411
|
+
for m in range(self.rows) if m != i]
|
|
412
|
+
# Cofactor = determinant of minor * (-1)^(i+j)
|
|
413
|
+
cofactor_row.append(((-1) ** (i + j)) * matrix(minor).determinant())
|
|
414
|
+
cofactors.append(cofactor_row)
|
|
415
|
+
|
|
416
|
+
# Transpose cofactor matrix to get adjugate
|
|
417
|
+
adjugate = matrix(cofactors).transpose()
|
|
418
|
+
|
|
419
|
+
# Divide each element by determinant
|
|
420
|
+
inv_matrix = [[x / det for x in row] for row in adjugate.matrix]
|
|
421
|
+
|
|
422
|
+
return matrix(inv_matrix)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def __pow__(self, power):
|
|
426
|
+
"""
|
|
427
|
+
Raises the matrix to the given positive integer power.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
power (int): The power to raise the matrix to. Must be >= 0.
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
matrix: New matrix representing self ** power.
|
|
434
|
+
|
|
435
|
+
Raises:
|
|
436
|
+
ValueError: If matrix is not square or power is negative.
|
|
437
|
+
"""
|
|
438
|
+
if not self.is_square():
|
|
439
|
+
raise ValueError("Only square matrices can be raised to a power.")
|
|
440
|
+
if power < 0:
|
|
441
|
+
inv = self.inverse()
|
|
442
|
+
return inv ** (-power)
|
|
443
|
+
|
|
444
|
+
# Power = 0 , return identity matrix
|
|
445
|
+
if power == 0:
|
|
446
|
+
return matrix([[1 if i == j else 0 for j in range(self.columns)] for i in range(self.rows)])
|
|
447
|
+
|
|
448
|
+
# Power = 1 , return a copy
|
|
449
|
+
result = matrix([row[:] for row in self.matrix])
|
|
450
|
+
|
|
451
|
+
for _ in range(1, power):
|
|
452
|
+
result = result @ self
|
|
453
|
+
|
|
454
|
+
return result
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
class matrix:
|
|
2
|
+
"""
|
|
3
|
+
A simple matrix class supporting basic matrix operations such as addition,
|
|
4
|
+
subtraction, multiplication, transpose, reshaping, flattening, and determinant
|
|
5
|
+
calculation. Also provides checks for square, identity, symmetric, and zero matrices.
|
|
6
|
+
|
|
7
|
+
Attributes:
|
|
8
|
+
matrix (list of lists): 2D list representing the matrix elements.
|
|
9
|
+
rows (int): Number of rows in the matrix.
|
|
10
|
+
columns (int): Number of columns in the matrix.
|
|
11
|
+
"""
|
|
12
|
+
def __init__(self,matrix):
|
|
13
|
+
"""
|
|
14
|
+
Initializes a matrix object.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
matrix (list of lists or list of numbers): Input matrix as a 2D list or
|
|
18
|
+
a single row vector as a list.
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
TypeError: If the input is not a list or contains incompatible types.
|
|
22
|
+
"""
|
|
23
|
+
if isinstance(matrix[0], (int, float)):
|
|
24
|
+
matrix = [matrix]
|
|
25
|
+
self.matrix = matrix
|
|
26
|
+
self.rows = len(matrix)
|
|
27
|
+
self.columns = len(matrix[0])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
"""
|
|
32
|
+
Returns a string representation of the matrix.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
str: A string where each row of the matrix is on a new line.
|
|
36
|
+
"""
|
|
37
|
+
matrix = ""
|
|
38
|
+
for row in self.matrix:
|
|
39
|
+
matrix += f"{row}\n"
|
|
40
|
+
return matrix
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def __eq__(self,other):
|
|
44
|
+
"""
|
|
45
|
+
Checks if two matrices are equal.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
other (matrix): Another matrix to compare.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
bool: True if matrices have the same shape and elements, False otherwise.
|
|
52
|
+
"""
|
|
53
|
+
if not isinstance(other, matrix):
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
if self.rows != other.rows or self.columns != other.columns:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
for i in range(self.rows):
|
|
60
|
+
for j in range(self.columns):
|
|
61
|
+
if self.matrix[i][j] != other.matrix[i][j]:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def __getitem__(self,index):
|
|
68
|
+
"""
|
|
69
|
+
Retrieves a row of the matrix by index.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
index (int): Index of the row to retrieve.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
list: The requested row.
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
IndexError: If index is out of range.
|
|
79
|
+
"""
|
|
80
|
+
try:
|
|
81
|
+
return self.matrix[index]
|
|
82
|
+
except:
|
|
83
|
+
return IndexError("Index out of range.")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def __add__(self,other):
|
|
87
|
+
"""
|
|
88
|
+
Adds two matrices element-wise.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
other (matrix): The matrix to add.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
matrix: New matrix representing the sum.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
ValueError: If matrices have different dimensions.
|
|
98
|
+
"""
|
|
99
|
+
r1,c1 = self.rows,self.columns
|
|
100
|
+
r2,c2 = other.rows,other.columns
|
|
101
|
+
if r1 != r2 or c1 != c2:
|
|
102
|
+
raise ValueError("Addition cannot be performed.(Size Mismatch)")
|
|
103
|
+
else:
|
|
104
|
+
sum = [[0 for _ in range(c1)] for _ in range(r1)]
|
|
105
|
+
for i in range(r1):
|
|
106
|
+
for j in range(c1):
|
|
107
|
+
sum[i][j] = self.matrix[i][j] + other.matrix[i][j]
|
|
108
|
+
return matrix(sum)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def __matmul__(self,other):
|
|
112
|
+
"""
|
|
113
|
+
Performs matrix multiplication using the '@' operator.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
other (matrix): The matrix to multiply.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
matrix: New matrix representing the product.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
ValueError: If number of columns in self does not match number of rows in other.
|
|
123
|
+
"""
|
|
124
|
+
if self.columns != other.rows:
|
|
125
|
+
raise ValueError("Matrix multiplication not possible")
|
|
126
|
+
|
|
127
|
+
result = [[0 for _ in range(other.columns)] for _ in range(self.rows)]
|
|
128
|
+
|
|
129
|
+
for i in range(self.rows):
|
|
130
|
+
for j in range(other.columns):
|
|
131
|
+
for k in range(self.columns):
|
|
132
|
+
result[i][j] += self.matrix[i][k] * other.matrix[k][j]
|
|
133
|
+
|
|
134
|
+
return matrix(result)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def __sub__(self,other):
|
|
138
|
+
"""
|
|
139
|
+
Subtracts one matrix from another element-wise.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
other (matrix): The matrix to subtract.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
matrix: New matrix representing the difference.
|
|
146
|
+
|
|
147
|
+
Raises:
|
|
148
|
+
ValueError: If matrices have different dimensions.
|
|
149
|
+
"""
|
|
150
|
+
r1,c1 = self.rows,self.columns
|
|
151
|
+
r2,c2 = other.rows,other.columns
|
|
152
|
+
if r1 != r2 or c1 != c2:
|
|
153
|
+
raise ValueError("Addition cannot be performed.(Size Mismatch)")
|
|
154
|
+
else:
|
|
155
|
+
sub = [[0 for _ in range(c1)] for _ in range(r1)]
|
|
156
|
+
for i in range(r1):
|
|
157
|
+
for j in range(c1):
|
|
158
|
+
sub[i][j] = self.matrix[i][j] - other.matrix[i][j]
|
|
159
|
+
return matrix(sub)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def __mul__(self, scalar):
|
|
163
|
+
"""
|
|
164
|
+
Multiplies the matrix by a scalar.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
scalar (int or float): The scalar value to multiply.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
matrix: New matrix with elements multiplied by scalar.
|
|
171
|
+
"""
|
|
172
|
+
if isinstance(scalar, (int, float)):
|
|
173
|
+
return matrix([[x * scalar for x in row] for row in self.matrix])
|
|
174
|
+
return NotImplemented
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def __rmul__(self, scalar):
|
|
178
|
+
"""
|
|
179
|
+
Enables scalar multiplication from the left.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
scalar (int or float): The scalar value to multiply.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
matrix: New matrix with elements multiplied by scalar.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
return self.__mul__(scalar)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def transpose(self):
|
|
192
|
+
"""
|
|
193
|
+
Transposes the matrix (rows become columns and vice versa).
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
matrix: New matrix representing the transpose.
|
|
197
|
+
"""
|
|
198
|
+
transpose = [[0 for i in range(self.rows)] for i in range(self.columns)]
|
|
199
|
+
for i in range(self.columns):
|
|
200
|
+
for j in range(self.rows):
|
|
201
|
+
transpose[i][j] = self.matrix[j][i]
|
|
202
|
+
return matrix(transpose)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def reshape(self,new_rows,new_cols):
|
|
206
|
+
"""
|
|
207
|
+
Reshapes the matrix to new dimensions.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
new_rows (int): New number of rows.
|
|
211
|
+
new_cols (int): New number of columns.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
matrix: New reshaped matrix.
|
|
215
|
+
|
|
216
|
+
Raises:
|
|
217
|
+
ValueError: If total elements do not match.
|
|
218
|
+
"""
|
|
219
|
+
if (self.rows * self.columns) != (new_rows * new_cols):
|
|
220
|
+
raise ValueError("Size Mismatch.")
|
|
221
|
+
else:
|
|
222
|
+
flat = []
|
|
223
|
+
for i in range(self.rows):
|
|
224
|
+
for j in range(self.columns):
|
|
225
|
+
flat.append(self.matrix[i][j])
|
|
226
|
+
reshape = [[0 for i in range(new_cols)] for i in range(new_rows)]
|
|
227
|
+
num = 0
|
|
228
|
+
for i in range(new_rows):
|
|
229
|
+
for j in range(new_cols):
|
|
230
|
+
reshape[i][j] = flat[num]
|
|
231
|
+
num += 1
|
|
232
|
+
return matrix(reshape)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def flatten(self):
|
|
236
|
+
"""
|
|
237
|
+
Flattens the matrix into a single list.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
list: List of all elements row-wise.
|
|
241
|
+
"""
|
|
242
|
+
flat = []
|
|
243
|
+
for i in range(self.rows):
|
|
244
|
+
for j in range(self.columns):
|
|
245
|
+
flat.append(self.matrix[i][j])
|
|
246
|
+
return flat
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def determinant(self):
|
|
250
|
+
"""
|
|
251
|
+
Calculates the determinant of a square matrix.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
int or float: Determinant value.
|
|
255
|
+
|
|
256
|
+
Raises:
|
|
257
|
+
ValueError: If the matrix is not square.
|
|
258
|
+
"""
|
|
259
|
+
# must be square
|
|
260
|
+
if self.rows != self.columns:
|
|
261
|
+
raise ValueError("Determinant only defined for square matrices")
|
|
262
|
+
|
|
263
|
+
# 1×1 matrix
|
|
264
|
+
if self.rows == 1:
|
|
265
|
+
return self.matrix[0][0]
|
|
266
|
+
|
|
267
|
+
# 2×2 matrix
|
|
268
|
+
if self.rows == 2:
|
|
269
|
+
return (self.matrix[0][0] * self.matrix[1][1] -
|
|
270
|
+
self.matrix[0][1] * self.matrix[1][0])
|
|
271
|
+
|
|
272
|
+
# larger matrices (recursive expansion)
|
|
273
|
+
det = 0
|
|
274
|
+
for col in range(self.columns):
|
|
275
|
+
# build minor matrix
|
|
276
|
+
minor = []
|
|
277
|
+
for i in range(1, self.rows):
|
|
278
|
+
row = []
|
|
279
|
+
for j in range(self.columns):
|
|
280
|
+
if j != col:
|
|
281
|
+
row.append(self.matrix[i][j])
|
|
282
|
+
minor.append(row)
|
|
283
|
+
|
|
284
|
+
sign = (-1) ** col
|
|
285
|
+
det += sign * self.matrix[0][col] * matrix(minor).determinant()
|
|
286
|
+
|
|
287
|
+
return det
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def is_square(self):
|
|
291
|
+
"""
|
|
292
|
+
Checks if the matrix is square.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
bool: True if rows == columns, else False.
|
|
296
|
+
"""
|
|
297
|
+
if (self.rows == self.columns):
|
|
298
|
+
return True
|
|
299
|
+
else:
|
|
300
|
+
return False
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def is_identity(self):
|
|
304
|
+
"""
|
|
305
|
+
Checks if the matrix is an identity matrix.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
bool: True if identity, else False.
|
|
309
|
+
"""
|
|
310
|
+
if self.rows != self.columns:
|
|
311
|
+
return False
|
|
312
|
+
|
|
313
|
+
for i in range(self.rows):
|
|
314
|
+
for j in range(self.columns):
|
|
315
|
+
if i == j:
|
|
316
|
+
if self.matrix[i][j] != 1:
|
|
317
|
+
return False
|
|
318
|
+
else:
|
|
319
|
+
if self.matrix[i][j] != 0:
|
|
320
|
+
return False
|
|
321
|
+
return True
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def is_symmetric(self):
|
|
325
|
+
"""
|
|
326
|
+
Checks if the matrix is symmetric.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
bool: True if symmetric, else False.
|
|
330
|
+
"""
|
|
331
|
+
if (self == self.transpose()):
|
|
332
|
+
return True
|
|
333
|
+
else:
|
|
334
|
+
return False
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def is_zero(self):
|
|
338
|
+
"""
|
|
339
|
+
Checks if the matrix is a zero matrix.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
bool: True if all elements are zero, else False.
|
|
343
|
+
"""
|
|
344
|
+
for i in range(self.rows):
|
|
345
|
+
for j in range(self.columns):
|
|
346
|
+
if self.matrix[i][j] != 0:
|
|
347
|
+
return False
|
|
348
|
+
return True
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def __truediv__(self, scalar):
|
|
352
|
+
"""
|
|
353
|
+
Divides the matrix by a scalar.
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
scalar (int or float): The scalar to divide by.
|
|
357
|
+
|
|
358
|
+
Returns:
|
|
359
|
+
matrix: New matrix with elements divided by scalar.
|
|
360
|
+
|
|
361
|
+
Raises:
|
|
362
|
+
ValueError: If scalar is not a number.
|
|
363
|
+
ZeroDivisionError: If scalar is zero.
|
|
364
|
+
"""
|
|
365
|
+
if not isinstance(scalar, (int, float)):
|
|
366
|
+
raise ValueError("Can only divide by a scalar")
|
|
367
|
+
if scalar == 0:
|
|
368
|
+
raise ZeroDivisionError("Division by zero is not allowed")
|
|
369
|
+
|
|
370
|
+
# multiply each element by 1/scalar
|
|
371
|
+
new_matrix = [[x / scalar for x in row] for row in self.matrix]
|
|
372
|
+
return matrix(new_matrix)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def inverse(self):
|
|
376
|
+
"""
|
|
377
|
+
Returns the inverse of a square, non-singular matrix.
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
matrix: The inverse of the matrix.
|
|
381
|
+
|
|
382
|
+
Raises:
|
|
383
|
+
ValueError: If the matrix is not square or singular (determinant is 0).
|
|
384
|
+
"""
|
|
385
|
+
if not self.is_square():
|
|
386
|
+
raise ValueError("Only square matrices can have an inverse.")
|
|
387
|
+
|
|
388
|
+
det = self.determinant()
|
|
389
|
+
if det == 0:
|
|
390
|
+
raise ValueError("Singular matrix; inverse does not exist.")
|
|
391
|
+
|
|
392
|
+
# 1x1 matrix
|
|
393
|
+
if self.rows == 1:
|
|
394
|
+
return matrix([[1 / self.matrix[0][0]]])
|
|
395
|
+
|
|
396
|
+
# 2x2 matrix
|
|
397
|
+
if self.rows == 2:
|
|
398
|
+
a, b = self.matrix[0]
|
|
399
|
+
c, d = self.matrix[1]
|
|
400
|
+
inv = [[d / det, -b / det],
|
|
401
|
+
[-c / det, a / det]]
|
|
402
|
+
return matrix(inv)
|
|
403
|
+
|
|
404
|
+
# NxN matrix: use adjugate method
|
|
405
|
+
cofactors = []
|
|
406
|
+
for i in range(self.rows):
|
|
407
|
+
cofactor_row = []
|
|
408
|
+
for j in range(self.columns):
|
|
409
|
+
# Build minor matrix by removing row i and column j
|
|
410
|
+
minor = [[self.matrix[m][n] for n in range(self.columns) if n != j]
|
|
411
|
+
for m in range(self.rows) if m != i]
|
|
412
|
+
# Cofactor = determinant of minor * (-1)^(i+j)
|
|
413
|
+
cofactor_row.append(((-1) ** (i + j)) * matrix(minor).determinant())
|
|
414
|
+
cofactors.append(cofactor_row)
|
|
415
|
+
|
|
416
|
+
# Transpose cofactor matrix to get adjugate
|
|
417
|
+
adjugate = matrix(cofactors).transpose()
|
|
418
|
+
|
|
419
|
+
# Divide each element by determinant
|
|
420
|
+
inv_matrix = [[x / det for x in row] for row in adjugate.matrix]
|
|
421
|
+
|
|
422
|
+
return matrix(inv_matrix)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def __pow__(self, power):
|
|
426
|
+
"""
|
|
427
|
+
Raises the matrix to the given positive integer power.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
power (int): The power to raise the matrix to. Must be >= 0.
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
matrix: New matrix representing self ** power.
|
|
434
|
+
|
|
435
|
+
Raises:
|
|
436
|
+
ValueError: If matrix is not square or power is negative.
|
|
437
|
+
"""
|
|
438
|
+
if not self.is_square():
|
|
439
|
+
raise ValueError("Only square matrices can be raised to a power.")
|
|
440
|
+
if power < 0:
|
|
441
|
+
inv = self.inverse()
|
|
442
|
+
return inv ** (-power)
|
|
443
|
+
|
|
444
|
+
# Power = 0 , return identity matrix
|
|
445
|
+
if power == 0:
|
|
446
|
+
return matrix([[1 if i == j else 0 for j in range(self.columns)] for i in range(self.rows)])
|
|
447
|
+
|
|
448
|
+
# Power = 1 , return a copy
|
|
449
|
+
result = matrix([row[:] for row in self.matrix])
|
|
450
|
+
|
|
451
|
+
for _ in range(1, power):
|
|
452
|
+
result = result @ self
|
|
453
|
+
|
|
454
|
+
return result
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: matrixcea
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Matrix operations and methods
|
|
5
|
+
Home-page: https://github.com/krx7h/matxforge
|
|
6
|
+
Author: Krishna Bhat U
|
|
7
|
+
Author-email: krxshna8@gmail.com
|
|
8
|
+
Keywords: matrixops
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENCE.txt
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: keywords
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# matrixcea
|
|
25
|
+
|
|
26
|
+
**matrixcea** is a simple Python library for performing matrix operations.
|
|
27
|
+
It supports basic linear algebra operations, including addition, subtraction, multiplication, determinant, transpose, reshaping, and even negative powers (using matrix inverse).
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## **Features**
|
|
32
|
+
|
|
33
|
+
- Create matrices from lists of lists or single row.
|
|
34
|
+
- Matrix addition, subtraction, scalar multiplication, and matrix multiplication.
|
|
35
|
+
- Transpose, flatten, and reshape matrices.
|
|
36
|
+
- Determinant calculation for square matrices.
|
|
37
|
+
- Check for square, identity, symmetric, or zero matrices.
|
|
38
|
+
- Raise a matrix to a positive or negative integer power.
|
|
39
|
+
- Compute matrix inverse (for square, non-singular matrices).
|
|
40
|
+
- Element-wise division by a scalar.
|
|
41
|
+
- Operator overloading for Pythonic syntax:
|
|
42
|
+
```python
|
|
43
|
+
A + B
|
|
44
|
+
A - B
|
|
45
|
+
A @ B # matrix multiplication
|
|
46
|
+
A * 3 # scalar multiplication
|
|
47
|
+
3 * A # scalar multiplication
|
|
48
|
+
A ** -1 # matrix inverse
|
|
49
|
+
A ** 3 # matrix power
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## **Usage example**:
|
|
53
|
+
```python
|
|
54
|
+
|
|
55
|
+
from matxxforgex import matrix
|
|
56
|
+
```
|
|
57
|
+
# Create matrices
|
|
58
|
+
```python
|
|
59
|
+
A = matrix([[1, 2], [3, 4]])
|
|
60
|
+
B = matrix([[5, 6], [7, 8]])
|
|
61
|
+
```
|
|
62
|
+
# Arithmetic operations
|
|
63
|
+
```python
|
|
64
|
+
C = A + B
|
|
65
|
+
D = A - B
|
|
66
|
+
E = A @ B
|
|
67
|
+
F = A * 2
|
|
68
|
+
G = 2 * A
|
|
69
|
+
H = A / 2
|
|
70
|
+
```
|
|
71
|
+
# Properties
|
|
72
|
+
```python
|
|
73
|
+
print(A.is_square()) # True
|
|
74
|
+
print(A.is_identity()) # False
|
|
75
|
+
print(A.is_symmetric()) # False
|
|
76
|
+
print(A.is_zero()) # False
|
|
77
|
+
```
|
|
78
|
+
# Advanced
|
|
79
|
+
```python
|
|
80
|
+
det = A.determinant()
|
|
81
|
+
A_inv = A.inverse()
|
|
82
|
+
A_pow = A ** 3
|
|
83
|
+
A_neg = A ** -1
|
|
84
|
+
A_T = A.transpose()
|
|
85
|
+
flat = A.flatten()
|
|
86
|
+
reshaped = A.reshape(1, 4)
|
|
87
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
matrixcea-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="matrixcea",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
author="Krishna Bhat U",
|
|
8
|
+
author_email="krxshna8@gmail.com",
|
|
9
|
+
description="Matrix operations and methods",
|
|
10
|
+
long_description=open("README.md").read(),
|
|
11
|
+
long_description_content_type="text/markdown",
|
|
12
|
+
url="https://github.com/krx7h/matxforge",
|
|
13
|
+
classifiers=[
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
],
|
|
18
|
+
keywords='matrixops'
|
|
19
|
+
)
|