Files
matrixmania/compute.py
T
2026-10-11 17:51:55 +02:00

164 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Matrix operations module.
This module provides utilities for basic matrix arithmetic:
* :func:`matmul` – standard matrix multiplication
* :func:`transpose` – matrix transposition
* :func:`rot_2D` – 2‑D rotation matrix generator
All functions validate inputs and raise ``ValueError`` where
appropriate. Type hints use the built‑in ``list`` and ``int | float`` union.
"""
from __future__ import annotations
import math
# Public type alias for a matrix of numeric values.
Matrix = list[list[int | float]]
# ---------------------------------------------------------------------------
# matmul
# ---------------------------------------------------------------------------
def matmul(a: Matrix, b: Matrix) -> Matrix:
"""Multiply two matrices.
Parameters
----------
a: Matrix
Left‑hand operand. Must be a non‑empty, rectangular matrix.
b: Matrix
Right‑hand operand. Must be a non‑empty, rectangular matrix
whose column count equals ``a``'s row count.
Returns
-------
Matrix
Result of the matrix product ``a @ b``.
Raises
------
ValueError
If either matrix is empty, not rectangular, or the inner
dimensions do not agree.
"""
if not a or not a[0] or not b or not b[0]:
raise ValueError("Both matrices must be non‑empty")
a_rows, a_cols = len(a), len(a[0])
b_rows, b_cols = len(b), len(b[0])
if any(len(row) != a_cols for row in a):
raise ValueError("Matrix 'a' is not rectangular")
if any(len(row) != b_cols for row in b):
raise ValueError("Matrix 'b' is not rectangular")
if a_cols != b_rows:
raise ValueError(
f"Inner matrix dimensions must agree: a_cols={a_cols} != b_rows={b_rows}"
)
result: Matrix = [[0 for _ in range(b_cols)] for _ in range(a_rows)]
for i in range(a_rows):
for j in range(b_cols):
s = 0
for k in range(a_cols):
s += a[i][k] * b[k][j]
result[i][j] = s
return result
# ---------------------------------------------------------------------------
# Transpose
# ---------------------------------------------------------------------------
def transpose(mat: Matrix) -> Matrix:
"""Return the transpose of a matrix.
Parameters
----------
mat: Matrix
Input matrix to transpose. Must be a non‑empty, rectangular matrix.
Returns
-------
Matrix
Transposed matrix: columns become rows and vice versa.
Raises
------
ValueError
If ``mat`` is empty or the rows have differing lengths.
"""
if not mat or not mat[0]:
raise ValueError("Matrix must be non‑empty")
row_len = len(mat[0])
if any(len(row) != row_len for row in mat):
raise ValueError("Matrix must be rectangular – rows have varying lengths")
transposed: Matrix = [[mat[row][col] for row in range(len(mat))] for col in range(row_len)]
return transposed
# ---------------------------------------------------------------------------
# Rotation matrix generator
# ---------------------------------------------------------------------------
def rot_2D(theta: float) -> Matrix:
"""Return a 2‑D rotation matrix for an angle ``theta``.
The matrix corresponds to a rotation about the origin by ``theta``
radians (counter‑clockwise). For a vector ``(x, y)`` the rotated
coordinates are obtained via ``matmul(rot_2D(theta), [x, y])``.
Parameters
----------
theta: float
Rotation angle in radians.
Returns
-------
Matrix
2×2 rotation matrix.
Raises
------
ValueError
Never raised – the function accepts any floating‑point value.
"""
c = math.cos(theta)
s = math.sin(theta)
return [[c, -s], [s, c]]
# ---------------------------------------------------------------------------
# Example usage / tests
# ---------------------------------------------------------------------------
if __name__ == "__main__":
# Example multiply
matrix_a = [
[3, 4, -1, 4],
[-2, 2, 5, 1]
]
matrix_b = [
[1, 3, -2],
[2, 5, 1],
[-1, 4, -4],
[2, 3, 6]
]
matrix_c = matmul(matrix_a, matrix_b)
print("Ergebnis C = A * B:")
for row in matrix_c:
print(row)
# Example transpose
matrix_d = [[1, 2, 3], [4, 5, 6]]
print("Transpose of", matrix_d, "=", transpose(matrix_d))
# Demonstrate rot_2D
angle = math.radians(45)
rot = rot_2D(angle)
vec = [[1], [0]]
print("Rotation matrix for 45°:", rot)
print("Rotated vec:", matmul(rot, vec))