144 lines
3.8 KiB
Python
144 lines
3.8 KiB
Python
"""
|
|
Mathematical operations on matrices.
|
|
|
|
``matmul`` multiplies two matrices in the usual way. The matrices are
|
|
represented as nested ``list`` objects. All rows must be of the same
|
|
length; all columns are assumed to contain numeric values that can be
|
|
multiplied and added.
|
|
|
|
If the inner dimension does not match (number of columns in ``matrix_a``
|
|
must equal the number of rows in ``matrix_b``) a ``ValueError`` with the
|
|
error message "diese matriezen können nicht multiplieziert werden."
|
|
is raised.
|
|
"""
|
|
|
|
import math
|
|
from typing import List, Iterable
|
|
|
|
|
|
def _is_rectangular(matrix: Iterable[Iterable]) -> bool:
|
|
"""Return ``True`` if the matrix contains rows of equal length."""
|
|
try:
|
|
rows: List[List] = [list(row) for row in matrix]
|
|
except TypeError:
|
|
return False
|
|
if not rows:
|
|
return True
|
|
first_len = len(rows[0])
|
|
return all(len(r) == first_len for r in rows)
|
|
|
|
|
|
def transpose(matrix: List[List[float]]) -> List[List[float]]:
|
|
"""Return the transpose of ``matrix``.
|
|
|
|
Parameters
|
|
----------
|
|
matrix: list[list[float]]
|
|
The source rectangular matrix.
|
|
|
|
Returns
|
|
-------
|
|
list[list[float]]
|
|
Transposed matrix.
|
|
|
|
Raises
|
|
------
|
|
ValueError
|
|
If the input is not a rectangular matrix.
|
|
"""
|
|
if not _is_rectangular(matrix):
|
|
raise ValueError("Input is not a rectangular matrix.")
|
|
rows = [list(row) for row in matrix]
|
|
n_rows = len(rows)
|
|
n_cols = len(rows[0]) if rows else 0
|
|
return [[rows[i][j] for i in range(n_rows)] for j in range(n_cols)]
|
|
|
|
def rot_2D(x: float, y: float, theta: float) -> List[float]:
|
|
"""Rotate the point ``(x, y)`` around the origin by ``theta`` radians.
|
|
|
|
Uses the rotation matrix
|
|
R = [[cos(theta), -sin(theta)],
|
|
[sin(theta), cos(theta)]].
|
|
"""
|
|
rotation_matrix = [
|
|
[math.cos(theta), -math.sin(theta)],
|
|
[math.sin(theta), math.cos(theta)],
|
|
]
|
|
return [
|
|
rotation_matrix[0][0] * x + rotation_matrix[0][1] * y,
|
|
rotation_matrix[1][0] * x + rotation_matrix[1][1] * y,
|
|
]
|
|
|
|
|
|
|
|
def matmul(matrix_a: List[List[float]], matrix_b: List[List[float]]) -> List[List[float]]:
|
|
"""Return the product of two matrices.
|
|
|
|
Parameters
|
|
----------
|
|
matrix_a, matrix_b
|
|
Nested lists representing the matrices.
|
|
|
|
Returns
|
|
-------
|
|
list[list[float]]
|
|
The resulting matrix.
|
|
|
|
Raises
|
|
------
|
|
ValueError
|
|
If the inner dimension is incompatible or the input is not
|
|
rectangular.
|
|
"""
|
|
if not (_is_rectangular(matrix_a) and _is_rectangular(matrix_b)):
|
|
raise ValueError("diese matriezen können nicht multiplieziert werden.")
|
|
a = [list(row) for row in matrix_a]
|
|
b = [list(row) for row in matrix_b]
|
|
rows_a, cols_a = len(a), len(a[0]) if a else 0
|
|
rows_b, cols_b = len(b), len(b[0]) if b else 0
|
|
if cols_a != rows_b:
|
|
raise ValueError("diese matriezen können nicht multiplieziert werden.")
|
|
result: List[List[float]] = [[0.0 for _ in range(cols_b)] for _ in range(rows_a)]
|
|
for i in range(rows_a):
|
|
for k in range(cols_a):
|
|
aik = a[i][k]
|
|
for j in range(cols_b):
|
|
result[i][j] += aik * b[k][j]
|
|
return result
|
|
|
|
|
|
my_matrix = [
|
|
[1.0, 2.0, 3.0],
|
|
[4.0, 5.0, 6.0]
|
|
]
|
|
|
|
# Alle öffentlichen Funktionen korrekt exportieren
|
|
#exportieren
|
|
__all__ = ["transpose", "matmul","rot_2D" ]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
a = [[1, 2, 3],
|
|
[4, 5, 6]]
|
|
b = [[7, 8],
|
|
[9, 10],
|
|
[11, 12]]
|
|
|
|
print("multiplication (matmul):")
|
|
print(matmul(a, b))
|
|
|
|
print("\nOriginal Matrix:")
|
|
print(my_matrix)
|
|
|
|
print("\ntranspose Matrix:")
|
|
trsp = transpose(my_matrix)
|
|
print(trsp)
|
|
|
|
print("\nrot_2D:")
|
|
# Punkt (1, 0) um 90 Grad (pi / 2) drehen
|
|
x_neu, y_neu = rot_2D(1.0, 0.0, math.pi / 2)
|
|
|
|
print(f"Gedrehter Punkt: x = {x_neu:.2f}, y = {y_neu:.2f}")
|
|
|
|
|