commit 3c19ddec5e69f74af8f4e26ee57b910a10a83af1 Author: MaaaartinTH Date: Thu Oct 15 13:31:00 2026 +0200 Erster Stand: compute.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1eb6e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.venv/ +__pycache__/ +.env \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..79a2eba --- /dev/null +++ b/AGENTS.md @@ -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`. \ No newline at end of file diff --git a/compute.py b/compute.py new file mode 100644 index 0000000..6fc8a29 --- /dev/null +++ b/compute.py @@ -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) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..46e3b47 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[project] +name = "matrixmania" +version = "0.1.0" \ No newline at end of file