hihi
This commit is contained in:
commit
d692f1282d
1 file changed
+140
+140
@@ -0,0 +1,140 @@
|
||||
"""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
|
||||
|
||||
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)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user