nmod_poly_factor.h
#include <flint/nmod_poly_factor.h>This module factors polynomials over the prime field , , represented as nmod_poly_t, tests them for irreducibility and squarefreeness, and finds their roots, over and also over for composite with known factorisation. A factorisation is stored in an nmod_poly_factor_t, a list of polynomials with exponents.
The factorisation, irreducibility and root-finding functions are thin wrappers around the generic finite-field implementations in gr_poly (gr_poly_factor_finite_field, gr_poly_is_irreducible, gr_poly_roots_finite_field and the functions they call), which view the nmod_poly_t as a gr_poly_t over the nmod context without copying it. A complete factorisation consists of a squarefree factorisation followed, for each squarefree part, by either the Cantor–Zassenhaus algorithm with classical distinct-degree factorisation (small degrees and small ) or the Kaltofen–Shoup algorithm with baby-step giant-step distinct-degree factorisation and modular composition; Berlekamp's algorithm is available on request. The guide Factoring polynomials over a prime field explains the choices and their costs with examples, and the algorithms are described in detail in:
gr_poly chooses between them.AlgorithmRoots of polynomials over finite fieldsRoots in by squarefree factorisation, the split and random shifts, with powers of computed through Taylor shifts; roots modulo prime powers by Hensel lifting of all roots, and modulo composite by the Chinese remainder theorem.Types and conventions#
A polynomial in factored form. The structure has the fields p (an array of alloc polynomials, of which the first num are used), exp (an array of alloc exponents of type slong), num and alloc. Entry for stands for the factor . An nmod_poly_factor_t is an array of one nmod_poly_factor_struct, so it is passed by reference.
- The factorisation, irreducibility, squarefreeness and root-finding functions require the modulus to be prime, except
nmod_poly_roots_factored. This is not checked: a composite modulus gives wrong results or an exception. - The factors computed by this module are monic.
nmod_poly_factorand its variants return the leading coefficient of the input separately. - The factors are stored in no particular order. The algorithms are randomised, but every function seeds its own random state with a fixed value, so the output is reproducible.
- Most functions overwrite the output factorisation, but
nmod_poly_factor_cantor_zassenhaus,nmod_poly_factor_berlekamp,nmod_poly_factor_kaltofen_shoup,nmod_poly_factor_distinct_degandnmod_poly_factor_equal_degappend to it; each function says which. - Distinct-degree and equal-degree factorisation of polynomials of degree above about 200 use several threads when they have been made available with
flint_set_num_threads.
Memory management#
void nmod_poly_factor_init(nmod_poly_factor_t fac)Initialises fac as the empty factorisation (), with space for 5 factors.
void nmod_poly_factor_clear(nmod_poly_factor_t fac)Frees the memory used by fac, including all allocated polynomials.
void nmod_poly_factor_realloc(nmod_poly_factor_t fac, slong alloc)Changes the space of fac to exactly alloc factors. For alloc = 0 the factorisation is cleared and reinitialised (with space for 5 factors and ). If alloc is smaller than the number of factors, the factors beyond the first alloc are discarded.
void nmod_poly_factor_fit_length(nmod_poly_factor_t fac, slong len)Ensures that fac has space for at least len factors. If it has to grow, it grows to at least twice its previous allocation.
Swaps a and b efficiently.
Basic manipulation#
void nmod_poly_factor_set(nmod_poly_factor_t res, const nmod_poly_factor_t fac)Sets res to a copy of fac, including the moduli of the factors.
void nmod_poly_factor_get_poly(nmod_poly_t a, const nmod_poly_factor_t b, slong i)Sets a to the factor b->p[i], for . The exponent is b->exp[i].
void nmod_poly_factor_insert(nmod_poly_factor_t fac, const nmod_poly_t poly, slong exp)Multiplies the factorisation by : if poly is equal to one of the factors, exp is added to its exponent, otherwise a copy of poly is appended with exponent exp. Constant polynomials are ignored. The search is linear in the number of factors.
void nmod_poly_factor_concat(nmod_poly_factor_t res, const nmod_poly_factor_t fac)Multiplies res by the factorisation fac, by inserting each factor of fac with nmod_poly_factor_insert. res and fac must be distinct objects.
void nmod_poly_factor_pow(nmod_poly_factor_t fac, slong exp)Multiplies every exponent of fac by exp, which raises the factored polynomial to the power exp.
Input and output#
void nmod_poly_factor_print(const nmod_poly_factor_t fac)void nmod_poly_factor_print_pretty(const nmod_poly_factor_t fac, const char * var)Print the factors to standard output, one per line, as the polynomial followed by ^ and the exponent. nmod_poly_factor_print writes the polynomials in the format of nmod_poly_print, and nmod_poly_factor_print_pretty in the format of nmod_poly_print_pretty with the variable name var.
Factorisation#
ulong nmod_poly_factor(nmod_poly_factor_t result, const nmod_poly_t input)Sets result to the factorisation of input into monic irreducible polynomials over and returns the leading coefficient of input, so that input equals the leading coefficient times the product of the factors raised to their exponents. A constant input gives the empty factorisation and returns the constant (0 for the zero polynomial).
ulong nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t result, const nmod_poly_t input)ulong nmod_poly_factor_with_berlekamp(nmod_poly_factor_t result, const nmod_poly_t input)ulong nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t result, const nmod_poly_t input)Like nmod_poly_factor, but split the squarefree factors with the Cantor–Zassenhaus algorithm, Berlekamp's algorithm or the Kaltofen–Shoup algorithm respectively. Deflation is still applied.
void nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res, const nmod_poly_t f)void nmod_poly_factor_berlekamp(nmod_poly_factor_t res, const nmod_poly_t f)void nmod_poly_factor_kaltofen_shoup(nmod_poly_factor_t res, const nmod_poly_t f)Append the factorisation of f into monic irreducible polynomials, with exponents, to res, using the Cantor–Zassenhaus algorithm, Berlekamp's algorithm or the Kaltofen–Shoup algorithm (with deflation, as in nmod_poly_factor). The leading coefficient of f is discarded; nothing is appended for a constant f.
void nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f)Sets res to the squarefree factorisation of f: monic squarefree polynomials , pairwise coprime and with distinct exponents , such that with the leading coefficient of . A constant f gives the empty factorisation.
void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res, const nmod_poly_t poly, slong * const * degs)void nmod_poly_factor_distinct_deg_threaded(nmod_poly_factor_t res, const nmod_poly_t poly, slong * const * degs)Distinct-degree factorisation of a squarefree polynomial poly of degree at least 1, which need not be monic. Appends to res monic polynomials , each with exponent 1, such that is the product of all monic irreducible factors of poly of one degree , and writes to (*degs)[j - 1]. The array *degs must have room for entries; the are distinct but not sorted. If poly is not squarefree the output is meaningless.
void nmod_poly_factor_equal_deg(nmod_poly_factor_t factors, const nmod_poly_t pol, slong d)Equal-degree factorisation: pol must be squarefree and a product of irreducible polynomials of degree , and must divide . Appends the monic irreducible factors of pol, each with exponent 1, to factors.
Irreducibility and squarefreeness#
int nmod_poly_is_irreducible(const nmod_poly_t f)Returns whether f is irreducible over . As a special case, constant polynomials, including zero, are considered irreducible (unlike gr_poly_is_irreducible, which returns false for them).
int nmod_poly_is_irreducible_ddf(const nmod_poly_t f)Returns whether f is irreducible, by the coarse phase of the baby-step giant-step distinct-degree factorisation: after a squarefreeness test, is irreducible if and only if it has no factor of degree at most . Constants are considered irreducible. This is gr_poly_is_irreducible_ddf; it stops at the first interval of degrees that contains a factor.
int nmod_poly_is_irreducible_rabin(const nmod_poly_t f)int _nmod_poly_is_squarefree(nn_srcptr f, slong len, nmod_t mod)int nmod_poly_is_squarefree(const nmod_poly_t f)Return whether f (given as (f, len) in the underscore version, with any ) is squarefree, by testing whether ; if and , then is a -th power and not squarefree. Nonzero constants are squarefree; as a special case, the zero polynomial is not.
Roots#
void nmod_poly_roots(nmod_poly_factor_t r, const nmod_poly_t f, int with_multiplicity)Sets r to the linear factors for the distinct roots of the nonzero polynomial f. If with_multiplicity is nonzero, the exponent of is the multiplicity of as a root of f, otherwise it is 1. The modulus must be prime. A zero f causes an exception.
int nmod_poly_roots_factored(nmod_poly_factor_t r, const nmod_poly_t f, int with_multiplicity, const n_factor_t * n)Sets r to the linear factors for the distinct roots of the nonzero polynomial f, where n holds the prime factorisation of the modulus of f (not checked). If with_multiplicity is nonzero, the exponent of is the largest such that divides in , otherwise it is
- Returns 1 on success and 0 if the roots were not computed because there are too many of them (more than about , or on 32-bit systems). A zero
fcauses an exception.
References#
- [Rab1980b] M. O. Rabin. Probabilistic algorithms in finite fields. SIAM Journal on Computing 9 (1980), 273–280.
The FLINT team, “nmod_poly_factor.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/nmod_poly_factor/index.html (generated 2026-11-02).
@misc{flint-doc-nmod-poly-factor-index,
author = {{The FLINT team}},
title = {{nmod\_poly\_factor.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/nmod_poly_factor/index.html},
note = {Generated 2026-11-02}
}