FLINT3.7.0-dev
Guide · fmpz_mod_mat.h

Prime and composite moduli

Linear algebra over Z/nZ\mathbb{Z}/n\mathbb{Z} is simplest when nn is prime and Z/nZ\mathbb{Z}/n\mathbb{Z} is a field: every nonzero pivot can be inverted, and Gaussian elimination computes ranks, inverses, solutions and echelon forms. For composite nn, 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 nn is prime; the functions fall into three groups.

Functions for every modulus#

These are correct for any n≥1n \ge 1:

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 nn are large. When a pivot is a zero divisor, the generic algorithm fails, and:

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 nn 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.

Examplefmpz_mod_mat_composite.cchecked by make checkdoc
#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;
}
Output
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 x2−4x+2x^2 - 4x + 2, printed with residues in [0,15)[0, 15).

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 (Zm)s(\mathbb{Z}_m)^s", Linear and Multilinear Algebra 19 (1986), 67-77
  • [StoMul1998] Storjohann, Arne and Mulders, Thom : Fast algorithms for linear algebra modulo :math:NN : 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
Cite this page

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).