The rank of a matrix is the number of linearly independent rows (equivalently, columns). Computed by row reduction in .

Computing the rank

int rank(vector<vector<long long>> a, long long MOD) {
    int n = a.size(), m = a[0].size(), rk = 0;
    for (int col = 0; col < m && rk < n; col++) {
        int piv = -1;
        for (int r = rk; r < n; r++) if (a[r][col]) { piv = r; break; }
        if (piv < 0) continue;                            // free column
        swap(a[rk], a[piv]);
        long long inv = powmod(a[rk][col], MOD - 2, MOD);
        for (int c = col; c < m; c++) a[rk][c] = a[rk][c] * inv % MOD;
        for (int r = 0; r < n; r++) {
            if (r == rk || !a[r][col]) continue;
            long long f = a[r][col];
            for (int c = col; c < m; c++)
                a[r][c] = (a[r][c] - f * a[rk][c] % MOD + MOD) % MOD;
        }
        rk++;
    }
    return rk;
}

Solving — the three cases

Row-reduce the augmented matrix . Then:

ConditionSolutions
none (an inconsistent row with )
(number of unknowns)unique
infinitely many free variables

Over the third case gives exactly solutions — a count, not “infinitely many”. That count is what most contest problems actually ask for.

Over — the common case

XOR systems are linear systems, and the whole computation becomes bitwise:

int rankF2(vector<uint64_t> a) {                  // each row is a bitmask
    int n = a.size(), rk = 0;
    for (int col = 63; col >= 0 && rk < n; col--) {
        int piv = -1;
        for (int r = rk; r < n; r++) if (a[r] >> col & 1) { piv = r; break; }
        if (piv < 0) continue;
        swap(a[rk], a[piv]);
        for (int r = 0; r < n; r++)
            if (r != rk && (a[r] >> col & 1)) a[r] ^= a[rk];
        rk++;
    }
    return rk;
}

with 64-bit rows, or with bitset rows for wider systems. This is the XOR basis construction, viewed as Gaussian elimination.

Where rank answers the question

ProblemRank interpretation
Number of distinct subset XORs
Number of subsets with a given XOR (or 0)
Solve a system of XOR equations (light switches, Lights Out) elimination
Does a perfect matching exist?rank of the Tutte matrix
Maximum matching sizehalf the Tutte matrix rank
Dimension of a vector spacerank of a spanning set
Number of independent constraintsrank
Linear independence of vectorsrank count
Count solutions of a modular linear system
Minimum generators of a group rank

The Lights Out pattern

A grid of lights; pressing one toggles it and its neighbours; make everything off. Each cell is an variable, each light gives one equation. Solve with Gaussian elimination:

  • rank → unique solution;
  • rank solutions; enumerate the free variables to find the one with the fewest presses;
  • inconsistent → impossible.

This models a large family of “toggle” puzzles.

Numerical rank

Over the reals, “is this entry zero” is meaningless in floating point. Use the singular value decomposition and count singular values above a tolerance. In competitive programming, work over instead — exact and unambiguous.

Sparse systems

For huge sparse matrices, elimination causes fill-in and destroys sparsity. Use Wiedemann or Lanczos, which only ever compute matrix-vector products: time, space.

See also: Gaussian Elimination · Linear Basis · Determinant