TheAlgorithms/Python · error · ValueError

Coefficient matrix is not strictly diagonally dominant

Error message

Coefficient matrix is not strictly diagonally dominant

What it means

Thrown by strictly_diagonally_dominant(), called from jacobi_iteration_method(), when for any row the diagonal entry is <= the sum of the other coefficients in that row. Jacobi iteration is only guaranteed to converge for strictly diagonally dominant matrices, so a non-dominant matrix is rejected rather than iterated into divergence.

Source

Thrown at linear_algebra/jacobi_iteration_method.py:195

    Traceback (most recent call last):
        ...
    ValueError: Coefficient matrix is not strictly diagonally dominant
    """

    rows, cols = table.shape

    is_diagonally_dominant = True

    for i in range(rows):
        total = 0
        for j in range(cols - 1):
            if i == j:
                continue
            else:
                total += table[i][j]

        if table[i][i] <= total:
            raise ValueError("Coefficient matrix is not strictly diagonally dominant")

    return is_diagonally_dominant


# Test Cases
if __name__ == "__main__":
    import doctest

    doctest.testmod()

View on GitHub (pinned to f5988cc097)

Solutions

  1. Reorder equations (pivot rows) so each row's largest-magnitude coefficient sits on the diagonal.
  2. Verify dominance before calling: all(|A[i,i]| > sum(|A[i,j]| for j != i) for i in range(n)).
  3. If reordering cannot achieve dominance, switch methods: gauss_seidel in this repo, or np.linalg.solve.

Example fix

# before
A = np.array([[1.0, 2.0], [3.0, 4.0]])  # row 0 not dominant

# after
A = np.array([[4.0, 3.0], [2.0, 1.0]])  # swap rows: |4|>3, |1|... use truly dominant rows
# or verify first:
assert all(abs(A[i, i]) > sum(abs(A[i, j]) for j in range(len(A)) if j != i) for i in range(len(A)))
Defensive patterns

Strategy: validation

Validate before calling

def is_strictly_diagonally_dominant(A: np.ndarray) -> bool:
    return all(
        abs(A[i, i]) > sum(abs(A[i, j]) for j in range(len(A)) if j != i)
        for i in range(len(A))
    )

assert is_strictly_diagonally_dominant(A)

Type guard

def is_jacobi_solvable(A: np.ndarray) -> bool:
        return (
        A.ndim == 2
        and A.shape[0] == A.shape[1]
        and is_strictly_diagonally_dominant(A)
    )

Try / catch

try:
    x = jacobi_iteration_method(A, b, x0, iters)
except ValueError as e:
    if "diagonally dominant" in str(e):
        A2 = reorder_rows_for_dominance(A)  # put max |coef| on each diagonal
        x = jacobi_iteration_method(A2, b, x0, iters)
    else:
        raise

Prevention

When it happens

Trigger: Calling jacobi_iteration_method with A = [[1, 2], [3, 4]] (|1| <= 2 in row 0). Note the check sums off-diagonal entries without abs(), so matrices with large negative off-diagonals can slip through or trip unexpectedly. Systems assembled in arbitrary equation order are the usual culprit.

Common situations: Equations ordered so the large coefficient is off-diagonal (reorder rows to put each row's largest coefficient on the diagonal); physically ill-conditioned systems (weak diagonal coupling) that Jacobi cannot solve — use Gauss-Seidel or direct solvers instead.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/74b0c37d632a8599. Report an issue: GitHub.