205 lines
5.6 KiB
Python
205 lines
5.6 KiB
Python
|
||
import math
|
||
|
||
from tabulate import tabulate
|
||
|
||
|
||
def matmul(a: list[list[float]], b: list[list[float]]) -> list[list[float]]:
|
||
"""Multiplicates two matrices.
|
||
|
||
Parameters
|
||
----------
|
||
a : list[list[float]]
|
||
Left matrix in row‑major order.
|
||
b : list[list[float]]
|
||
Right matrix in row‑major order.
|
||
|
||
Returns
|
||
-------
|
||
list[list[float]]
|
||
Product matrix `c = a × b`.
|
||
|
||
Raises
|
||
------
|
||
ValueError
|
||
If matrices are not rectangular or if the number of columns in ``a``
|
||
does not equal the number of rows in ``b``.
|
||
|
||
Notes
|
||
-----
|
||
* Empty matrices (``[]``) yield an empty result.
|
||
* The implementation uses pure Python lists and does not depend on
|
||
external libraries such as NumPy.
|
||
"""
|
||
# Validate input matrices are non‑empty lists of lists
|
||
if not isinstance(a, list) or not isinstance(b, list):
|
||
raise ValueError("Both arguments must be lists of lists.")
|
||
|
||
# Handle empty matrices early – return empty list for any empty input
|
||
if not a or not b:
|
||
return []
|
||
|
||
# Determine dimensions of left matrix ``a``
|
||
a_rows = len(a)
|
||
a_cols = None
|
||
for row in a:
|
||
if not isinstance(row, list):
|
||
raise ValueError("Matrix a must be a list of lists.")
|
||
if a_cols is None:
|
||
a_cols = len(row)
|
||
elif len(row) != a_cols:
|
||
raise ValueError("All rows in matrix a must have the same length.")
|
||
|
||
# Determine dimensions of right matrix ``b``
|
||
b_rows = len(b)
|
||
b_cols = None
|
||
for row in b:
|
||
if not isinstance(row, list):
|
||
raise ValueError("Matrix b must be a list of lists.")
|
||
if b_cols is None:
|
||
b_cols = len(row)
|
||
elif len(row) != b_cols:
|
||
raise ValueError("All rows in matrix b must have the same length.")
|
||
|
||
# Check for dimensional compatibility between ``a`` and ``b``
|
||
if a_cols != b_rows:
|
||
raise ValueError(
|
||
f"Matrix dimensions do not align: a.columns={a_cols} != b.rows={b_rows}"
|
||
)
|
||
|
||
# Initialize result matrix with zeros – dimensions a_rows × b_cols
|
||
result = [[0.0 for _ in range(b_cols)] for _ in range(a_rows)]
|
||
|
||
# Perform multiplication: iterate over rows of ``a`` and columns of ``b``
|
||
for i in range(a_rows):
|
||
for j in range(b_cols):
|
||
s = 0.0
|
||
for k in range(a_cols):
|
||
s += a[i][k] * b[k][j]
|
||
result[i][j] = s
|
||
|
||
return result
|
||
|
||
|
||
def transpose(a: list[list[float]]) -> list[list[float]]:
|
||
"""Transposes a matrix.
|
||
|
||
Parameters
|
||
----------
|
||
a : list[list[float]]
|
||
Matrix in row‑major order.
|
||
|
||
Returns
|
||
-------
|
||
list[list[float]]
|
||
Transposed matrix where rows and columns are swapped.
|
||
|
||
Raises
|
||
------
|
||
ValueError
|
||
If the matrix is not rectangular.
|
||
|
||
Notes
|
||
-----
|
||
* Empty matrices (``[]``) yield an empty result.
|
||
* The implementation uses pure Python lists and does not depend on
|
||
external libraries such as NumPy.
|
||
"""
|
||
# Validate input is a list
|
||
if not isinstance(a, list):
|
||
raise ValueError("Argument must be a list of lists.")
|
||
|
||
# Handle empty matrix early – return empty list
|
||
if not a:
|
||
return []
|
||
|
||
# Determine dimensions and check rectangularity
|
||
rows = len(a)
|
||
cols = None
|
||
for row in a:
|
||
if not isinstance(row, list):
|
||
raise ValueError("Matrix must be a list of lists.")
|
||
if cols is None:
|
||
cols = len(row)
|
||
elif len(row) != cols:
|
||
raise ValueError("All rows in the matrix must have the same length.")
|
||
|
||
# Build transposed matrix with dimensions cols × rows
|
||
result = [[a[i][j] for i in range(rows)] for j in range(cols)]
|
||
|
||
return result
|
||
|
||
|
||
def rot_2D(angle: float) -> list[list[float]]:
|
||
"""Creates a 2×2 rotation matrix.
|
||
|
||
Parameters
|
||
----------
|
||
angle : float
|
||
Rotation angle in radians (counter‑clockwise).
|
||
|
||
Returns
|
||
-------
|
||
list[list[float]]
|
||
Matrix ``[[cos(angle), -sin(angle)], [sin(angle), cos(angle)]]``.
|
||
|
||
Raises
|
||
------
|
||
ValueError
|
||
If ``angle`` is not a real number.
|
||
|
||
Notes
|
||
-----
|
||
* The implementation uses pure Python lists and does not depend on
|
||
external libraries such as NumPy.
|
||
"""
|
||
# Validate input is a real number
|
||
if not isinstance(angle, (int, float)) or isinstance(angle, bool):
|
||
raise ValueError("Angle must be a real number (radians).")
|
||
|
||
c = math.cos(angle)
|
||
s = math.sin(angle)
|
||
|
||
return [[c, -s], [s, c]]
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# Beispiel 1: 2x3 × 3x2
|
||
a = [[1, 2, 3], [4, 5, 6]]
|
||
b = [[7, 8], [9, 10], [11, 12]]
|
||
print("Beispiel 1 Ergebnis:")
|
||
for row in matmul(a, b):
|
||
print(row)
|
||
|
||
# Beispiel 2: 2x2 × 2x2
|
||
a2 = [[1, 0], [0, 1]]
|
||
b2 = [[5, 6], [7, 8]]
|
||
print("\nBeispiel 2 Ergebnis:")
|
||
for row in matmul(a2, b2):
|
||
print(row)
|
||
|
||
# Beispiel 3: Transponieren einer 2x3-Matrix -> 3x2
|
||
m = [[1, 2, 3], [4, 5, 6]]
|
||
print("\nBeispiel 3 Original:")
|
||
for row in m:
|
||
print(row)
|
||
print("Beispiel 3 Transponiert:")
|
||
for row in transpose(m):
|
||
print(row)
|
||
|
||
# Beispiel 4: Rotationsmatrix (90°) und Probe durch Drehen von (1, 0)
|
||
r = rot_2D(math.pi / 2)
|
||
print("\nBeispiel 4 Rotationsmatrix (90°):")
|
||
for row in r:
|
||
print(row)
|
||
print("Beispiel 4 Vektor (1, 0) nach 90°:")
|
||
for row in matmul(r, [[1.0], [0.0]]):
|
||
print([round(v, 10) for v in row])
|
||
|
||
# Matrix in Tabelle ausgeben
|
||
print(tabulate(rot_2D(1.0)))
|
||
|
||
# Docstring und Type Hints sind vorhanden und stimmen mit dem Code überein.
|
||
# Fehlerfälle werden behandelt
|
||
# Namen sind Aussagekräftig
|