TheAlgorithms/Python · error · ValueError
Input matrix A is not invertible. Cannot compute Schur compl
Error message
Input matrix A is not invertible. Cannot compute Schur complement.
What it means
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.
Source
Thrown at linear_algebra/src/schur_complement.py:54
msg = (
"Expected the same number of rows for A and B. "
f"Instead found A of size {shape_a} and B of size {shape_b}"
)
raise ValueError(msg)
if shape_b[1] != shape_c[1]:
msg = (
"Expected the same number of columns for B and C. "
f"Instead found B of size {shape_b} and C of size {shape_c}"
)
raise ValueError(msg)
a_inv = pseudo_inv
if a_inv is None:
try:
a_inv = np.linalg.inv(mat_a)
except np.linalg.LinAlgError:
raise ValueError(
"Input matrix A is not invertible. Cannot compute Schur complement."
)
return mat_c - mat_b.T @ a_inv @ mat_b
class TestSchurComplement(unittest.TestCase):
def test_schur_complement(self) -> None:
a = np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]])
b = np.array([[0, 3], [3, 0], [2, 3]])
c = np.array([[2, 1], [6, 3]])
s = schur_complement(a, b, c)
input_matrix = np.block([[a, b], [b.T, c]])
det_x = np.linalg.det(input_matrix)
det_a = np.linalg.det(a)View on GitHub (pinned to f5988cc097)
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.
Example fix
# before result = schur_complement(a, b, c) # a is singular # after result = schur_complement(a, b, c, pseudo_inv=np.linalg.pinv(a))
Defensive patterns
Strategy: fallback
Validate before calling
if np.linalg.matrix_rank(mat_a) < mat_a.shape[0]:
result = schur_complement(mat_a, mat_b, mat_c, pseudo_inv=np.linalg.pinv(mat_a))
else:
result = schur_complement(mat_a, mat_b, mat_c) Type guard
def is_invertible(a: np.ndarray) -> bool:
return a.ndim == 2 and a.shape[0] == a.shape[1] and np.linalg.matrix_rank(a) == a.shape[0] Try / catch
try:
result = schur_complement(a, b, c)
except ValueError as e:
if "not invertible" in str(e):
result = schur_complement(a, b, c, pseudo_inv=np.linalg.pinv(a))
else:
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- No LU decomposition exists
- Matrix is not invertible
- Expected the same number of rows for A and B. Instead found
- Expected the same number of columns for B and C. Instead fou
- Coefficient matrix dimensions must be nxn but received {rows
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/6dd8bba1a185f833.
Report an issue: GitHub.