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:
| Condition | Solutions |
|---|---|
| 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
| Problem | Rank 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 size | half the Tutte matrix rank |
| Dimension of a vector space | rank of a spanning set |
| Number of independent constraints | rank |
| Linear independence of vectors | rank 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