sympy_mcp_matrix_operation
Perform symbolic matrix operations such as determinant, inverse, row reduction, and eigenvalue computation. Input data and specify operations for precise mathematical analysis.
Instructions
Do symbolic matrix operations like create, det, inv, rref, eigenvals
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | ||
| ncols | No | ||
| nrows | No | ||
| operation | Yes | ||
| rational | No | ||
| simplify | No |
Implementation Reference
- fmcp/sympy_mcp/core/matrices.py:59-178 (handler)The handler function matrix_operation that executes the tool logic for various SymPy matrix operations including det, inv, rref, eigenvals, and create.def matrix_operation( operation: MatrixOperation, data: Union[str, List, Tuple], # Create parameters rational: bool = True, nrows: Optional[int] = None, ncols: Optional[int] = None, # Common parameters simplify: bool = True, ) -> Any: """ Unified interface for matrix operations. Args: operation: The matrix operation to perform. One of: - 'create': Create a matrix from data - 'det': Calculate the determinant - 'inv': Calculate the inverse - 'rref': Compute reduced row echelon form - 'eigenvals': Compute eigenvalues data: The matrix data in one of these formats: - String: "1 2; 3 4" or "[1, 2] [3, 4]" - List of lists: [[1, 2], [3, 4]] - Single list: [1, 2, 3, 4] (will be converted to a row matrix) rational: If True, convert to rational numbers (default: True) nrows, ncols: For creating matrices of specific dimensions simplify: If True, simplify the result (default: True) Returns: The result of the operation in a JSON-serializable format. For 'create', returns the matrix as a list of lists. For 'det', returns the determinant as a float or symbolic expression. For 'inv', returns the inverse matrix as a list of lists. For 'rref', returns a tuple (RREF_matrix, pivot_columns). For 'eigenvals', returns a dictionary of eigenvalues with multiplicities. Examples: >>> matrix_operation('create', '1 2; 3 4') [[1, 2], [3, 4]] >>> matrix_operation('det', [[1, 2], [3, 4]]) -2 >>> matrix_operation('inv', '1 2; 3 4') [[-2.0, 1.0], [1.5, -0.5]] >>> matrix_operation('rref', '1 2 3; 4 5 6') ([[1, 0, -1], [0, 1, 2]], (0, 1)) >>> matrix_operation('eigenvals', '3 -2; 4 -1') {'1 - 2*I': 1, '1 + 2*I': 1} """ # Parse matrix data matrix_data = _parse_matrix_data(data) # Create matrix, optionally converting to rational numbers if rational: matrix = Matrix(matrix_data).applyfunc(lambda x: nsimplify(x, rational=True)) else: matrix = Matrix(matrix_data) # Handle matrix reshaping if nrows/ncols are provided if nrows is not None and ncols is not None: matrix = matrix.reshape(nrows, ncols) elif nrows is not None: matrix = matrix.reshape(nrows, -1) elif ncols is not None: matrix = matrix.reshape(-1, ncols) # Handle different operations if operation == "create": return _convert_to_json_serializable(matrix.tolist()) # For other operations, ensure the matrix is square if needed if operation in ["det", "inv", "eigenvals"] and matrix.rows != matrix.cols: raise ValueError(f"Matrix must be square for {operation} operation") if operation == "det": try: det = matrix.det() return float(det) if det.is_real else str(det) except (TypeError, AttributeError): return str(det) elif operation == "inv": try: inv_matrix = matrix.inv() return _convert_to_json_serializable(inv_matrix.tolist()) except ValueError as e: if "matrix is not invertible" in str(e).lower(): raise ValueError("Matrix is not invertible (determinant is zero)") raise elif operation == "rref": rref_matrix, pivot_columns = matrix.rref() return ( _convert_to_json_serializable(rref_matrix.tolist()), tuple(pivot_columns), ) elif operation == "eigenvals": try: eigenvals = matrix.eigenvals() # Convert to a serializable format with better handling of complex numbers result = {} for val, mult in eigenvals.items(): # Convert to complex and format nicely cval = complex(val.evalf()) if abs(cval.imag) < 1e-10: # Effectively real key = f"{cval.real:.6f}".rstrip("0").rstrip(".") else: # Complex number real_part = f"{cval.real:.6f}".rstrip("0").rstrip(".") imag_part = f"{abs(cval.imag):.6f}".rstrip("0").rstrip(".") sign = " + " if cval.imag >= 0 else " - " key = f"{real_part}{sign}{imag_part}j" result[key] = int(mult) return result except Exception as e: raise ValueError(f"Failed to compute eigenvalues: {str(e)}") else: valid_ops = get_args(MatrixOperation) raise ValueError(f"Invalid operation. Must be one of: {valid_ops}")
- fmcp/sympy_mcp/server.py:26-29 (registration)Registers the matrix_operation function as the sympy_mcp_matrix_operation tool in the FastMCP server.sympy_mcp.tool( matrix_operation, description="Do symbolic matrix operations like create, det, inv, rref, eigenvals", )
- fmcp/sympy_mcp/core/matrices.py:4-68 (schema)Type definitions for the tool parameters, including MatrixOperation literal and function signature serving as input schema.# Define operation types for type hints MatrixOperation = Literal["create", "det", "inv", "rref", "eigenvals"] def _parse_matrix_data(data: Union[List, Tuple, str]) -> List[List[Any]]: """Parse matrix data from various input formats.""" if isinstance(data, str): # Handle string input like "1 2; 3 4" or "[1, 2] [3, 4]" if ";" in data: # Handle MATLAB-style format: "1 2; 3 4" rows = [row.strip() for row in data.split(";") if row.strip()] return [[sympify(x) for x in row.split()] for row in rows] else: # Handle list of lists format: "[1, 2] [3, 4]" import ast try: # Try to parse as a list of lists parsed = ast.literal_eval("[" + data.replace(" ", ",") + "]") if all(isinstance(row, (list, tuple)) for row in parsed): return [[sympify(x) for x in row] for row in parsed] elif all(not isinstance(x, (list, tuple)) for x in parsed): # Single row matrix return [[sympify(x) for x in parsed]] except (ValueError, SyntaxError): pass # Try space-separated values return [ [sympify(x) for x in row.split()] for row in data.split("\n") if row.strip() ] # Handle list/tuple input if all(isinstance(row, (list, tuple)) for row in data): return [[sympify(x) for x in row] for row in data] elif all(not isinstance(x, (list, tuple)) for x in data): # Single row matrix return [[sympify(x) for x in data]] raise ValueError("Invalid matrix format") def _convert_to_json_serializable(obj): """Convert SymPy objects to JSON-serializable types.""" if hasattr(obj, "as_immutable"): return str(obj) elif isinstance(obj, (list, tuple)): return [_convert_to_json_serializable(x) for x in obj] elif isinstance(obj, dict): return {str(k): _convert_to_json_serializable(v) for k, v in obj.items()} return obj def matrix_operation( operation: MatrixOperation, data: Union[str, List, Tuple], # Create parameters rational: bool = True, nrows: Optional[int] = None, ncols: Optional[int] = None, # Common parameters simplify: bool = True, ) -> Any:
- fmcp/sympy_mcp/core/matrices.py:8-46 (helper)Helper function to parse matrix data from different input formats into SymPy-compatible lists.def _parse_matrix_data(data: Union[List, Tuple, str]) -> List[List[Any]]: """Parse matrix data from various input formats.""" if isinstance(data, str): # Handle string input like "1 2; 3 4" or "[1, 2] [3, 4]" if ";" in data: # Handle MATLAB-style format: "1 2; 3 4" rows = [row.strip() for row in data.split(";") if row.strip()] return [[sympify(x) for x in row.split()] for row in rows] else: # Handle list of lists format: "[1, 2] [3, 4]" import ast try: # Try to parse as a list of lists parsed = ast.literal_eval("[" + data.replace(" ", ",") + "]") if all(isinstance(row, (list, tuple)) for row in parsed): return [[sympify(x) for x in row] for row in parsed] elif all(not isinstance(x, (list, tuple)) for x in parsed): # Single row matrix return [[sympify(x) for x in parsed]] except (ValueError, SyntaxError): pass # Try space-separated values return [ [sympify(x) for x in row.split()] for row in data.split("\n") if row.strip() ] # Handle list/tuple input if all(isinstance(row, (list, tuple)) for row in data): return [[sympify(x) for x in row] for row in data] elif all(not isinstance(x, (list, tuple)) for x in data): # Single row matrix return [[sympify(x) for x in data]] raise ValueError("Invalid matrix format")