Erster Stand: compute.py
This commit is contained in:
commit
3c19ddec5e
4 files changed
+140
No files matched your search
@@ -0,0 +1,3 @@
|
||||
.venv/
|
||||
__pycache__/
|
||||
.env
|
||||
@@ -0,0 +1,4 @@
|
||||
# Regeln für dieses Projekt
|
||||
- Code nach PEP 8, Zeilenlänge maximal 88 Zeichen.
|
||||
- Jede Funktion und Methode hat einen Docstring und Type Hints.
|
||||
- Vor jedem Commit: `ruff check` und `ruff format`.
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
"""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)
|
||||
@@ -0,0 +1,3 @@
|
||||
[project]
|
||||
name = "matrixmania"
|
||||
version = "0.1.0"
|
||||
Reference in new issue
Block a user