Spaces:
Running on Zero
Running on Zero
atakan
fix: Enforce parameter provenance, fix rendering/citations, add tools, harden agent loop
48ee375 | """Deterministic linear-algebra tool: the basic matrix operations every other | |
| analysis builds on. Direct requests like "A times B", "invert this matrix", or | |
| "eigenvalues of A" must never depend on model-written freehand code -- they get | |
| one schema-validated tool call.""" | |
| from __future__ import annotations | |
| from typing import Any | |
| import numpy as np | |
| from controlai_agent.registry import registry | |
| def matrix_arithmetic( | |
| operation: str, | |
| matrix_a: list[list[float]], | |
| matrix_b: list[list[float]] | None = None, | |
| ) -> dict[str, Any]: | |
| A = np.array(matrix_a, dtype=float) | |
| binary_ops = {"multiply", "add", "subtract", "elementwise_multiply"} | |
| if operation in binary_ops: | |
| if matrix_b is None: | |
| return {"status": "error", "error": f"operation '{operation}' requires matrix_b."} | |
| B = np.array(matrix_b, dtype=float) | |
| if operation == "multiply": | |
| if A.shape[1] != B.shape[0]: | |
| return { | |
| "status": "error", | |
| "error": f"Cannot multiply: matrix_a is {A.shape[0]}x{A.shape[1]} but matrix_b is {B.shape[0]}x{B.shape[1]} (inner dimensions must match).", | |
| } | |
| result = A @ B | |
| elif operation == "elementwise_multiply": | |
| if A.shape != B.shape: | |
| return {"status": "error", "error": f"Elementwise multiply needs equal shapes, got {A.shape} and {B.shape}."} | |
| result = A * B | |
| else: | |
| if A.shape != B.shape: | |
| return {"status": "error", "error": f"'{operation}' needs equal shapes, got {A.shape} and {B.shape}."} | |
| result = A + B if operation == "add" else A - B | |
| return { | |
| "operation": operation, | |
| "shape_a": list(A.shape), | |
| "shape_b": list(B.shape), | |
| "result": result.tolist(), | |
| "result_shape": list(result.shape), | |
| } | |
| # Unary operations | |
| out: dict[str, Any] = {"operation": operation, "shape_a": list(A.shape)} | |
| if operation == "transpose": | |
| out["result"] = A.T.tolist() | |
| elif operation == "rank": | |
| out["result"] = int(np.linalg.matrix_rank(A)) | |
| elif operation in ("inverse", "determinant", "trace", "eigenvalues"): | |
| if A.shape[0] != A.shape[1]: | |
| return {"status": "error", "error": f"'{operation}' requires a square matrix, got {A.shape[0]}x{A.shape[1]}."} | |
| if operation == "inverse": | |
| det = float(np.linalg.det(A)) | |
| if abs(det) < 1e-12: | |
| return {"status": "error", "error": f"Matrix is singular (determinant = {det:g}); no inverse exists."} | |
| out["result"] = np.linalg.inv(A).tolist() | |
| out["determinant"] = det | |
| elif operation == "determinant": | |
| out["result"] = float(np.linalg.det(A)) | |
| elif operation == "trace": | |
| out["result"] = float(np.trace(A)) | |
| else: # eigenvalues | |
| eig = np.linalg.eigvals(A) | |
| out["result"] = [[float(v.real), float(v.imag)] for v in eig] | |
| out["spectral_radius"] = float(np.max(np.abs(eig))) | |
| return out | |