Files
matrixmania/compute.py
T
2026-10-15 13:31:00 +02:00

130 lines
3.7 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.
"""Computational utilities for matrix operations and 2D transformations.
Functions:
matmul(A, B)
Multiply two matrices represented as list of lists.
transpose(matrix)
Return the transpose of a matrix.
rot_2D(theta)
Return the 2D rotation matrix for a given angle theta.
"""
from __future__ import annotations
from typing import List
import math
Matrix = List[List[float]]
def transpose(matrix: Matrix) -> Matrix:
"""Return the transpose of *matrix*.
The matrix must be non‑empty and rectangular; this is validated
by the existing ``_check_matrix`` helper.
"""
_check_matrix(matrix)
rows, cols = len(matrix), len(matrix[0])
return [[matrix[i][j] for i in range(rows)] for j in range(cols)]
def rot_2D(theta: float) -> Matrix:
"""Return the 2D rotation matrix for a given angle theta (in radians).
Parameters
----------
theta : float
Rotation angle in radians.
Returns
-------
Matrix
A 2x2 rotation matrix [[cos(theta), -sin(theta)], [sin(theta), cos(theta)]].
"""
c = math.cos(theta)
s = math.sin(theta)
return [
[c, -s],
[s, c]
]
def _check_matrix(matrix: Matrix) -> None:
"""Ensure all rows in *matrix* are lists of floats and of equal length.
Raises:
ValueError: If *matrix* is empty, contains non‑list rows,
non‑float elements, or uneven row lengths.
"""
if not matrix:
raise ValueError("Matrix must not be empty")
row_len = None
for row_idx, row in enumerate(matrix):
if not isinstance(row, list):
raise ValueError(f"Row {row_idx} is not a list")
if row_len is None:
row_len = len(row)
if row_len == 0:
raise ValueError("Rows must contain at least one element")
elif len(row) != row_len:
raise ValueError(
f"Row {row_idx} length {len(row)} differs from expected {row_len}"
)
for col_idx, item in enumerate(row):
if not isinstance(item, (int, float)):
raise ValueError(
f"Element at ({row_idx},{col_idx}) is not a number"
)
def matmul(A: Matrix, B: Matrix) -> Matrix:
"""Return the matrix product of *A* and *B*.
The matrices must be compatible for multiplication, i.e. the
number of columns in *A* must equal the number of rows in *B*.
Parameters
----------
A, B : Matrix
Two‑dimensional lists of numeric values.
Returns
-------
Matrix
Resulting matrix of dimensions ``len(A) x len(B[0])``.
Raises
------
ValueError
If either input is malformed (non‑uniform rows, empty,
non‑numeric entries) or if the dimensions are incompatible.
"""
_check_matrix(A)
_check_matrix(B)
a_rows, a_cols = len(A), len(A[0])
b_rows, b_cols = len(B), len(B[0])
if a_cols != b_rows:
raise ValueError(
f"Cannot multiply: {a_rows}x{a_cols} matrix A with {b_rows}x{b_cols} matrix B"
)
result: Matrix = []
for i in range(a_rows):
row: List[float] = []
for j in range(b_cols):
s = 0.0
for k in range(a_cols):
s += A[i][k] * B[k][j]
row.append(s)
result.append(row)
return result
if __name__ == "__main__":
# Test für rot_2D (z. B. Rotation um 90 Grad = pi / 2)
theta = math.pi / 2
R = rot_2D(theta)
print("Rotationsmatrix für 90 Grad:", R)
# Einen Punkt (Vektor) als 2x1 Matrix rotieren: [ [x], [y] ]
point = [[1.0], [0.0]] # Punkt auf der x-Achse bei x=1, y=0
rotated_point = matmul(R, point)
print("Gedrehter Punkt (erwartet y=1, x=0):", rotated_point)