TheAlgorithms/Python · error · ValueError

Expected the same number of columns for B and C. Instead fou

Error message

Expected the same number of columns for B and C. Instead found B of size {shape_b} and C of size {shape_c}

What it means

Raised by schur_complement when the column count of B differs from the column count of C. The final product B.T @ inv(A) @ B yields a q x q matrix that must subtract cleanly from C, so C must be q x q with q = mat_b.shape[1].

Source

Thrown at linear_algebra/src/schur_complement.py:47

           [ 0.,  6.]])
    """
    shape_a = np.shape(mat_a)
    shape_b = np.shape(mat_b)
    shape_c = np.shape(mat_c)

    if shape_a[0] != shape_b[0]:
        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]])

View on GitHub (pinned to f5988cc097)

Solutions

  1. Check np.shape(mat_b)[1] == np.shape(mat_c)[1] == np.shape(mat_c)[0] before calling (C should be square with dimension equal to B's columns).
  2. Fix the construction of C so it covers exactly the variables spanned by B's columns.
  3. If C came from a larger matrix, slice it to the correct block instead of passing the whole matrix.

Example fix

# before
b = np.ones((3, 2)); c = np.eye(3)  # c is 3x3, b has 2 columns
schur_complement(np.eye(3), b, c)

# after
b = np.ones((3, 2)); c = np.eye(2)
schur_complement(np.eye(3), b, c)
Defensive patterns

Strategy: validation

Validate before calling

if mat_b.shape[1] != mat_c.shape[1] or mat_c.shape[0] != mat_c.shape[1]:
    raise ValueError("C must be square with dimension equal to B's columns")
result = schur_complement(mat_a, mat_b, mat_c)

Type guard

def blocks_col_aligned(b: np.ndarray, c: np.ndarray) -> bool:
    return b.ndim == 2 and c.ndim == 2 and b.shape[1] == c.shape[0] == c.shape[1]

Try / catch

try:
    schur_complement(a, b, c)
except ValueError as e:
    if "number of columns" in str(e):
        raise ValueError(f"block partition inconsistent: {e}") from None

Prevention

When it happens

Trigger: Calling schur_complement(a, b, c) where np.shape(mat_b)[1] != np.shape(mat_c)[1], e.g. B is 3x2 while C is 2x3.

Common situations: Passing a non-square C, forgetting that C indexes the same coordinates as the columns of B, or building C from a differently-ordered subset of features than B.

Related errors


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