TheAlgorithms/Python · error · ValueError
Matrix is singular
Error message
Matrix is singular
What it means
Raised by solve_linear_system() in linear_algebra/src/gaussian_elimination_pivoting.py:51 during forward elimination when, after the pivot search, abs(ab[column_num][column_num]) < 1e-8. This means no usable pivot exists in that column — the matrix is (numerically) singular or ill-conditioned enough that the fixed 1e-8 tolerance rejects it, so back substitution would divide by zero.
Source
Thrown at linear_algebra/src/gaussian_elimination_pivoting.py:51
ValueError: Matrix is singular
"""
ab = np.copy(matrix)
num_of_rows = ab.shape[0]
num_of_columns = ab.shape[1] - 1
x_lst: list[float] = []
if num_of_rows != num_of_columns:
raise ValueError("Matrix is not square")
for column_num in range(num_of_rows):
# Lead element search
for i in range(column_num, num_of_columns):
if abs(ab[i][column_num]) > abs(ab[column_num][column_num]):
ab[[column_num, i]] = ab[[i, column_num]]
# Upper triangular matrix
if abs(ab[column_num, column_num]) < 1e-8:
raise ValueError("Matrix is singular")
if column_num != 0:
for i in range(column_num, num_of_rows):
ab[i, :] -= (
ab[i, column_num - 1]
/ ab[column_num - 1, column_num - 1]
* ab[column_num - 1, :]
)
# Find x vector (Back Substitution)
for column_num in range(num_of_rows - 1, -1, -1):
x = ab[column_num, -1] / ab[column_num, column_num]
x_lst.insert(0, x)
for i in range(column_num - 1, -1, -1):
ab[i, -1] -= ab[i, column_num] * x
# Return the solution vector
return np.asarray(x_lst)View on GitHub (pinned to f5988cc097)
Solutions
- Check np.linalg.matrix_rank(A) == n or abs(np.linalg.det(A)) is not tiny before calling.
- Rescale rows/columns so matrix entries are of order 1 (row equilibration) — the 1e-8 tolerance is absolute, not relative.
- Remove linearly dependent equations or use np.linalg.lstsq for rank-deficient least-squares solutions.
- Catch ValueError and surface a 'singular system' message to the caller.
Example fix
// before
x = solve_linear_system(np.array([[1, 2, 3], [2, 4, 6]], dtype=float)) # ValueError: singular
// after
A = np.array([[1, 2], [2, 4]])
if np.linalg.matrix_rank(A) < A.shape[0]:
x, *_ = np.linalg.lstsq(A, np.array([3, 6]), rcond=None)
else:
ab = np.column_stack((A, np.array([3, 6]))).astype(float)
x = solve_linear_system(ab) Defensive patterns
Strategy: try-catch
Validate before calling
import numpy as np
A = ab[:, :-1]
# rank check + scale check: the solver's 1e-8 pivot tolerance is absolute
nonsingular = np.linalg.matrix_rank(A) == A.shape[0]
well_scaled = np.max(np.abs(A)) > 1e-6 # avoids rejecting legitimately small entries
if not (nonsingular and well_scaled):
raise ValueError("system is singular or too small in magnitude for the 1e-8 pivot tolerance") Try / catch
try:
x = solve_linear_system(ab)
except ValueError as e:
if "singular" in str(e):
x, *_ = np.linalg.lstsq(ab[:, :-1], ab[:, -1], rcond=None) # least-squares fallback
else:
raise Prevention
- Screen with np.linalg.matrix_rank(A) == n before solving; rank deficiency guarantees this error.
- Scale equations so coefficients are order 1 — the 1e-8 pivot cutoff is absolute, so uniformly tiny systems (entries ~1e-9) get falsely rejected.
- Deduplicate or drop linearly dependent rows before assembling the system.
- Distinguish the two ValueErrors this function raises ('not square' vs 'singular') by message when handling both.
When it happens
Trigger: Calling solve_linear_system() with duplicate/linearly dependent rows, e.g. np.array([[1, 2, 3], [2, 4, 6]], dtype=float) (row2 = 2*row1), or np.zeros((2, 3)). Also triggered by very small-magnitude entries: a matrix scaled by 1e-9 can be rejected even if mathematically non-singular, because of the absolute tolerance.
Common situations: Rank-deficient data (repeated measurements, collinear features), zero matrices from empty input, or poorly scaled systems where legitimate pivots fall below 1e-8. Users moving from np.linalg.solve are surprised that near-singular matrices are rejected by tolerance rather than producing garbage.
Related errors
- No LU decomposition exists
- Matrix is not invertible
- Matrix is not square
- Input matrix A is not invertible. Cannot compute Schur compl
- determinant modular {req_l} of encryption key({det}) is not
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/e4334817edd12f7e.
Report an issue: GitHub.