Skip to main content
Glama
by apetta
test_linalg.py12.5 kB
"""Tests for linear algebra tools.""" import json import pytest @pytest.mark.asyncio async def test_matrix_multiply(mcp_client, sample_array_2x2): """Test matrix multiplication.""" result = await mcp_client.call_tool( "matrix_operations", {"operation": "multiply", "matrix1": sample_array_2x2, "matrix2": sample_array_2x2}, ) data = json.loads(result.content[0].text) assert "result" in data # [[1,2],[3,4]] * [[1,2],[3,4]] = [[7,10],[15,22]] assert data["result"] == [[7.0, 10.0], [15.0, 22.0]] @pytest.mark.asyncio async def test_matrix_transpose(mcp_client, sample_array_2x2): """Test matrix transpose.""" result = await mcp_client.call_tool( "matrix_operations", {"operation": "transpose", "matrix1": sample_array_2x2} ) data = json.loads(result.content[0].text) assert "result" in data assert data["result"] == [[1.0, 3.0], [2.0, 4.0]] @pytest.mark.asyncio async def test_matrix_determinant(mcp_client, sample_array_2x2): """Test matrix determinant.""" result = await mcp_client.call_tool( "matrix_operations", {"operation": "determinant", "matrix1": sample_array_2x2} ) data = json.loads(result.content[0].text) assert "result" in data # det([[1,2],[3,4]]) = 1*4 - 2*3 = -2 assert abs(data["result"] - (-2.0)) < 1e-10 @pytest.mark.asyncio async def test_matrix_trace(mcp_client, sample_array_2x2): """Test matrix trace.""" result = await mcp_client.call_tool( "matrix_operations", {"operation": "trace", "matrix1": sample_array_2x2} ) data = json.loads(result.content[0].text) assert "result" in data # trace([[1,2],[3,4]]) = 1 + 4 = 5 assert data["result"] == 5.0 @pytest.mark.asyncio async def test_solve_linear_system(mcp_client): """Test solving linear system.""" # 2x + 3y = 8 # x + y = 3 coefficients = [[2, 3], [1, 1]] constants = [8, 3] result = await mcp_client.call_tool( "solve_linear_system", {"coefficients": coefficients, "constants": constants, "method": "direct"}, ) data = json.loads(result.content[0].text) assert "result" in data # Solution: x=1, y=2 assert abs(data["result"][0] - 1.0) < 1e-10 assert abs(data["result"][1] - 2.0) < 1e-10 @pytest.mark.asyncio async def test_matrix_decomposition_svd(mcp_client, sample_array_2x2): """Test SVD decomposition.""" result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": sample_array_2x2, "decomposition": "svd"} ) data = json.loads(result.content[0].text) assert "result" in data assert "U" in data["result"] assert "singular_values" in data["result"] assert "Vt" in data["result"] @pytest.mark.asyncio async def test_matrix_decomposition_qr(mcp_client, sample_array_2x2): """Test QR decomposition.""" result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": sample_array_2x2, "decomposition": "qr"} ) data = json.loads(result.content[0].text) assert "result" in data assert "Q" in data["result"] assert "R" in data["result"] @pytest.mark.asyncio async def test_matrix_inverse_2x2(mcp_client): """Test 2x2 matrix inversion.""" matrix = [[4.0, 7.0], [2.0, 6.0]] result = await mcp_client.call_tool( "matrix_operations", {"operation": "inverse", "matrix1": matrix} ) data = json.loads(result.content[0].text) assert "result" in data # Verify inverse exists and has correct shape assert len(data["result"]) == 2 assert len(data["result"][0]) == 2 # For [[4,7],[2,6]], det = 24-14 = 10, inverse = [[0.6,-0.7],[-0.2,0.4]] assert abs(data["result"][0][0] - 0.6) < 1e-10 @pytest.mark.asyncio async def test_matrix_inverse_3x3(mcp_client): """Test 3x3 matrix inversion.""" matrix = [[1.0, 2.0, 3.0], [0.0, 1.0, 4.0], [5.0, 6.0, 0.0]] result = await mcp_client.call_tool( "matrix_operations", {"operation": "inverse", "matrix1": matrix} ) data = json.loads(result.content[0].text) assert "result" in data # Verify inverse has correct shape assert len(data["result"]) == 3 assert len(data["result"][0]) == 3 @pytest.mark.asyncio async def test_matrix_inverse_singular(mcp_client): """Test error when trying to invert singular matrix.""" # Singular matrix (rows are linearly dependent) matrix = [[1.0, 2.0], [2.0, 4.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_operations", {"operation": "inverse", "matrix1": matrix} ) assert "singular" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_inverse_non_square(mcp_client): """Test error when trying to invert non-square matrix.""" matrix = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_operations", {"operation": "inverse", "matrix1": matrix} ) assert "square" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_multiply_incompatible_shapes(mcp_client): """Test error when multiplying incompatible matrices.""" matrix1 = [[1.0, 2.0], [3.0, 4.0]] # 2x2 matrix2 = [[1.0, 2.0, 3.0]] # 1x3 with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_operations", {"operation": "multiply", "matrix1": matrix1, "matrix2": matrix2}, ) assert "Incompatible" in str(exc_info.value) or "shape" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_multiply_missing_matrix2(mcp_client, sample_array_2x2): """Test error when matrix2 is missing for multiplication.""" with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_operations", {"operation": "multiply", "matrix1": sample_array_2x2} ) assert "requires matrix2" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_determinant_non_square(mcp_client): """Test error when computing determinant of non-square matrix.""" matrix = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_operations", {"operation": "determinant", "matrix1": matrix} ) assert "square" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_trace_non_square(mcp_client): """Test error when computing trace of non-square matrix.""" matrix = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_operations", {"operation": "trace", "matrix1": matrix} ) assert "square" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_solve_linear_system_dimension_mismatch(mcp_client): """Test error when coefficient matrix rows != constants vector length.""" coefficients = [[1.0, 2.0], [3.0, 4.0]] constants = [5.0, 6.0, 7.0] # Too many constants with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "solve_linear_system", {"coefficients": coefficients, "constants": constants, "method": "direct"}, ) assert "dimension" in str(exc_info.value).lower() or "incompatible" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_solve_linear_system_non_square_direct(mcp_client): """Test error when using direct method on non-square system.""" coefficients = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]] constants = [7.0, 8.0, 9.0] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "solve_linear_system", {"coefficients": coefficients, "constants": constants, "method": "direct"}, ) assert "square" in str(exc_info.value).lower() or "least_squares" in str(exc_info.value) @pytest.mark.asyncio async def test_solve_linear_system_singular(mcp_client): """Test error when system is singular.""" # Singular system (rows are linearly dependent) coefficients = [[1.0, 2.0], [2.0, 4.0]] constants = [3.0, 6.0] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "solve_linear_system", {"coefficients": coefficients, "constants": constants, "method": "direct"}, ) assert "singular" in str(exc_info.value).lower() or "poorly conditioned" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_decomposition_eigen_2x2(mcp_client): """Test eigenvalue decomposition of 2x2 matrix.""" matrix = [[4.0, 2.0], [1.0, 3.0]] result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "eigen"} ) data = json.loads(result.content[0].text) assert "result" in data assert "eigenvalues" in data["result"] assert "eigenvectors" in data["result"] assert len(data["result"]["eigenvalues"]) == 2 @pytest.mark.asyncio async def test_matrix_decomposition_eigen_3x3(mcp_client): """Test eigenvalue decomposition of 3x3 matrix.""" matrix = [[1.0, 2.0, 3.0], [0.0, 4.0, 5.0], [0.0, 0.0, 6.0]] result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "eigen"} ) data = json.loads(result.content[0].text) assert "result" in data assert len(data["result"]["eigenvalues"]) == 3 assert len(data["result"]["eigenvectors"]) == 3 @pytest.mark.asyncio async def test_matrix_decomposition_eigen_non_square(mcp_client): """Test error when computing eigenvalues of non-square matrix.""" matrix = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "eigen"} ) assert "square" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_decomposition_cholesky_positive_definite(mcp_client): """Test Cholesky decomposition of positive definite matrix.""" # Symmetric positive definite matrix matrix = [[4.0, 2.0], [2.0, 3.0]] result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "cholesky"} ) data = json.loads(result.content[0].text) assert "result" in data assert "L" in data["result"] assert len(data["result"]["L"]) == 2 @pytest.mark.asyncio async def test_matrix_decomposition_cholesky_non_symmetric(mcp_client): """Test error when Cholesky decomposition is applied to non-symmetric matrix.""" matrix = [[4.0, 1.0], [2.0, 3.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "cholesky"} ) assert "symmetric" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_decomposition_cholesky_not_positive_definite(mcp_client): """Test error when matrix is symmetric but not positive definite.""" # Symmetric but not positive definite (has negative eigenvalue) matrix = [[1.0, 2.0], [2.0, 1.0]] with pytest.raises(Exception) as exc_info: await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "cholesky"} ) assert "positive definite" in str(exc_info.value).lower() @pytest.mark.asyncio async def test_matrix_decomposition_lu_2x2(mcp_client): """Test LU decomposition of 2x2 matrix.""" matrix = [[3.0, 1.0], [6.0, 4.0]] result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "lu"} ) data = json.loads(result.content[0].text) assert "result" in data assert "P" in data["result"] assert "L" in data["result"] assert "U" in data["result"] assert len(data["result"]["L"]) == 2 @pytest.mark.asyncio async def test_matrix_decomposition_lu_3x3(mcp_client): """Test LU decomposition of 3x3 matrix.""" matrix = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 10.0]] result = await mcp_client.call_tool( "matrix_decomposition", {"matrix": matrix, "decomposition": "lu"} ) data = json.loads(result.content[0].text) assert "result" in data assert len(data["result"]["P"]) == 3 assert len(data["result"]["L"]) == 3 assert len(data["result"]["U"]) == 3

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apetta/vibe-math-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server