diff --git a/opencode.json b/opencode.json new file mode 100644 index 0000000..15be39d --- /dev/null +++ b/opencode.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "thn": { + "npm": "@ai-sdk/openai-compatible", + "options": { + "baseURL": "http://141.75.33.244:8000/v1", + "apiKey": "sk-QXj1p40XOwNSze_5-eYrBzVh3qIgAfqoWPkAjNVqOS8" + }, + "models": { + "gpt-oss:20b": { "name": "GPT-OSS 20B" } + } + } + }, + "model": "thn/gpt-oss:20b" +} \ No newline at end of file diff --git a/src/matrixmania/__init__.py b/src/matrixmania/__init__.py index d74c98f..42bb67e 100644 --- a/src/matrixmania/__init__.py +++ b/src/matrixmania/__init__.py @@ -1 +1 @@ -from .compute import matmul, transpose, rot_2d +from .compute import matmul, rot_2d, transpose, rot_3d diff --git a/src/matrixmania/compute.py b/src/matrixmania/compute.py index c2a64a8..51c9f04 100644 --- a/src/matrixmania/compute.py +++ b/src/matrixmania/compute.py @@ -14,13 +14,6 @@ from __future__ import annotations Matrix = list[list[float]] -def main(): - a = [[1, 2, 3], [4, 5, 6]] - b = [[7, 8], [10, 11], [12, 13]] - print(matmul(a,b)) - print(rotate(a)) - print(transpose(a)) - def matmul(a: Matrix, b: Matrix) -> Matrix: """Return the product of two matrices. @@ -119,7 +112,66 @@ def rot_2d(matrix: Matrix) -> Matrix: transposed = transpose(matrix) return [list(reversed(row)) for row in transposed] -if __name__ == "__main__": - main() +def rot_3d(matrix: Matrix, angle: float, axis: str) -> Matrix: + """Return a new matrix rotated around the specified axis. + + Parameters + ---------- + matrix: Matrix + Matrix of 3‑element vectors to be rotated. + angle: float + Rotation angle in degrees. + axis: str + Axis to rotate around. Must be ``'x'``, ``'y'`` or ``'z'``. + + Returns + ------- + Matrix + Rotated matrix of 3‑element vectors. + + Raises + ------ + ValueError + If the input matrix is empty, rows are not of length 3, or the axis is invalid. + """ + import math + + if not isinstance(angle, (int, float)): + raise ValueError("angle must be a numeric value") + if not isinstance(axis, str): + raise ValueError("axis must be a string") + + rad = math.radians(angle) + c = math.cos(rad) + s = math.sin(rad) + + axis = axis.lower() + if axis == "x": + rot = [[1, 0, 0], + [0, c, -s], + [0, s, c]] + elif axis == "y": + rot = [[c, 0, s], + [0, 1, 0], + [-s, 0, c]] + elif axis == "z": + rot = [[c, -s, 0], + [s, c, 0], + [0, 0, 1]] + else: + raise ValueError("axis must be one of 'x', 'y', or 'z'") + + if not matrix or not all(isinstance(row, list) for row in matrix): + raise ValueError("Input must be a list of rows") + if not all(len(row) == 3 for row in matrix): + raise ValueError("Each row must contain exactly 3 elements") + + result: Matrix = [] + for vec in matrix: + if any(not isinstance(v, (int, float)) for v in vec): + raise ValueError("All coordinates must be numeric") + rotated = [sum(v * r for v, r in zip(vec, col)) for col in zip(*rot)] + result.append([float(x) for x in rotated]) + return result """End of module""" diff --git a/test/test_matrixmania/test_rot.py b/test/test_matrixmania/test_rot.py new file mode 100644 index 0000000..b8c770e --- /dev/null +++ b/test/test_matrixmania/test_rot.py @@ -0,0 +1,13 @@ +from src.matrixmania.compute import * + +def test_matmul(): + a = [[1, 2, 3], [4, 5, 6]] + b = [[7, 8], [10, 11], [12, 13]] + + expected_value = [] + expected_type = Matrix + + result = matmul(a,b) + + assert result == expected_value + assert isinstance(result, expected_type) \ No newline at end of file