mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
fix: mypy 0.991 issues (#7988)
* fix: mypy 0.991 issues * fix: invalid condition for base case
This commit is contained in:
parent
4ce8ad9ce6
commit
8bfd1c844b
|
@ -76,8 +76,9 @@ def decimal_to_any(num: int, base: int) -> str:
|
||||||
div, mod = divmod(num, base)
|
div, mod = divmod(num, base)
|
||||||
if base >= 11 and 9 < mod < 36:
|
if base >= 11 and 9 < mod < 36:
|
||||||
actual_value = ALPHABET_VALUES[str(mod)]
|
actual_value = ALPHABET_VALUES[str(mod)]
|
||||||
mod = actual_value
|
else:
|
||||||
new_value += str(mod)
|
actual_value = str(mod)
|
||||||
|
new_value += actual_value
|
||||||
div = num // base
|
div = num // base
|
||||||
num = div
|
num = div
|
||||||
if div == 0:
|
if div == 0:
|
||||||
|
|
|
@ -49,7 +49,7 @@ class LinkedList:
|
||||||
>>> print(linked_list)
|
>>> print(linked_list)
|
||||||
9 --> 14 --> 23
|
9 --> 14 --> 23
|
||||||
"""
|
"""
|
||||||
if not self.is_empty:
|
if self.is_empty():
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
iterate = self.head
|
iterate = self.head
|
||||||
|
|
|
@ -1,366 +1,366 @@
|
||||||
# An OOP approach to representing and manipulating matrices
|
# An OOP approach to representing and manipulating matrices
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
class Matrix:
|
class Matrix:
|
||||||
"""
|
"""
|
||||||
Matrix object generated from a 2D array where each element is an array representing
|
Matrix object generated from a 2D array where each element is an array representing
|
||||||
a row.
|
a row.
|
||||||
Rows can contain type int or float.
|
Rows can contain type int or float.
|
||||||
Common operations and information available.
|
Common operations and information available.
|
||||||
>>> rows = [
|
>>> rows = [
|
||||||
... [1, 2, 3],
|
... [1, 2, 3],
|
||||||
... [4, 5, 6],
|
... [4, 5, 6],
|
||||||
... [7, 8, 9]
|
... [7, 8, 9]
|
||||||
... ]
|
... ]
|
||||||
>>> matrix = Matrix(rows)
|
>>> matrix = Matrix(rows)
|
||||||
>>> print(matrix)
|
>>> print(matrix)
|
||||||
[[1. 2. 3.]
|
[[1. 2. 3.]
|
||||||
[4. 5. 6.]
|
[4. 5. 6.]
|
||||||
[7. 8. 9.]]
|
[7. 8. 9.]]
|
||||||
|
|
||||||
Matrix rows and columns are available as 2D arrays
|
Matrix rows and columns are available as 2D arrays
|
||||||
>>> matrix.rows
|
>>> matrix.rows
|
||||||
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||||
>>> matrix.columns()
|
>>> matrix.columns()
|
||||||
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
|
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
|
||||||
|
|
||||||
Order is returned as a tuple
|
Order is returned as a tuple
|
||||||
>>> matrix.order
|
>>> matrix.order
|
||||||
(3, 3)
|
(3, 3)
|
||||||
|
|
||||||
Squareness and invertability are represented as bool
|
Squareness and invertability are represented as bool
|
||||||
>>> matrix.is_square
|
>>> matrix.is_square
|
||||||
True
|
True
|
||||||
>>> matrix.is_invertable()
|
>>> matrix.is_invertable()
|
||||||
False
|
False
|
||||||
|
|
||||||
Identity, Minors, Cofactors and Adjugate are returned as Matrices. Inverse can be
|
Identity, Minors, Cofactors and Adjugate are returned as Matrices. Inverse can be
|
||||||
a Matrix or Nonetype
|
a Matrix or Nonetype
|
||||||
>>> print(matrix.identity())
|
>>> print(matrix.identity())
|
||||||
[[1. 0. 0.]
|
[[1. 0. 0.]
|
||||||
[0. 1. 0.]
|
[0. 1. 0.]
|
||||||
[0. 0. 1.]]
|
[0. 0. 1.]]
|
||||||
>>> print(matrix.minors())
|
>>> print(matrix.minors())
|
||||||
[[-3. -6. -3.]
|
[[-3. -6. -3.]
|
||||||
[-6. -12. -6.]
|
[-6. -12. -6.]
|
||||||
[-3. -6. -3.]]
|
[-3. -6. -3.]]
|
||||||
>>> print(matrix.cofactors())
|
>>> print(matrix.cofactors())
|
||||||
[[-3. 6. -3.]
|
[[-3. 6. -3.]
|
||||||
[6. -12. 6.]
|
[6. -12. 6.]
|
||||||
[-3. 6. -3.]]
|
[-3. 6. -3.]]
|
||||||
>>> # won't be apparent due to the nature of the cofactor matrix
|
>>> # won't be apparent due to the nature of the cofactor matrix
|
||||||
>>> print(matrix.adjugate())
|
>>> print(matrix.adjugate())
|
||||||
[[-3. 6. -3.]
|
[[-3. 6. -3.]
|
||||||
[6. -12. 6.]
|
[6. -12. 6.]
|
||||||
[-3. 6. -3.]]
|
[-3. 6. -3.]]
|
||||||
>>> matrix.inverse()
|
>>> matrix.inverse()
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
TypeError: Only matrices with a non-zero determinant have an inverse
|
TypeError: Only matrices with a non-zero determinant have an inverse
|
||||||
|
|
||||||
Determinant is an int, float, or Nonetype
|
Determinant is an int, float, or Nonetype
|
||||||
>>> matrix.determinant()
|
>>> matrix.determinant()
|
||||||
0
|
0
|
||||||
|
|
||||||
Negation, scalar multiplication, addition, subtraction, multiplication and
|
Negation, scalar multiplication, addition, subtraction, multiplication and
|
||||||
exponentiation are available and all return a Matrix
|
exponentiation are available and all return a Matrix
|
||||||
>>> print(-matrix)
|
>>> print(-matrix)
|
||||||
[[-1. -2. -3.]
|
[[-1. -2. -3.]
|
||||||
[-4. -5. -6.]
|
[-4. -5. -6.]
|
||||||
[-7. -8. -9.]]
|
[-7. -8. -9.]]
|
||||||
>>> matrix2 = matrix * 3
|
>>> matrix2 = matrix * 3
|
||||||
>>> print(matrix2)
|
>>> print(matrix2)
|
||||||
[[3. 6. 9.]
|
[[3. 6. 9.]
|
||||||
[12. 15. 18.]
|
[12. 15. 18.]
|
||||||
[21. 24. 27.]]
|
[21. 24. 27.]]
|
||||||
>>> print(matrix + matrix2)
|
>>> print(matrix + matrix2)
|
||||||
[[4. 8. 12.]
|
[[4. 8. 12.]
|
||||||
[16. 20. 24.]
|
[16. 20. 24.]
|
||||||
[28. 32. 36.]]
|
[28. 32. 36.]]
|
||||||
>>> print(matrix - matrix2)
|
>>> print(matrix - matrix2)
|
||||||
[[-2. -4. -6.]
|
[[-2. -4. -6.]
|
||||||
[-8. -10. -12.]
|
[-8. -10. -12.]
|
||||||
[-14. -16. -18.]]
|
[-14. -16. -18.]]
|
||||||
>>> print(matrix ** 3)
|
>>> print(matrix ** 3)
|
||||||
[[468. 576. 684.]
|
[[468. 576. 684.]
|
||||||
[1062. 1305. 1548.]
|
[1062. 1305. 1548.]
|
||||||
[1656. 2034. 2412.]]
|
[1656. 2034. 2412.]]
|
||||||
|
|
||||||
Matrices can also be modified
|
Matrices can also be modified
|
||||||
>>> matrix.add_row([10, 11, 12])
|
>>> matrix.add_row([10, 11, 12])
|
||||||
>>> print(matrix)
|
>>> print(matrix)
|
||||||
[[1. 2. 3.]
|
[[1. 2. 3.]
|
||||||
[4. 5. 6.]
|
[4. 5. 6.]
|
||||||
[7. 8. 9.]
|
[7. 8. 9.]
|
||||||
[10. 11. 12.]]
|
[10. 11. 12.]]
|
||||||
>>> matrix2.add_column([8, 16, 32])
|
>>> matrix2.add_column([8, 16, 32])
|
||||||
>>> print(matrix2)
|
>>> print(matrix2)
|
||||||
[[3. 6. 9. 8.]
|
[[3. 6. 9. 8.]
|
||||||
[12. 15. 18. 16.]
|
[12. 15. 18. 16.]
|
||||||
[21. 24. 27. 32.]]
|
[21. 24. 27. 32.]]
|
||||||
>>> print(matrix * matrix2)
|
>>> print(matrix * matrix2)
|
||||||
[[90. 108. 126. 136.]
|
[[90. 108. 126. 136.]
|
||||||
[198. 243. 288. 304.]
|
[198. 243. 288. 304.]
|
||||||
[306. 378. 450. 472.]
|
[306. 378. 450. 472.]
|
||||||
[414. 513. 612. 640.]]
|
[414. 513. 612. 640.]]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, rows: list[list[int]]):
|
def __init__(self, rows: list[list[int]]):
|
||||||
error = TypeError(
|
error = TypeError(
|
||||||
"Matrices must be formed from a list of zero or more lists containing at "
|
"Matrices must be formed from a list of zero or more lists containing at "
|
||||||
"least one and the same number of values, each of which must be of type "
|
"least one and the same number of values, each of which must be of type "
|
||||||
"int or float."
|
"int or float."
|
||||||
)
|
)
|
||||||
if len(rows) != 0:
|
if len(rows) != 0:
|
||||||
cols = len(rows[0])
|
cols = len(rows[0])
|
||||||
if cols == 0:
|
if cols == 0:
|
||||||
raise error
|
raise error
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if len(row) != cols:
|
if len(row) != cols:
|
||||||
raise error
|
raise error
|
||||||
for value in row:
|
for value in row:
|
||||||
if not isinstance(value, (int, float)):
|
if not isinstance(value, (int, float)):
|
||||||
raise error
|
raise error
|
||||||
self.rows = rows
|
self.rows = rows
|
||||||
else:
|
else:
|
||||||
self.rows = []
|
self.rows = []
|
||||||
|
|
||||||
# MATRIX INFORMATION
|
# MATRIX INFORMATION
|
||||||
def columns(self) -> list[list[int]]:
|
def columns(self) -> list[list[int]]:
|
||||||
return [[row[i] for row in self.rows] for i in range(len(self.rows[0]))]
|
return [[row[i] for row in self.rows] for i in range(len(self.rows[0]))]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_rows(self) -> int:
|
def num_rows(self) -> int:
|
||||||
return len(self.rows)
|
return len(self.rows)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_columns(self) -> int:
|
def num_columns(self) -> int:
|
||||||
return len(self.rows[0])
|
return len(self.rows[0])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def order(self) -> tuple[int, int]:
|
def order(self) -> tuple[int, int]:
|
||||||
return (self.num_rows, self.num_columns)
|
return (self.num_rows, self.num_columns)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_square(self) -> bool:
|
def is_square(self) -> bool:
|
||||||
return self.order[0] == self.order[1]
|
return self.order[0] == self.order[1]
|
||||||
|
|
||||||
def identity(self) -> Matrix:
|
def identity(self) -> Matrix:
|
||||||
values = [
|
values = [
|
||||||
[0 if column_num != row_num else 1 for column_num in range(self.num_rows)]
|
[0 if column_num != row_num else 1 for column_num in range(self.num_rows)]
|
||||||
for row_num in range(self.num_rows)
|
for row_num in range(self.num_rows)
|
||||||
]
|
]
|
||||||
return Matrix(values)
|
return Matrix(values)
|
||||||
|
|
||||||
def determinant(self) -> int:
|
def determinant(self) -> int:
|
||||||
if not self.is_square:
|
if not self.is_square:
|
||||||
return 0
|
return 0
|
||||||
if self.order == (0, 0):
|
if self.order == (0, 0):
|
||||||
return 1
|
return 1
|
||||||
if self.order == (1, 1):
|
if self.order == (1, 1):
|
||||||
return int(self.rows[0][0])
|
return int(self.rows[0][0])
|
||||||
if self.order == (2, 2):
|
if self.order == (2, 2):
|
||||||
return int(
|
return int(
|
||||||
(self.rows[0][0] * self.rows[1][1])
|
(self.rows[0][0] * self.rows[1][1])
|
||||||
- (self.rows[0][1] * self.rows[1][0])
|
- (self.rows[0][1] * self.rows[1][0])
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return sum(
|
return sum(
|
||||||
self.rows[0][column] * self.cofactors().rows[0][column]
|
self.rows[0][column] * self.cofactors().rows[0][column]
|
||||||
for column in range(self.num_columns)
|
for column in range(self.num_columns)
|
||||||
)
|
)
|
||||||
|
|
||||||
def is_invertable(self) -> bool:
|
def is_invertable(self) -> bool:
|
||||||
return bool(self.determinant())
|
return bool(self.determinant())
|
||||||
|
|
||||||
def get_minor(self, row: int, column: int) -> int:
|
def get_minor(self, row: int, column: int) -> int:
|
||||||
values = [
|
values = [
|
||||||
[
|
[
|
||||||
self.rows[other_row][other_column]
|
self.rows[other_row][other_column]
|
||||||
for other_column in range(self.num_columns)
|
for other_column in range(self.num_columns)
|
||||||
if other_column != column
|
if other_column != column
|
||||||
]
|
]
|
||||||
for other_row in range(self.num_rows)
|
for other_row in range(self.num_rows)
|
||||||
if other_row != row
|
if other_row != row
|
||||||
]
|
]
|
||||||
return Matrix(values).determinant()
|
return Matrix(values).determinant()
|
||||||
|
|
||||||
def get_cofactor(self, row: int, column: int) -> int:
|
def get_cofactor(self, row: int, column: int) -> int:
|
||||||
if (row + column) % 2 == 0:
|
if (row + column) % 2 == 0:
|
||||||
return self.get_minor(row, column)
|
return self.get_minor(row, column)
|
||||||
return -1 * self.get_minor(row, column)
|
return -1 * self.get_minor(row, column)
|
||||||
|
|
||||||
def minors(self) -> Matrix:
|
def minors(self) -> Matrix:
|
||||||
return Matrix(
|
return Matrix(
|
||||||
[
|
[
|
||||||
[self.get_minor(row, column) for column in range(self.num_columns)]
|
[self.get_minor(row, column) for column in range(self.num_columns)]
|
||||||
for row in range(self.num_rows)
|
for row in range(self.num_rows)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
def cofactors(self) -> Matrix:
|
def cofactors(self) -> Matrix:
|
||||||
return Matrix(
|
return Matrix(
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
self.minors().rows[row][column]
|
self.minors().rows[row][column]
|
||||||
if (row + column) % 2 == 0
|
if (row + column) % 2 == 0
|
||||||
else self.minors().rows[row][column] * -1
|
else self.minors().rows[row][column] * -1
|
||||||
for column in range(self.minors().num_columns)
|
for column in range(self.minors().num_columns)
|
||||||
]
|
]
|
||||||
for row in range(self.minors().num_rows)
|
for row in range(self.minors().num_rows)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
def adjugate(self) -> Matrix:
|
def adjugate(self) -> Matrix:
|
||||||
values = [
|
values = [
|
||||||
[self.cofactors().rows[column][row] for column in range(self.num_columns)]
|
[self.cofactors().rows[column][row] for column in range(self.num_columns)]
|
||||||
for row in range(self.num_rows)
|
for row in range(self.num_rows)
|
||||||
]
|
]
|
||||||
return Matrix(values)
|
return Matrix(values)
|
||||||
|
|
||||||
def inverse(self) -> Matrix:
|
def inverse(self) -> Matrix:
|
||||||
determinant = self.determinant()
|
determinant = self.determinant()
|
||||||
if not determinant:
|
if not determinant:
|
||||||
raise TypeError("Only matrices with a non-zero determinant have an inverse")
|
raise TypeError("Only matrices with a non-zero determinant have an inverse")
|
||||||
return self.adjugate() * (1 / determinant)
|
return self.adjugate() * (1 / determinant)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return str(self.rows)
|
return str(self.rows)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
if self.num_rows == 0:
|
if self.num_rows == 0:
|
||||||
return "[]"
|
return "[]"
|
||||||
if self.num_rows == 1:
|
if self.num_rows == 1:
|
||||||
return "[[" + ". ".join(str(self.rows[0])) + "]]"
|
return "[[" + ". ".join(str(self.rows[0])) + "]]"
|
||||||
return (
|
return (
|
||||||
"["
|
"["
|
||||||
+ "\n ".join(
|
+ "\n ".join(
|
||||||
[
|
[
|
||||||
"[" + ". ".join([str(value) for value in row]) + ".]"
|
"[" + ". ".join([str(value) for value in row]) + ".]"
|
||||||
for row in self.rows
|
for row in self.rows
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
+ "]"
|
+ "]"
|
||||||
)
|
)
|
||||||
|
|
||||||
# MATRIX MANIPULATION
|
# MATRIX MANIPULATION
|
||||||
def add_row(self, row: list[int], position: int | None = None) -> None:
|
def add_row(self, row: list[int], position: int | None = None) -> None:
|
||||||
type_error = TypeError("Row must be a list containing all ints and/or floats")
|
type_error = TypeError("Row must be a list containing all ints and/or floats")
|
||||||
if not isinstance(row, list):
|
if not isinstance(row, list):
|
||||||
raise type_error
|
raise type_error
|
||||||
for value in row:
|
for value in row:
|
||||||
if not isinstance(value, (int, float)):
|
if not isinstance(value, (int, float)):
|
||||||
raise type_error
|
raise type_error
|
||||||
if len(row) != self.num_columns:
|
if len(row) != self.num_columns:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Row must be equal in length to the other rows in the matrix"
|
"Row must be equal in length to the other rows in the matrix"
|
||||||
)
|
)
|
||||||
if position is None:
|
if position is None:
|
||||||
self.rows.append(row)
|
self.rows.append(row)
|
||||||
else:
|
else:
|
||||||
self.rows = self.rows[0:position] + [row] + self.rows[position:]
|
self.rows = self.rows[0:position] + [row] + self.rows[position:]
|
||||||
|
|
||||||
def add_column(self, column: list[int], position: int | None = None) -> None:
|
def add_column(self, column: list[int], position: int | None = None) -> None:
|
||||||
type_error = TypeError(
|
type_error = TypeError(
|
||||||
"Column must be a list containing all ints and/or floats"
|
"Column must be a list containing all ints and/or floats"
|
||||||
)
|
)
|
||||||
if not isinstance(column, list):
|
if not isinstance(column, list):
|
||||||
raise type_error
|
raise type_error
|
||||||
for value in column:
|
for value in column:
|
||||||
if not isinstance(value, (int, float)):
|
if not isinstance(value, (int, float)):
|
||||||
raise type_error
|
raise type_error
|
||||||
if len(column) != self.num_rows:
|
if len(column) != self.num_rows:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Column must be equal in length to the other columns in the matrix"
|
"Column must be equal in length to the other columns in the matrix"
|
||||||
)
|
)
|
||||||
if position is None:
|
if position is None:
|
||||||
self.rows = [self.rows[i] + [column[i]] for i in range(self.num_rows)]
|
self.rows = [self.rows[i] + [column[i]] for i in range(self.num_rows)]
|
||||||
else:
|
else:
|
||||||
self.rows = [
|
self.rows = [
|
||||||
self.rows[i][0:position] + [column[i]] + self.rows[i][position:]
|
self.rows[i][0:position] + [column[i]] + self.rows[i][position:]
|
||||||
for i in range(self.num_rows)
|
for i in range(self.num_rows)
|
||||||
]
|
]
|
||||||
|
|
||||||
# MATRIX OPERATIONS
|
# MATRIX OPERATIONS
|
||||||
def __eq__(self, other: object) -> bool:
|
def __eq__(self, other: object) -> bool:
|
||||||
if not isinstance(other, Matrix):
|
if not isinstance(other, Matrix):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
return self.rows == other.rows
|
return self.rows == other.rows
|
||||||
|
|
||||||
def __ne__(self, other: object) -> bool:
|
def __ne__(self, other: object) -> bool:
|
||||||
return not self == other
|
return not self == other
|
||||||
|
|
||||||
def __neg__(self) -> Matrix:
|
def __neg__(self) -> Matrix:
|
||||||
return self * -1
|
return self * -1
|
||||||
|
|
||||||
def __add__(self, other: Matrix) -> Matrix:
|
def __add__(self, other: Matrix) -> Matrix:
|
||||||
if self.order != other.order:
|
if self.order != other.order:
|
||||||
raise ValueError("Addition requires matrices of the same order")
|
raise ValueError("Addition requires matrices of the same order")
|
||||||
return Matrix(
|
return Matrix(
|
||||||
[
|
[
|
||||||
[self.rows[i][j] + other.rows[i][j] for j in range(self.num_columns)]
|
[self.rows[i][j] + other.rows[i][j] for j in range(self.num_columns)]
|
||||||
for i in range(self.num_rows)
|
for i in range(self.num_rows)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
def __sub__(self, other: Matrix) -> Matrix:
|
def __sub__(self, other: Matrix) -> Matrix:
|
||||||
if self.order != other.order:
|
if self.order != other.order:
|
||||||
raise ValueError("Subtraction requires matrices of the same order")
|
raise ValueError("Subtraction requires matrices of the same order")
|
||||||
return Matrix(
|
return Matrix(
|
||||||
[
|
[
|
||||||
[self.rows[i][j] - other.rows[i][j] for j in range(self.num_columns)]
|
[self.rows[i][j] - other.rows[i][j] for j in range(self.num_columns)]
|
||||||
for i in range(self.num_rows)
|
for i in range(self.num_rows)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
def __mul__(self, other: Matrix | int | float) -> Matrix:
|
def __mul__(self, other: Matrix | int | float) -> Matrix:
|
||||||
if isinstance(other, (int, float)):
|
if isinstance(other, (int, float)):
|
||||||
return Matrix(
|
return Matrix(
|
||||||
[[int(element * other) for element in row] for row in self.rows]
|
[[int(element * other) for element in row] for row in self.rows]
|
||||||
)
|
)
|
||||||
elif isinstance(other, Matrix):
|
elif isinstance(other, Matrix):
|
||||||
if self.num_columns != other.num_rows:
|
if self.num_columns != other.num_rows:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"The number of columns in the first matrix must "
|
"The number of columns in the first matrix must "
|
||||||
"be equal to the number of rows in the second"
|
"be equal to the number of rows in the second"
|
||||||
)
|
)
|
||||||
return Matrix(
|
return Matrix(
|
||||||
[
|
[
|
||||||
[Matrix.dot_product(row, column) for column in other.columns()]
|
[Matrix.dot_product(row, column) for column in other.columns()]
|
||||||
for row in self.rows
|
for row in self.rows
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"A Matrix can only be multiplied by an int, float, or another matrix"
|
"A Matrix can only be multiplied by an int, float, or another matrix"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __pow__(self, other: int) -> Matrix:
|
def __pow__(self, other: int) -> Matrix:
|
||||||
if not isinstance(other, int):
|
if not isinstance(other, int):
|
||||||
raise TypeError("A Matrix can only be raised to the power of an int")
|
raise TypeError("A Matrix can only be raised to the power of an int")
|
||||||
if not self.is_square:
|
if not self.is_square:
|
||||||
raise ValueError("Only square matrices can be raised to a power")
|
raise ValueError("Only square matrices can be raised to a power")
|
||||||
if other == 0:
|
if other == 0:
|
||||||
return self.identity()
|
return self.identity()
|
||||||
if other < 0:
|
if other < 0:
|
||||||
if self.is_invertable:
|
if self.is_invertable():
|
||||||
return self.inverse() ** (-other)
|
return self.inverse() ** (-other)
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Only invertable matrices can be raised to a negative power"
|
"Only invertable matrices can be raised to a negative power"
|
||||||
)
|
)
|
||||||
result = self
|
result = self
|
||||||
for _ in range(other - 1):
|
for _ in range(other - 1):
|
||||||
result *= self
|
result *= self
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def dot_product(cls, row: list[int], column: list[int]) -> int:
|
def dot_product(cls, row: list[int], column: list[int]) -> int:
|
||||||
return sum(row[i] * column[i] for i in range(len(row)))
|
return sum(row[i] * column[i] for i in range(len(row)))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user