The definition has terms; Gaussian elimination computes it in .
Computing it
long long determinant(vector<vector<long long>> a, long long MOD) {
int n = a.size();
long long det = 1;
for (int i = 0; i < n; i++) {
int piv = -1;
for (int r = i; r < n; r++) if (a[r][i]) { piv = r; break; }
if (piv < 0) return 0; // singular
if (piv != i) { swap(a[piv], a[i]); det = MOD - det; } // row swap flips the sign
det = det * a[i][i] % MOD;
long long inv = powmod(a[i][i], MOD - 2, MOD);
for (int r = i + 1; r < n; r++) {
long long f = a[r][i] * inv % MOD;
if (!f) continue;
for (int c = i; c < n; c++)
a[r][c] = (a[r][c] - f * a[i][c] % MOD + MOD) % MOD;
}
}
return det;
}Row operations and the determinant:
| Operation | Effect on |
|---|---|
| Swap two rows | multiply by |
| Multiply a row by | multiply by |
| Add a multiple of one row to another | unchanged |
Only the first two need tracking, which is why elimination works.
Properties
| Property | |
|---|---|
| iff is singular | iff the rows are linearly dependent |
| of a triangular matrix | product of the diagonal |
| = product of eigenvalues | |
| of a block-triangular matrix | product of the blocks’ determinants |
Over which ring?
| Setting | Method |
|---|---|
| Modulo a prime | Gaussian elimination with inverses, |
| Modulo a composite | Euclidean row reduction (repeated subtraction, like gcd) — no inverses needed, |
| Exact integers | Bareiss — fraction-free, no coefficient blowup |
| Exact, huge | compute modulo several primes + CRT, with the Hadamard bound to know when to stop |
| Floating point | LU decomposition with partial pivoting |
| Sparse | Wiedemann, |
Composite modulus without inverses
for (int r = i + 1; r < n; r++)
while (a[r][i]) { // Euclidean-style
long long t = a[i][i] / a[r][i];
for (int c = i; c < n; c++)
a[i][c] = (a[i][c] - t * a[r][c] % MOD + MOD) % MOD;
swap(a[i], a[r]); det = MOD - det;
}— the standard trick when the modulus is not prime.
Hadamard’s bound
for entries bounded by . Tells you how many CRT primes are needed for an exact answer.
Where determinants appear
| Problem | Determinant |
|---|---|
| Count spanning trees | Matrix-Tree theorem — a Laplacian cofactor |
| Count Eulerian circuits | BEST theorem (an arborescence count × factorials) |
| Perfect matching exists (general graph) | Tutte matrix rank |
| Count perfect matchings in a planar graph | FKT algorithm — a Pfaffian, hence a determinant |
| Count perfect matchings in a bipartite graph | the permanent — p-hard, no determinant shortcut |
| Lattice point counting / volume | determinant of the basis |
| Orientation test | a or determinant |
| Circle through three points | a determinant |
| Solving | Cramer’s rule ( — use elimination instead) |
| Lindström-Gessel-Viennot | count non-intersecting lattice paths |
Lindström-Gessel-Viennot is worth flagging: the number of families of non-intersecting paths between two sets of endpoints is a determinant of the pairwise path counts. It turns several hard-looking counting problems into an computation.
Permanent — the hard cousin
— the determinant without signs. Computing it is #P-complete, and the signs are exactly what makes the determinant easy. Best known: Ryser’s formula, , which is bitmask DP in disguise.
See also: Gaussian Elimination · Rank · Matrix-Tree Theorem