fmpz_mod_mat.hPrime and composite moduli
Linear algebra over is simplest when is prime and is a field: every nonzero pivot can be inverted, and Gaussian elimination computes ranks, inverses, solutions and echelon forms. For composite , a nonzero entry may be a zero divisor, rank is no longer well defined in the usual sense, and elimination needs other algorithms. fmpz_mod_mat never tests whether is prime; the functions fall into three groups.
Functions for every modulus#
These are correct for any :
- arithmetic:
fmpz_mod_mat_add,fmpz_mod_mat_mul,fmpz_mod_mat_pow_ui, the matrix-vector products,fmpz_mod_mat_trace, and the conversions and random matrices; fmpz_mod_mat_detandfmpz_mod_mat_charpoly, which fall back to the division-free Berkowitz algorithm [Ber1984] when elimination meets a non-invertible pivot;fmpz_mod_mat_similarity, which uses no division;fmpz_mod_mat_howell_formandfmpz_mod_mat_strong_echelon_form, which compute canonical forms of the row span over with extended gcds instead of inverses [How1986; StoMul1998; FieHof2014]. The Howell form is the right replacement for the reduced row echelon form when is composite.
Functions that need a prime modulus#
The other elimination functions are wrappers of generic algorithms for fields over the fmpz_mod ring (gr_mat_lu, gr_mat_rref_lu, gr_mat_nonsingular_solve_lu, ...). For a composite modulus they give the correct result as long as every pivot they choose is invertible, which is the common case for random matrices when the prime factors of are large. When a pivot is a zero divisor, the generic algorithm fails, and:
fmpz_mod_mat_lu,fmpz_mod_mat_rank,fmpz_mod_mat_rref,fmpz_mod_mat_nullspace,fmpz_mod_mat_solve_trilandfmpz_mod_mat_solve_triuthrow an exception;fmpz_mod_mat_solve,fmpz_mod_mat_can_solveandfmpz_mod_mat_invreturn 0, as if the matrix were singular, even if it is invertible modulo (an inverse exists exactly when the determinant is a unit);fmpz_mod_mat_minpolydeclares the ring a field and may return a wrong result.
Exceptions can be caught with the mechanism of flint_set_throw, but for composite moduli it is better to use the functions of the first group, or to factor and work modulo each prime power.
Example#
The matrix below has determinant 2, a unit modulo 15, but its first pivot 3 is a zero divisor.
#include <flint/fmpz.h>
#include <flint/fmpz_mod.h>
#include <flint/fmpz_mod_mat.h>
#include <flint/fmpz_mod_poly.h>
int main(void)
{
fmpz_mod_ctx_t ctx;
fmpz_mod_mat_t A, B, H;
fmpz_mod_poly_t p;
fmpz_t d;
slong rank;
fmpz_init(d);
fmpz_mod_ctx_init_ui(ctx, 15);
fmpz_mod_mat_init(A, 2, 2, ctx);
fmpz_mod_mat_init(B, 2, 2, ctx);
fmpz_mod_poly_init(p, ctx);
/* A = [[3, 1], [1, 1]] */
fmpz_set_ui(fmpz_mod_mat_entry(A, 0, 0), 3);
fmpz_set_ui(fmpz_mod_mat_entry(A, 0, 1), 1);
fmpz_set_ui(fmpz_mod_mat_entry(A, 1, 0), 1);
fmpz_set_ui(fmpz_mod_mat_entry(A, 1, 1), 1);
/* division-free algorithms work for any modulus */
fmpz_mod_mat_det(d, A, ctx);
printf("det: "); fmpz_print(d); printf("\n");
fmpz_mod_mat_charpoly(p, A, ctx);
printf("charpoly: "); fmpz_mod_poly_print_pretty(p, "x", ctx); printf("\n");
/* elimination for fields gives up at the pivot 3 */
printf("inv: %d\n", fmpz_mod_mat_inv(B, A, ctx));
/* the Howell form works for any modulus: the rows (3, 6) and
(5, 10) generate the same module as (1, 2) */
fmpz_mod_mat_init(H, 3, 2, ctx);
fmpz_set_ui(fmpz_mod_mat_entry(H, 0, 0), 3);
fmpz_set_ui(fmpz_mod_mat_entry(H, 0, 1), 6);
fmpz_set_ui(fmpz_mod_mat_entry(H, 1, 0), 5);
fmpz_set_ui(fmpz_mod_mat_entry(H, 1, 1), 10);
rank = fmpz_mod_mat_howell_form(H, ctx);
printf("howell form, %ld nonzero rows:\n", rank);
fmpz_mod_mat_print_pretty(H, ctx);
printf("\n");
fmpz_mod_mat_clear(A, ctx);
fmpz_mod_mat_clear(B, ctx);
fmpz_mod_mat_clear(H, ctx);
fmpz_mod_poly_clear(p, ctx);
fmpz_mod_ctx_clear(ctx);
fmpz_clear(d);
return 0;
}det: 2 charpoly: x^2+11*x+2 inv: 0 howell form, 1 nonzero rows: [[1 2] [0 0] [0 0] ]
The characteristic polynomial is , printed with residues in .
References#
- [Ber1984] S. J. Berkowitz, "On computing the determinant in small parallel time using a small number of processors", Information Processing Letters 18 (1984), 147-150
- [How1986] J. A. Howell, "Spans in the module ", Linear and Multilinear Algebra 19 (1986), 67-77
- [StoMul1998] Storjohann, Arne and Mulders, Thom : Fast algorithms for linear algebra modulo :math: : Algorithms—{ESA} '98 (Venice), Lecture Notes in Comput. Sci. 1461 139–150
- [FieHof2014] Fieker C. and Hofmann T.: "Computing in quotients of rings of integers" LMS Journal of Computation and Mathematics, 17(A), 349-365
The FLINT team, “Prime and composite moduli (fmpz_mod_mat.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fmpz_mod_mat/composite.html (generated 2026-11-02).
@misc{flint-doc-fmpz-mod-mat-composite,
author = {{The FLINT team}},
title = {{Prime and composite moduli (fmpz\_mod\_mat.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/fmpz_mod_mat/composite.html},
note = {Generated 2026-11-02}
}