Files
matrixmania/compute.py
T
2026-10-19 16:11:33 +02:00

148 lines
4.2 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.
"""Utility module for matrix multiplication.
This module provides a single function :func:`matmul` that multiplies two
matrices represented as nested Python lists (``List[List[Number]]``). The
function performs basic validation of dimensions and individual rows and
raises :class:`ValueError` if the input is not a proper matrix or if the
matrices cannot be multiplied.
The module contains a small ``main`` helper that demonstrates the usage
with a simple example when run as a script.
"""
from __future__ import annotations
import math
from tabulate import tabulate
Number = (int, float)
__all__ = ["matmul", "transpose"]
def matmul(a: list[list[float]] , b:list[list[float]]) -> list[list[float]]:
"""Return the product of two matrices ``a`` and ``b``.
Returns
-------
List[List[float]]
The matrix product ``a`` × ``b``.
Raises
------
ValueError
If either argument is not a well‑formed matrix (e.g. jagged rows) or
if the inner dimensions do not match.
"""
# Helper to validate that each row has the same length and contains
# only numbers.
def _validate(matrix: list[list[float]], name: str) -> int:
if not matrix:
raise ValueError(f"{name} is empty")
row_len = None
for r_index, row in enumerate(matrix, start=1):
if not isinstance(row, (list, tuple)):
raise ValueError(f"{name} row {r_index} is not a sequence")
if row_len is None:
row_len = len(row)
if row_len == 0:
raise ValueError(f"{name} row {r_index} is empty")
elif len(row) != row_len:
raise ValueError(
f"{name} row {r_index} length {len(row)} != expected {row_len}")
for c_index, val in enumerate(row, start=1):
if not isinstance(val, (int, float)):
raise ValueError(
f"{name} element ({r_index},{c_index}) is not a number")
return row_len
a_rows = len(a)
a_cols = _validate(a, "a")
b_rows = len(b)
b_cols = _validate(b, "b")
if a_cols != b_rows:
raise ValueError(
f"Cannot multiply: a has {a_cols} columns but b has {b_rows} rows")
# Compute the product.
result: List[List[float]] = []
for i in range(a_rows):
result_row: List[float] = []
for j in range(b_cols):
element = sum(a[i][k] * b[k][j] for k in range(a_cols))
result_row.append(float(element))
result.append(result_row)
return result
def transponse(a, b):
"""Gibt die transponierten Matrizen a und b zurück."""
a_transponse = []
b_transponse = []
for cols in range(len(a[0])):
new_row = []
for row in a:
new_row.append(row[cols])
a_transponse.append(new_row)
for cols in range(len(b[0])):
new_row = []
for row in b:
new_row.append(row[cols])
b_transponse.append(new_row)
return a_transponse, b_transponse
def rot_2D(winkel):
"""Gibt die Rotationsmatrix für einen Winkel in Radiant zurück."""
return [
[math.cos(winkel), -math.sin(winkel)],
[math.sin(winkel), math.cos(winkel)]
]
def transpose(a: list[list[float]]) -> list[list[float]]:
"""Gibt die transponierte Matrix a zurück."""
return [
[row[i] for row in a]
for i in range(len(a[0]))
]
def main() -> None:
"""Demonstrate :func:`matmul` with a simple example.
This function is only executed when the module is run as a script.
"""
a = [
[1, 2,3],
[4, 5,3],
]
b = [
[7, 8],
[9, 10],
[11, 12],
]
product = matmul(a, b)
print("Result of matmul(a, b):")
for row in product:
print(row)
a_transponse, b_transponse = transponse(a, b)
print("Transponierte Matrix a:")
for row in a_transponse:
print(row)
print("Transponierte Matrix b:")
for row in b_transponse:
print(row)
rotation = rot_2D(math.pi / 2)
print("Rotationsmatrix für 90 Grad:")
for row in rotation:
print(row)
print(tabulate(rot_2D(1.0)))
if __name__ == "__main__":
main()