Computing determinants
#include <flint/fmpz_mat.h>void fmpz_mat_det(fmpz_t det, const fmpz_mat_t A)sourcevoid fmpz_mat_det_cofactor(fmpz_t det, const fmpz_mat_t A)sourcevoid fmpz_mat_det_bareiss(fmpz_t det, const fmpz_mat_t A)sourceSets det to the determinant of the square matrix ; the determinant of an empty matrix is 1. fmpz_mat_det throws if is not square and chooses a method from the dimension and the entry size; fmpz_mat_det_cofactor uses cofactor expansion and throws for dimensions above 4; fmpz_mat_det_bareiss uses fraction-free elimination. See Computing determinants.
void fmpz_mat_det_modular(fmpz_t det, const fmpz_mat_t A, int proved)sourcevoid fmpz_mat_det_modular_accelerated(fmpz_t det, const fmpz_mat_t A, int proved)sourcevoid fmpz_mat_det_modular_given_divisor(fmpz_t det, const fmpz_mat_t A, const fmpz_t d, int proved)sourceSets det to the determinant of the square matrix , computed modulo word-size primes and reconstructed by the Chinese remainder theorem. fmpz_mat_det_modular_given_divisor takes a known divisor of the determinant and only reconstructs ; fmpz_mat_det_modular_accelerated first computes such a divisor with fmpz_mat_det_divisor. If proved is 0, the result is only correct with high probability.
With proved set, primes are used until their product exceeds twice the Hadamard bound divided by . With proved 0, the iteration also stops once the reconstructed value has not changed while more than 100 bits of primes were added, which is correct with high probability but not proven. A zero determinant is detected early and certified with an exact kernel vector. See Computing determinants and Determinants.
fmpz_mat_det computes the determinant of a square integer matrix exactly. For small dimensions it uses cofactor expansion or fraction-free elimination, whose intermediate entries never exceed the size of minors of the matrix. For larger dimensions it computes the determinant modulo word-size primes, where elimination costs word operations per prime, and reconstructs it by the Chinese remainder theorem. The number of primes is governed by Hadamard's bound, unless a large divisor of the determinant is found first, in which case only the cofactor needs to be reconstructed. All results are proven unless proved is set to 0 in the modular functions.
Choice of algorithm#
For an matrix whose largest entry has bits, fmpz_mat_det chooses as follows.
| Dimension | Method |
|---|---|
fmpz_mat_det_cofactor: explicit cofactor expansion | |
fmpz_mat_det_bareiss: fraction-free elimination | |
fmpz_mat_det_modular with proved = 1 | |
| , | fmpz_mat_det_modular with proved = 1 |
| , | fmpz_mat_det_modular_accelerated with proved = 1 |
The empty matrix has determinant 1. A nonsquare matrix raises an exception in fmpz_mat_det; the other functions assume squareness.
Fraction-free elimination#
fmpz_mat_det_bareiss runs fmpz_mat_fflu with rank check on a copy of . By Sylvester's identity the -th pivot of Bareiss' algorithm is the leading minor of the row-permuted matrix, so the last pivot is , with the sign of the permutation, and all intermediate entries are minors of , bounded by Hadamard's inequality [Bar1968]. The cost is multiplications and exact divisions of integers of up to bits, about word operations with classical integer multiplication, which is why it is used only for small ; see Fraction-free elimination.
Modular computation#
fmpz_mat_det_modular_given_divisor(det, A, d, proved) computes for a known divisor of the determinant (1 in fmpz_mat_det_modular):
- =
fmpz_mat_det_bound(A)(Hadamard's bound), and the target is , rounded up. - For primes above that do not divide : reduce modulo , compute its LU decomposition with
nmod_mat_lu_with_pivots, and set . - Combine the with
fmpz_CRT_uiin the symmetric range until the product of the primes exceeds . Then is determined.
If the rank modulo some is below , the function tries to prove at once with an exact kernel vector (_fmpz_mat_certify_singular_lu_mod_p), which succeeds whenever the rank modulo equals the rank of . With proved = 0 the loop also stops when the reconstructed value has stayed the same while more than 100 bits of primes were added: the probability that a wrong value survives that many primes is negligible for nonadversarial input, but the result is not proven.
The cost is about LU decompositions modulo primes, each , plus the reduction of , reductions of -bit entries per prime. With , this is word operations for fmpz_mat_det_modular.
Large divisors#
fmpz_mat_det_modular_accelerated first calls fmpz_mat_det_divisor, which solves for a vector with entries by -adic lifting and returns the least common multiple of the denominators of . This divides the largest invariant factor of , and for random matrices it equals , which is up to a small factor [AbbottBronsteinMulders1999; Pan1988]. Only remains to be reconstructed, which typically takes one or two primes. Since the -adic solution costs about the same as primes in the purely modular method but saves primes, this pays off when the determinant is large compared with , which fmpz_mat_det estimates by . For matrices with a large Smith form cofactor , for example diagonal-dominant structured matrices, the gain disappears; see Determinants.
Related functions#
fmpz_mat_det_boundcomputes Hadamard's bound, andfmpz_mat_det_bound_submatrixa bound valid for all minors.fmpz_mat_is_singulardecides without computing the determinant, with a prime of 17 bits and an exact certificate; it is much faster thanfmpz_mat_detfor large nonsingular matrices.fmpz_mat_det_divisorreturns the divisor described above.nmod_mat_detcomputes determinants modulo , andfmpq_mat_detdeterminants of rational matrices by clearing denominators row by row.
Example#
A dense matrix with prescribed determinant , obtained from a sparse matrix by random unimodular row and column operations. All methods agree, and the Hadamard bound is far larger than the determinant. Since fmpz_mat_randdet spreads the prime factors of the determinant over many diagonal entries, the largest invariant factor, which is what fmpz_mat_det_divisor finds, is only here; for such matrices the accelerated method gains nothing.
#include <flint/flint.h>
#include <flint/fmpz.h>
#include <flint/fmpz_mat.h>
int main(void)
{
fmpz_mat_t A;
fmpz_t D, d, t;
flint_rand_t state;
slong n = 40;
flint_rand_init(state);
fmpz_init(D);
fmpz_init(d);
fmpz_init(t);
fmpz_mat_init(A, n, n);
/* D = 2^40 * 3^20 * 1000003 */
fmpz_ui_pow_ui(D, 3, 20);
fmpz_mul_2exp(D, D, 40);
fmpz_mul_ui(D, D, 1000003);
fmpz_mat_randdet(A, state, D);
fmpz_mat_randops(A, state, 2000);
flint_printf("entries up to %wd bits\n", FLINT_ABS(fmpz_mat_max_bits(A)));
fmpz_mat_det(d, A);
flint_printf("det: %{fmpz}\n", d);
flint_printf("correct: %d\n", fmpz_equal(d, D));
fmpz_mat_det_bareiss(t, A);
flint_printf("bareiss agrees: %d\n", fmpz_equal(t, D));
fmpz_mat_det_modular(t, A, 1);
flint_printf("modular agrees: %d\n", fmpz_equal(t, D));
fmpz_mat_det_modular_accelerated(t, A, 1);
flint_printf("accelerated agrees: %d\n", fmpz_equal(t, D));
fmpz_mat_det_divisor(t, A);
flint_printf("divisor: %{fmpz}\n", t);
flint_printf("divides det: %d\n", fmpz_divisible(D, t));
fmpz_mat_det_bound(t, A);
flint_printf("bits of det %wd, of Hadamard bound %wd\n",
fmpz_bits(D), fmpz_bits(t));
fmpz_mat_clear(A);
fmpz_clear(D);
fmpz_clear(d);
fmpz_clear(t);
flint_rand_clear(state);
return 0;
}entries up to 47 bits det: 3833771493727452464601366528 correct: 1 bareiss agrees: 1 modular agrees: 1 accelerated agrees: 1 divisor: 36000108 divides det: 1 bits of det 92, of Hadamard bound 1865
Guides#
References#
- [Bar1968] E. H. Bareiss, "Sylvester's identity and multistep integer-preserving Gaussian elimination", Mathematics of Computation 22 (1968), 565–578. https://doi.org/10.1090/S0025-5718-1968-0226829-0
- [AbbottBronsteinMulders1999] Fast deterministic computation of determinants of dense matrices, ACM International Symposium on Symbolic and Algebraic Computation (1999)
- [Pan1988] V. Pan, "Computing the determinant and the characteristic polynomial of a matrix via solving linear systems of equations", Information Processing Letters 28:2 (1988), 71–75. https://doi.org/10.1016/0020-0190(88)90166-4
The FLINT team, “Computing determinants (fmpz_mat.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fmpz_mat/det.html (generated 2026-11-02).
@misc{flint-doc-fmpz-mat-det,
author = {{The FLINT team}},
title = {{Computing determinants (fmpz\_mat.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/fmpz_mat/det.html},
note = {Generated 2026-11-02}
}