From a0031cac5842b68380fa7dd9b31afb610375bc86 Mon Sep 17 00:00:00 2001 From: Leon Zielinski Date: Tue, 13 Oct 2026 16:40:44 +0200 Subject: [PATCH] Erster Stand: compute.py --- .gitignore | 3 + AGENTS.md | 4 + compute.py | 198 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 3 + 4 files changed, 208 insertions(+) create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 compute.py create mode 100644 pyproject.toml 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..8414cb0 --- /dev/null +++ b/compute.py @@ -0,0 +1,198 @@ +import math + + +def matmul(a: list[list[float]], b: list[list[float]]) -> list[list[float]]: + """Multiplicates two matrices. + + Parameters + ---------- + a : list[list[float]] + Left matrix in row‑major order. + b : list[list[float]] + Right matrix in row‑major order. + + Returns + ------- + list[list[float]] + Product matrix `c = a × b`. + + Raises + ------ + ValueError + If matrices are not rectangular or if the number of columns in ``a`` + does not equal the number of rows in ``b``. + + Notes + ----- + * Empty matrices (``[]``) yield an empty result. + * The implementation uses pure Python lists and does not depend on + external libraries such as NumPy. + """ + # Validate input matrices are non‑empty lists of lists + if not isinstance(a, list) or not isinstance(b, list): + raise ValueError("Both arguments must be lists of lists.") + + # Handle empty matrices early – return empty list for any empty input + if not a or not b: + return [] + + # Determine dimensions of left matrix ``a`` + a_rows = len(a) + a_cols = None + for row in a: + if not isinstance(row, list): + raise ValueError("Matrix a must be a list of lists.") + if a_cols is None: + a_cols = len(row) + elif len(row) != a_cols: + raise ValueError("All rows in matrix a must have the same length.") + + # Determine dimensions of right matrix ``b`` + b_rows = len(b) + b_cols = None + for row in b: + if not isinstance(row, list): + raise ValueError("Matrix b must be a list of lists.") + if b_cols is None: + b_cols = len(row) + elif len(row) != b_cols: + raise ValueError("All rows in matrix b must have the same length.") + + # Check for dimensional compatibility between ``a`` and ``b`` + if a_cols != b_rows: + raise ValueError( + f"Matrix dimensions do not align: a.columns={a_cols} != b.rows={b_rows}" + ) + + # Initialize result matrix with zeros – dimensions a_rows × b_cols + result = [[0.0 for _ in range(b_cols)] for _ in range(a_rows)] + + # Perform multiplication: iterate over rows of ``a`` and columns of ``b`` + for i in range(a_rows): + for j in range(b_cols): + s = 0.0 + for k in range(a_cols): + s += a[i][k] * b[k][j] + result[i][j] = s + + return result + + +def transpose(a: list[list[float]]) -> list[list[float]]: + """Transposes a matrix. + + Parameters + ---------- + a : list[list[float]] + Matrix in row‑major order. + + Returns + ------- + list[list[float]] + Transposed matrix where rows and columns are swapped. + + Raises + ------ + ValueError + If the matrix is not rectangular. + + Notes + ----- + * Empty matrices (``[]``) yield an empty result. + * The implementation uses pure Python lists and does not depend on + external libraries such as NumPy. + """ + # Validate input is a list + if not isinstance(a, list): + raise ValueError("Argument must be a list of lists.") + + # Handle empty matrix early – return empty list + if not a: + return [] + + # Determine dimensions and check rectangularity + rows = len(a) + cols = None + for row in a: + if not isinstance(row, list): + raise ValueError("Matrix must be a list of lists.") + if cols is None: + cols = len(row) + elif len(row) != cols: + raise ValueError("All rows in the matrix must have the same length.") + + # Build transposed matrix with dimensions cols × rows + result = [[a[i][j] for i in range(rows)] for j in range(cols)] + + return result + + +def rot_2D(angle: float) -> list[list[float]]: + """Creates a 2×2 rotation matrix. + + Parameters + ---------- + angle : float + Rotation angle in radians (counter‑clockwise). + + Returns + ------- + list[list[float]] + Matrix ``[[cos(angle), -sin(angle)], [sin(angle), cos(angle)]]``. + + Raises + ------ + ValueError + If ``angle`` is not a real number. + + Notes + ----- + * The implementation uses pure Python lists and does not depend on + external libraries such as NumPy. + """ + # Validate input is a real number + if not isinstance(angle, (int, float)) or isinstance(angle, bool): + raise ValueError("Angle must be a real number (radians).") + + c = math.cos(angle) + s = math.sin(angle) + + return [[c, -s], [s, c]] + + +if __name__ == "__main__": + # Beispiel 1: 2x3 × 3x2 + a = [[1, 2, 3], [4, 5, 6]] + b = [[7, 8], [9, 10], [11, 12]] + print("Beispiel 1 Ergebnis:") + for row in matmul(a, b): + print(row) + + # Beispiel 2: 2x2 × 2x2 + a2 = [[1, 0], [0, 1]] + b2 = [[5, 6], [7, 8]] + print("\nBeispiel 2 Ergebnis:") + for row in matmul(a2, b2): + print(row) + + # Beispiel 3: Transponieren einer 2x3-Matrix -> 3x2 + m = [[1, 2, 3], [4, 5, 6]] + print("\nBeispiel 3 Original:") + for row in m: + print(row) + print("Beispiel 3 Transponiert:") + for row in transpose(m): + print(row) + + # Beispiel 4: Rotationsmatrix (90°) und Probe durch Drehen von (1, 0) + r = rot_2D(math.pi / 2) + print("\nBeispiel 4 Rotationsmatrix (90°):") + for row in r: + print(row) + print("Beispiel 4 Vektor (1, 0) nach 90°:") + for row in matmul(r, [[1.0], [0.0]]): + print([round(v, 10) for v in row]) + +# Docstring und Type Hints sind vorhanden und stimmen mit dem Code überein. +# Fehlerfälle werden behandelt +# Namen sind Aussagekräftig 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