106 lines
3.0 KiB
Python
106 lines
3.0 KiB
Python
"""
|
||
Mathematical matrix multiplication, transposition, and rotation without external libraries.
|
||
|
||
The ``matmul`` function implements a straightforward algorithm that
|
||
multiplies two 2‑D matrices where each element is a ``float``.
|
||
|
||
The functions perform validity checks on the dimensions:
|
||
- Matrices must be non-empty lists of lists and rectangular.
|
||
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
import math
|
||
|
||
|
||
def matmul(a: list[list[float]], b: list[list[float]]) -> list[list[float]]:
|
||
"""Multiply two 2‑D matrices."""
|
||
if not a or not a[0]:
|
||
raise ValueError("Matrix 'a' must not be empty")
|
||
if not b or not b[0]:
|
||
raise ValueError("Matrix 'b' must not be empty")
|
||
|
||
a_rows = len(a)
|
||
a_cols = len(a[0])
|
||
for row in a:
|
||
if len(row) != a_cols:
|
||
raise ValueError("Matrix 'a' rows must all have the same length")
|
||
|
||
b_rows = len(b)
|
||
b_cols = len(b[0])
|
||
for row in b:
|
||
if len(row) != b_cols:
|
||
raise ValueError("Matrix 'b' rows must all have the same length")
|
||
|
||
if a_cols != b_rows:
|
||
raise ValueError(
|
||
f"Cannot multiply: number of columns in 'a' ({a_cols}) "
|
||
f"does not equal number of rows in 'b' ({b_rows})"
|
||
)
|
||
|
||
result: list[list[float]] = []
|
||
for i in range(a_rows):
|
||
result_row: list[float] = []
|
||
for j in range(b_cols):
|
||
element = 0.0
|
||
for k in range(a_cols):
|
||
element += a[i][k] * b[k][j]
|
||
result_row.append(element)
|
||
result.append(result_row)
|
||
|
||
return result
|
||
|
||
|
||
def transpose(a: list[list[float]]) -> list[list[float]]:
|
||
"""Transposes a 2‑D matrix."""
|
||
if not a or not a[0]:
|
||
raise ValueError("Matrix must not be empty")
|
||
|
||
a_rows = len(a)
|
||
a_cols = len(a[0])
|
||
for row in a:
|
||
if len(row) != a_cols:
|
||
raise ValueError("Matrix rows must all have the same length")
|
||
|
||
result: list[list[float]] = []
|
||
for j in range(a_cols):
|
||
result_row: list[float] = []
|
||
for i in range(a_rows):
|
||
result_row.append(a[i][j])
|
||
result.append(result_row)
|
||
|
||
return result
|
||
|
||
|
||
def rot_2D(theta: float) -> list[list[float]]:
|
||
"""Erzeugt eine 2D-Rotationsmatrix für den Winkel theta (im Bogenmaß)."""
|
||
cos_t = math.cos(theta)
|
||
sin_t = math.sin(theta)
|
||
return [
|
||
[cos_t, -sin_t],
|
||
[sin_t, cos_t]
|
||
]
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# Valid example: multiplication
|
||
matrix_a = [[1, 2, 3], [4, 5, 6]]
|
||
matrix_b = [[7, 8], [9, 10], [11, 12]]
|
||
print("Valid multiplication result:")
|
||
print(matmul(matrix_a, matrix_b))
|
||
|
||
# Valid example: transposition
|
||
print("\nTransposed matrix_a result:")
|
||
print(transpose(matrix_a))
|
||
|
||
# Valid example: rotation (2D)
|
||
print("\nRotated 2D matrix (theta = 0.5) result:")
|
||
print(rot_2D(0.5))
|
||
|
||
# Example that raises ValueError
|
||
try:
|
||
invalid_b = [[1, 2], [3, 4]]
|
||
print("\nThis should raise an error:")
|
||
print(matmul(matrix_a, invalid_b))
|
||
except ValueError as e:
|
||
print("Caught ValueError as expected:", e) |