"""Hilfsfunktionen für grundlegende Matrixoperationen.""" from __future__ import annotations from typing import List, Sequence, TypeVar Number = TypeVar("Number", int, float) def matmul(a: Sequence[Sequence[Number]], b: Sequence[Sequence[Number]]) -> List[List[Number]]: """ Multipliziert zwei Matrizen miteinander. :param a: Die linke Matrix der Dimension (m, n). :type a: Sequence[Sequence[Number]] :param b: Die rechte Matrix der Dimension (n, p). :type b: Sequence[Sequence[Number]] :return: Die entstehende Ergebnismatrix der Dimension (m, p). :rtype: List[List[Number]] :raises ValueError: Wenn die Matrizen aufgrund inkompatibler Dimensionen oder unregelmäßiger Form nicht multipliziert werden können. """ if not a or not b: raise ValueError("Matrix-Eingaben dürfen nicht leer sein") m = len(a) n = len(a[0]) for row in a: if len(row) != n: raise ValueError("Matrix a ist nicht rechteckig") if len(b) != n: raise ValueError("Die Anzahl der Spalten in a muss der Anzahl der Zeilen in b entsprechen") p = len(b[0]) for row in b: if len(row) != p: raise ValueError("Matrix b ist nicht rechteckig") result: List[List[Number]] = [[0 for _ in range(p)] for _ in range(m)] for i in range(m): for j in range(p): total: Number = 0 for k in range(n): total += a[i][k] * b[k][j] result[i][j] = total return result def transpose(matrix: Sequence[Sequence[Number]]) -> List[List[Number]]: """ Transponiert eine Matrix. :param matrix: Die Eingabematrix der Dimension (m, n). :type matrix: Sequence[Sequence[Number]] :return: Die transponierte Matrix der Dimension (n, m). :rtype: List[List[Number]] :raises ValueError: Wenn die Matrix leer ist oder Zeilen unterschiedlicher Länge hat. """ if not matrix or not matrix[0]: raise ValueError("Matrix darf nicht leer sein") row_len = len(matrix[0]) for row in matrix: if len(row) != row_len: raise ValueError("Die Zeilen der Matrix haben unterschiedliche Längen") n_rows = len(matrix) n_cols = row_len transposed: List[List[Number]] = [[0] * n_rows for _ in range(n_cols)] for i in range(n_rows): for j in range(n_cols): transposed[j][i] = matrix[i][j] return transposed import math def rot_2D(theta: Number) -> List[List[Number]]: """ Erstellt die 2D-Rotationsmatrix für einen gegebenen Winkel. :param theta: Der Winkel in Bogenmaß (Radiant). :type theta: Number :return: Die Rotationsmatrix ``[[cos(theta), -sin(theta)], [sin(theta), cos(theta)]]``. :rtype: List[List[Number]] :raises TypeError: Wenn theta kein numerischer Typ ist. """ if not isinstance(theta, (int, float)): raise TypeError("theta muss numerisch sein (int oder float)") cos_t = math.cos(theta) sin_t = math.sin(theta) return [[cos_t, -sin_t], [sin_t, cos_t]]