Files

145 lines
4.5 KiB
Python
Raw Permalink 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.
"""Compute operations for matrices.
This module provides public functions for matrix multiplication, transposition,
matrix rotation, and generating 2D and 3D rotation matrices as well as projections.
"""
from __future__ import annotations
import math
from typing import List
def matmul(
matrix_a: List[List[float]], matrix_b: List[List[float]]
) -> List[List[float]]:
"""Multiply two 2D matrices.
Both matrices are expected to be non‑empty and to have consistent row
lengths. The number of columns in ``matrix_a`` must equal the number of
rows in ``matrix_b``.
Args:
matrix_a: A matrix of shape (m, n) represented as a list of m rows.
matrix_b: A matrix of shape (n, p) represented as a list of n rows.
Returns:
A new matrix of shape (m, p) containing the product ``matrix_a @ matrix_b``.
Raises:
ValueError: If either matrix is empty or dimensions do not match.
"""
if not matrix_a or not matrix_b:
raise ValueError("Input matrices must not be empty.")
n_cols_a = len(matrix_a[0])
if any(len(row) != n_cols_a for row in matrix_a):
raise ValueError("All rows of matrix_a must have the same number of columns.")
n_rows_b = len(matrix_b)
if n_cols_a != n_rows_b:
raise ValueError(
f"Matrix dimension mismatch: matrix_a columns {n_cols_a} != matrix_b rows {n_rows_b}"
)
n_cols_b = len(matrix_b[0])
if any(len(row) != n_cols_b for row in matrix_b):
raise ValueError("All rows of matrix_b must have the same number of columns.")
result: List[List[float]] = []
for i in range(len(matrix_a)):
row: List[float] = []
for j in range(n_cols_b):
elem = sum(matrix_a[i][k] * matrix_b[k][j] for k in range(n_cols_a))
row.append(elem)
result.append(row)
return result
def transpose(matrix: List[List[float]]) -> List[List[float]]:
"""Return the transpose of a 2D matrix."""
if not matrix:
raise ValueError("Cannot transpose an empty matrix.")
n_rows = len(matrix)
n_cols = len(matrix[0])
if any(len(row) != n_cols for row in matrix):
raise ValueError("All rows of the matrix must have the same number of columns.")
return [[matrix[i][j] for i in range(n_rows)] for j in range(n_cols)]
def rotate_clockwise(matrix: List[List[float]]) -> List[List[float]]:
"""Rotate a square matrix 90 degrees clockwise."""
if not matrix:
raise ValueError("Cannot rotate an empty matrix.")
n_cols = len(matrix[0])
if any(len(row) != n_cols for row in matrix):
raise ValueError("All rows of the matrix must have the same number of columns.")
transposed = transpose(matrix)
return [row[::-1] for row in transposed]
def rot_2D(theta: float) -> List[List[float]]:
"""Return the 2D rotation matrix for a given angle in degrees."""
rad = math.radians(theta)
c = math.cos(rad)
s = math.sin(rad)
return [[c, -s], [s, c]]
def rot_3D(angle: float, axis: str) -> list[list[float]]:
"""Erzeugt eine 3D-Rotationsmatrix um die angegebene Achse ('x', 'y' oder 'z')."""
rad = math.radians(angle)
c, s = math.cos(rad), math.sin(rad)
axis = axis.lower()
if axis == 'x':
return [
[1.0, 0.0, 0.0],
[0.0, c, -s],
[0.0, s, c]
]
elif axis == 'y':
return [
[c, 0.0, s],
[0.0, 1.0, 0.0],
[-s, 0.0, c]
]
elif axis == 'z':
return [
[c, -s, 0.0],
[s, c, 0.0],
[0.0, 0.0, 1.0]
]
else:
raise ValueError("Achse muss 'x', 'y' oder 'z' sein.")
def project_ortho(point: tuple[float, float, float], scale: float = 1.0) -> tuple[float, float]:
"""Projiziert einen 3D-Punkt orthogonal auf eine 2D-Ebene und skaliert ihn."""
x, y, z = point
return (x * scale, y * scale)
def project_perspective(point: tuple[float, float, float], distance: float = 200.0, scale: float = 1.0) -> tuple[float, float]:
"""Projiziert einen 3D-Punkt perspektivisch auf eine 2D-Fläche."""
x, y, z = point
# Verhindert Division durch 0, falls z genau bei -distance liegt
factor = distance / (distance + z) if (distance + z) != 0 else 1.0
return (x * factor * scale, y * factor * scale)
if __name__ == "__main__":
a = [[1, 2, 3], [4, 5, 6]]
b = [[7, 8], [9, 10], [11, 12]]
print("matmul(a, b):", matmul(a, b))
print("transpose(a):", transpose(a))
# Teste deine Tests mit: python -m pytest