install_dependencies.py, test_projection.py, test_rot.py hinzugefügt, compute.py und pyproject.toml modified
This commit is contained in:
1 parent
bdbf024154
commit
806434d813
5 files changed
+255
-80
No files matched your search
+51
-79
@@ -1,8 +1,7 @@
|
||||
"""Compute operations for matrices.
|
||||
|
||||
This module provides public functions for matrix multiplication, transposition,
|
||||
matrix rotation, and generating 2D rotation matrices. The implementation is
|
||||
lightweight, well typed and contains detailed Google‑style documentation.
|
||||
matrix rotation, and generating 2D and 3D rotation matrices as well as projections.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -12,7 +11,7 @@ from typing import List
|
||||
|
||||
|
||||
def matmul(
|
||||
matrix_a: List[List[float]], matrix_b: List[List[float]]
|
||||
matrix_a: List[List[float]], matrix_b: List[List[float]]
|
||||
) -> List[List[float]]:
|
||||
"""Multiply two 2D matrices.
|
||||
|
||||
@@ -21,33 +20,25 @@ def matmul(
|
||||
rows in ``matrix_b``.
|
||||
|
||||
Args:
|
||||
matrix_a: A matrix of shape (m, n) represented as a list of m rows,
|
||||
each a list of n floats.
|
||||
matrix_b: A matrix of shape (n, p) represented as a list of n rows,
|
||||
each a list of p floats.
|
||||
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``.
|
||||
A new matrix of shape (m, p) containing the product ``matrix_a @ matrix_b``.
|
||||
|
||||
Raises:
|
||||
ValueError: If either matrix is empty or if the column count of
|
||||
``matrix_a`` does not match the row count of ``matrix_b``.
|
||||
ValueError: If either matrix is empty or dimensions do not match.
|
||||
"""
|
||||
|
||||
# SCHRITT 1: Validierung – Prüfen, ob die Matrizen überhaupt Daten enthalten
|
||||
if not matrix_a or not matrix_b:
|
||||
raise ValueError("Input matrices must not be empty.")
|
||||
|
||||
n_cols_a = len(matrix_a[0])
|
||||
|
||||
# SCHRITT 2: Konsistenzprüfung für Matrix A
|
||||
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)
|
||||
|
||||
# SCHRITT 3: Mathematische Regel prüfen: Spalten von A müssen gleich Zeilen von B sein
|
||||
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}"
|
||||
@@ -55,15 +46,13 @@ def matmul(
|
||||
|
||||
n_cols_b = len(matrix_b[0])
|
||||
|
||||
# SCHRITT 4: Konsistenzprüfung für Matrix B
|
||||
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.")
|
||||
|
||||
# SCHRITT 5: Eigentliche Matrixmultiplikation (Skalarprodukt der Zeilen und Spalten)
|
||||
result: List[List[float]] = []
|
||||
for i in range(len(matrix_a)): # Gehe jede Zeile von Matrix A durch
|
||||
for i in range(len(matrix_a)):
|
||||
row: List[float] = []
|
||||
for j in range(n_cols_b): # Gehe jede Spalte von Matrix B durch
|
||||
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)
|
||||
@@ -72,18 +61,7 @@ def matmul(
|
||||
|
||||
|
||||
def transpose(matrix: List[List[float]]) -> List[List[float]]:
|
||||
"""Return the transpose of a 2‑D matrix.
|
||||
|
||||
Args:
|
||||
matrix: A non‑empty matrix represented as a list of rows.
|
||||
|
||||
Returns:
|
||||
A new matrix where rows become columns.
|
||||
|
||||
Raises:
|
||||
ValueError: If the input matrix is empty or ragged.
|
||||
"""
|
||||
|
||||
"""Return the transpose of a 2D matrix."""
|
||||
if not matrix:
|
||||
raise ValueError("Cannot transpose an empty matrix.")
|
||||
|
||||
@@ -97,27 +75,11 @@ def transpose(matrix: List[List[float]]) -> List[List[float]]:
|
||||
|
||||
|
||||
def rotate_clockwise(matrix: List[List[float]]) -> List[List[float]]:
|
||||
"""Rotate a square matrix 90 degrees clockwise.
|
||||
|
||||
The function works for any rectangular matrix but will produce a matrix
|
||||
of dimensions (cols, rows).
|
||||
|
||||
Args:
|
||||
matrix: A non‑empty matrix.
|
||||
|
||||
Returns:
|
||||
The rotated matrix.
|
||||
|
||||
Raises:
|
||||
ValueError: If the matrix is empty.
|
||||
"""
|
||||
|
||||
"""Rotate a square matrix 90 degrees clockwise."""
|
||||
if not matrix:
|
||||
raise ValueError("Cannot rotate 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.")
|
||||
|
||||
@@ -126,42 +88,52 @@ def rotate_clockwise(matrix: List[List[float]]) -> List[List[float]]:
|
||||
|
||||
|
||||
def rot_2D(theta: float) -> List[List[float]]:
|
||||
"""Return the 2D rotation matrix for a given angle.
|
||||
|
||||
Calculates the 2x2 rotation matrix used in computer graphics to rotate a point
|
||||
counterclockwise around the origin by angle theta (in radians).
|
||||
|
||||
Args:
|
||||
theta: The rotation angle in radians.
|
||||
|
||||
Returns:
|
||||
A 2x2 rotation matrix represented as a list of lists of floats:
|
||||
[[cos(theta), -sin(theta)],
|
||||
[sin(theta), cos(theta)]]
|
||||
"""
|
||||
c = math.cos(theta)
|
||||
s = math.sin(theta)
|
||||
"""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)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Testdaten für die Demonstration
|
||||
a = [[1, 2, 3], [4, 5, 6]]
|
||||
b = [[7, 8], [9, 10], [11, 12]]
|
||||
|
||||
print("matmul(a, b):")
|
||||
print(matmul(a, b))
|
||||
print("matmul(a, b):", matmul(a, b))
|
||||
print("transpose(a):", transpose(a))
|
||||
|
||||
print("transpose(a):")
|
||||
print(transpose(a))
|
||||
|
||||
c = [[1, 2], [3, 4], [5, 6]]
|
||||
print("rotate_clockwise(c):")
|
||||
print(rotate_clockwise(c))
|
||||
|
||||
# Demonstration von rot_2D (z. B. 90 Grad = pi / 2 Radiant)
|
||||
angle = math.pi / 2
|
||||
print(f"rot_2D (pi / 2 radians / 90 degrees):")
|
||||
rotation_matrix = rot_2D(angle)
|
||||
for row in rotation_matrix:
|
||||
print([round(val, 4) for val in row])
|
||||
# Teste deine Tests mit: python -m pytest
|
||||
Reference in new issue
Block a user