{"record":{"id":"6dd8bba1a185f833","repo":"TheAlgorithms/Python","slug":"input-matrix-a-is-not-invertible-cannot-compute-s","errorCode":null,"errorMessage":"Input matrix A is not invertible. Cannot compute Schur complement.","messagePattern":"Input matrix A is not invertible\\. Cannot compute Schur complement\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"linear_algebra/src/schur_complement.py","lineNumber":54,"sourceCode":"        msg = (\n            \"Expected the same number of rows for A and B. \"\n            f\"Instead found A of size {shape_a} and B of size {shape_b}\"\n        )\n        raise ValueError(msg)\n\n    if shape_b[1] != shape_c[1]:\n        msg = (\n            \"Expected the same number of columns for B and C. \"\n            f\"Instead found B of size {shape_b} and C of size {shape_c}\"\n        )\n        raise ValueError(msg)\n\n    a_inv = pseudo_inv\n    if a_inv is None:\n        try:\n            a_inv = np.linalg.inv(mat_a)\n        except np.linalg.LinAlgError:\n            raise ValueError(\n                \"Input matrix A is not invertible. Cannot compute Schur complement.\"\n            )\n\n    return mat_c - mat_b.T @ a_inv @ mat_b\n\n\nclass TestSchurComplement(unittest.TestCase):\n    def test_schur_complement(self) -> None:\n        a = np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]])\n        b = np.array([[0, 3], [3, 0], [2, 3]])\n        c = np.array([[2, 1], [6, 3]])\n\n        s = schur_complement(a, b, c)\n\n        input_matrix = np.block([[a, b], [b.T, c]])\n\n        det_x = np.linalg.det(input_matrix)\n        det_a = np.linalg.det(a)","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/linear_algebra/src/schur_complement.py#L36-L72","documentation":"Raised by schur_complement when np.linalg.inv(mat_a) raises LinAlgError, i.e. block A is square but singular (determinant 0 or numerically rank-deficient). The mathematical Schur complement requires a non-singular A; the function offers the pseudo_inv parameter exactly for this case.","triggerScenarios":"Passing a singular A such as np.array([[1, 2], [2, 4]]) without the pseudo_inv argument. Also happens for nearly-singular A under floating-point round-off when the LU solver reports exact singularity.","commonSituations":"Covariance matrices from degenerate data (fewer samples than dimensions), A containing linearly dependent rows/columns, or regularizing later but forgetting that this call needs the inverse.","solutions":["Supply a pseudo-inverse explicitly: schur_complement(a, b, c, pseudo_inv=np.linalg.pinv(a)).","Regularize A before calling, e.g. a_reg = a + 1e-8 * np.eye(a.shape[0]).","Inspect A's rank with np.linalg.matrix_rank(a) and remove linearly dependent rows/columns if full rank is expected."],"exampleFix":"# before\nresult = schur_complement(a, b, c)  # a is singular\n\n# after\nresult = schur_complement(a, b, c, pseudo_inv=np.linalg.pinv(a))","handlingStrategy":"fallback","validationCode":"if np.linalg.matrix_rank(mat_a) < mat_a.shape[0]:\n    result = schur_complement(mat_a, mat_b, mat_c, pseudo_inv=np.linalg.pinv(mat_a))\nelse:\n    result = schur_complement(mat_a, mat_b, mat_c)","typeGuard":"def is_invertible(a: np.ndarray) -> bool:\n    return a.ndim == 2 and a.shape[0] == a.shape[1] and np.linalg.matrix_rank(a) == a.shape[0]","tryCatchPattern":"try:\n    result = schur_complement(a, b, c)\nexcept ValueError as e:\n    if \"not invertible\" in str(e):\n        result = schur_complement(a, b, c, pseudo_inv=np.linalg.pinv(a))\n    else:\n        raise","preventionTips":["Check np.linalg.matrix_rank(A) before calling when A comes from data.","Know the pseudo_inv escape hatch exists for singular A.","Regularize nearly-singular A with a small ridge term when appropriate."],"tags":["linear-algebra","schur-complement","singular-matrix","numpy","pseudo-inverse"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}