Files
matrixmania/compute.py
T
2026-10-20 16:26:10 +02:00

150 lines
4.1 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.
"""Modul zur Matrizenmultiplikation."""
from __future__ import annotations
import math
from tabulate import tabulate
#test
Matrix = list[list[float]]
def matmul(a: Matrix, b: Matrix) -> Matrix:
"""Multipliziert zwei Matrizen a * b.
Args:
a: Erste Matrix der Dimension (m x n).
b: Zweite Matrix der Dimension (n x p).
Returns:
Ergebnismatrix der Dimension (m x p).
Raises:
ValueError: Wenn die Matrizen leer sind, unregulär sind
(ungleiche Zeilenlängen) oder die Innen Dimensionen
nicht zusammenpassen (a.Zeilen != b.Spalten).
"""
if not a or not b:
raise ValueError("Matrizen duerfen nicht leer sein.")
rows_a = len(a)
cols_a = len(a[0])
rows_b = len(b)
cols_b = len(b[0])
for row in a:
if len(row) != cols_a:
raise ValueError("Matrix a ist nicht rechteckig.")
for row in b:
if len(row) != cols_b:
raise ValueError("Matrix b ist nicht rechteckig.")
if cols_a != rows_b:
raise ValueError(
f"Nicht passende Dimensionen: a ist {rows_a}x{cols_a}, "
f"b ist {rows_b}x{cols_b} (a.Spalten muss b.Zeilen sein)."
)
result: Matrix = []
for i in range(rows_a):
new_row: list[float] = []
for j in range(cols_b):
new_row.append(sum(a[i][k] * b[k][j] for k in range(cols_a)))
result.append(new_row)
return result
def transpose(m: Matrix) -> Matrix:
"""Transponiert die gegebene Matrix.
Args:
m: Matrix von Dimension (rows x cols).
Returns:
Eine neue Matrix mit umgekehrter Dimension (cols x rows).
"""
if not m:
raise ValueError("Matrix darf nicht leer sein.")
rows = len(m)
cols = len(m[0])
# überprüfen, ob die Matrix rechteckig ist
for row in m:
if len(row) != cols:
raise ValueError("Matrix ist nicht rechteckig.")
# Transponieren
return [[m[r][c] for r in range(rows)] for c in range(cols)]
def rot_2D(m: Matrix | float) -> Matrix:
"""Rotiert die Matrix um 90 Grad im Uhrzeigersinn.
Falls ``m`` ein Zahlenwert ist, wird die Rotationsmatrix
für den Winkel ``m`` (in Bogenmaß) zurückgegeben. Andernfalls
wird die Matrix um 90° gedreht.
Args:
m: Eingabe‑Matrix oder Winkel in Radiant.
Returns:
Rotierte Matrix bzw. 2×2‑Rotationsmatrix.
"""
if isinstance(m, (int, float)):
theta = float(m)
c = math.cos(theta)
s = math.sin(theta)
return [[c, -s], [s, c]]
# Ansonsten normal 90°‑Rotation (wie bisher)
if not m:
raise ValueError("Matrix darf nicht leer sein.")
rows = len(m)
cols = len(m[0])
for row in m:
if len(row) != cols:
raise ValueError("Matrix ist nicht rechteckig.")
return [[m[row][col] for row in reversed(range(rows))] for col in range(cols)]
if __name__ == "__main__":
# Beispiel 1: klassischer Fall 2x3 * 3x2 -> 2x2
print(tabulate(rot_2D(1.0)))
a1 = [[1, 2, 3],
[4, 5, 6]]
b1 = [[7, 8],
[9, 10],
[11, 12]]
expected1 = [[58, 64],
[139, 154]]
got1 = matmul(a1, b1)
assert got1 == expected1, f"Beispiel 1 fehlgeschlagen: {got1}"
print("Beispiel 1 ok:", got1)
# Beispiel 4: Transponieren einer 3x2 Matrix -> 2x3
m4 = [[1, 2],
[3, 4],
[5, 6]]
expected4 = [[1, 3, 5],
[2, 4, 6]]
got4 = transpose(m4)
assert got4 == expected4, f"Beispiel 4 fehlgeschlagen: {got4}"
print("Beispiel 4 ok:", got4)
# Beispiel 5: Transponieren einer Einheitsmatrix -> gleich
e5 = [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
got5 = transpose(e5)
assert got5 == e5, f"Beispiel 5 fehlgeschlagen: {got5}"
print("Beispiel 5 ok:", got5)
# Beispiel 6: Fehlerfall – transponieren leerer Matrix
try:
transpose([])
except ValueError as err:
print("Beispiel 6 ok (Fehler erwartet):", err)
m7 = [[1, 2, 3],
[4, 5, 6]]
expected7 = [[4, 1],
[5, 2],
[6, 3]]