fmpz_poly_factor.h
#include <flint/fmpz_poly_factor.h>This module factors polynomials in \mathbb{Z}[x] into irreducible factors. A factorisation is stored as an fmpz_poly_factor_t: a signed content c together with distinct primitive irreducible factors f_i of positive degree and positive leading coefficient, and multiplicities e_i, so that f = c \prod_i f_i^{e_i}. The main function is fmpz_poly_factor, which lifts a factorisation modulo a small prime p-adically and recombines the modular factors by the Zassenhaus algorithm when there are few and by van Hoeij's lattice reduction algorithm when there are many. The guide Factoring polynomials over the integers shows how to use it, and Factoring polynomials over the integers describes the algorithms.
Types and memory management#
A factorisation c \prod_{i < \mathit{num}} p_i^{e_i}, with fields c (an fmpz, the constant factor), p (an array of alloc polynomials, of which the first num are used), exp (the multiplicities) and num, alloc. An fmpz_poly_factor_t is an array of one structure. A freshly initialised structure represents the empty product, with c = 1.
void fmpz_poly_factor_init(fmpz_poly_factor_t fac)void fmpz_poly_factor_init2(fmpz_poly_factor_t fac, slong alloc)Initialise fac as the empty factorisation with c = 1, allocating nothing, respectively room for alloc factors.
void fmpz_poly_factor_realloc(fmpz_poly_factor_t fac, slong alloc)Changes the allocated space to exactly alloc factors; for alloc = 0 the structure is cleared and reinitialised. The number of factors is not adjusted, so alloc should be at least fac->num.
void fmpz_poly_factor_fit_length(fmpz_poly_factor_t fac, slong len)Ensures that fac has room for at least len factors, growing the allocation to at least twice its old size if it has to grow.
void fmpz_poly_factor_clear(fmpz_poly_factor_t fac)Frees the memory used by fac.
Manipulating factorisations#
void fmpz_poly_factor_set(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac)Sets res to a copy of fac.
void fmpz_poly_factor_insert(fmpz_poly_factor_t fac, const fmpz_poly_t p, slong e)Multiplies the factorisation by p^e: if p is equal to one of the stored factors, its multiplicity is increased by e, otherwise p is appended with multiplicity e. The content is not changed. Meant for primitive p of positive degree and e \ne 0, which is not checked.
void fmpz_poly_factor_concat(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac)Multiplies res by the factorisation fac: the contents are multiplied and the factors of fac are inserted with fmpz_poly_factor_insert. res and fac must be distinct.
void fmpz_poly_factor_get_fmpz(fmpz_t z, const fmpz_poly_factor_t F)void fmpz_poly_factor_get_fmpz_poly(fmpz_poly_t z, const fmpz_poly_factor_t F, slong i)Set z to the constant factor c of F, respectively to the factor with index i, which must satisfy 0 \le i < F->num.
void fmpz_poly_factor_print(const fmpz_poly_factor_t fac)Prints the content on one line, then each factor in the plain format of fmpz_poly_print followed by ^ and its multiplicity, one per line.
Factoring#
void fmpz_poly_factor(fmpz_poly_factor_t fac, const fmpz_poly_t G)Sets fac to the factorisation of G into its signed content and irreducible primitive factors with positive leading coefficient and their multiplicities. The zero polynomial gives content 0 and no factors, a constant c gives content c and no factors. fac must be initialised; its previous factors are discarded. The factors are not sorted.
void fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t fac, const fmpz_poly_t G)Factors G like fmpz_poly_factor, but without deflation and using only the Zassenhaus recombination. Its running time is exponential in the number of modular factors, so it is meant for comparison and testing. fac should be freshly initialised, since the factors are appended to those already present.
void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, const fmpz_poly_t F)Sets the content of fac to the signed content c of F (with the sign of the leading coefficient) and appends squarefree, pairwise coprime, primitive factors g_i of positive degree with distinct multiplicities e_i, so that F = c \prod_i g_i^{e_i} with \gcd(g_i, g_i') = 1. Each g_i is the product of all irreducible factors of F of multiplicity e_i. Uses Yun's algorithm [Yun1976] (Squarefree factorisation). fac should be freshly initialised.
void _fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, slong exp, const fmpz_poly_t f, slong cutoff, int use_van_hoeij)Appends the irreducible factors of the squarefree, primitive polynomial f of length at least 2 with nonzero constant coefficient and positive leading coefficient, each with multiplicity exp, to final_fac; none of the conditions is checked.
void fmpz_poly_factor_van_hoeij(fmpz_poly_factor_t final_fac, const nmod_poly_factor_t fac, const fmpz_poly_t f, slong exp, ulong p)Appends the irreducible factors of the squarefree primitive f, each with multiplicity exp, to final_fac, given its factorisation fac into r \ge 2 monic irreducible factors modulo the prime p, by van Hoeij's knapsack algorithm with gradual feeding of CLD data [vHo2002], [HvHN2011]. The modular factors are lifted to an initial precision, a lattice is reduced with LLL after each new column of CLD data, and the precision is doubled until a 0-1 basis of the recombination lattice is found and verified.
void _fmpz_poly_factor_quadratic(fmpz_poly_factor_t fac, const fmpz_poly_t f, slong exp)void _fmpz_poly_factor_cubic(fmpz_poly_factor_t fac, const fmpz_poly_t f, slong exp)Insert the factorisation of the primitive quadratic (respectively cubic) polynomial f into fac, with multiplicity exp, without changing the content of fac. A quadratic splits if and only if its discriminant is a square; a cubic is reducible if and only if it has a rational root, which is located from real and 2-adic approximations of the roots and tested over \mathbb{Z} (Cubics). The content of f must be 1, which is not checked.
void fmpz_poly_factor_mignotte(fmpz_t B, const fmpz_poly_t f)Sets B to a bound for the absolute values of the coefficients of all factors in \mathbb{Z}[x] of f of degree m \ge 2: the maximum of |f(0)|, |\operatorname{lc}(f)| and of \binom{m-1}{j} N + \binom{m-1}{j-1} |\operatorname{lc}(f)| for 1 \le j < m, where N \ge \|f\|_2 is an integer [Coh1996, Theorem 3.5.1]. The Zassenhaus algorithm lifts to p^a > 2 |\operatorname{lc}(f)| B.
Irreducibility of inflations#
int _fmpz_poly_factor_inflation_is_irreducible_capelli(const fmpz_poly_t T, ulong p)Given T irreducible over \mathbb{Q} of degree at least 1 and a prime p, attempts to prove that T(x^p) is irreducible over \mathbb{Q}. Returns 1 if a proof was found and 0 if the search was inconclusive, in which case T(x^p) may still be irreducible. The behaviour is undefined if T is reducible. T need not be primitive and may have negative leading coefficient.
Moreint fmpz_poly_factor_inflation_is_irreducible_capelli(const fmpz_poly_t T, ulong d)Given T irreducible over \mathbb{Q} of degree at least 1 and d \ge 1, returns 1 if T(x^d) is proved irreducible over \mathbb{Q} and 0 if the attempt was inconclusive. The prime-step certificate is chained over the prime factorisation of d, using T(x^d) = U(x^{d/p}) with U = T(x^p). The behaviour is undefined if T is reducible. fmpz_poly_factor uses this to avoid refactoring inflations of irreducible factors of deflated polynomials.
Recombination#
void fmpz_poly_factor_zassenhaus_recombination(fmpz_poly_factor_t final_fac, const fmpz_poly_factor_t lifted_fac, const fmpz_poly_t F, const fmpz_t P, slong exp)void fmpz_poly_factor_zassenhaus_recombination_with_prune(fmpz_poly_factor_t final_fac, const fmpz_poly_factor_t lifted_fac, const fmpz_poly_t F, const fmpz_t P, slong exp, const zassenhaus_prune_t Z)Find the irreducible factors of the squarefree primitive F from its monic factors lifted_fac modulo P = p^a, where P > 2 |\operatorname{lc}(F)| B for the Mignotte bound B, by trying subsets of the modular factors in order of increasing size: for each subset S, the product \operatorname{lc}(F) \prod_{i \in S} g_i is reduced into the symmetric range modulo P, its primitive part is tested as a divisor of F, and true factors are removed together with their modular factors. Each factor is appended to final_fac with multiplicity exp. The with_prune version skips subsets whose total degree is impossible according to Z.
slong _fmpz_poly_factor_CLD_mat(fmpz_mat_t res, const fmpz_poly_t f, fmpz_poly_factor_t lifted_fac, fmpz_t P, ulong k)Fills the (r + 1) \times 2k matrix res with the CLD data of van Hoeij's algorithm for the r lifted factors g_i of f modulo P: row i holds low and high coefficients of f g_i' / g_i modulo P in the symmetric range, and row r the corresponding bounds from fmpz_poly_CLD_bound. Of the low k and high k coefficients, only those whose bound times \sqrt{\deg f} is small enough compared to P are used; the function returns the number of columns filled, low ones first.
int fmpz_poly_factor_van_hoeij_check_if_solved(fmpz_mat_t M, fmpz_poly_factor_t final_fac, fmpz_poly_factor_t lifted_fac, const fmpz_poly_t f, fmpz_t P, slong exp, fmpz_t lc)Checks whether the reduced lattice basis M of van Hoeij's algorithm determines the factorisation: if the first r columns of M define a partition of the r lifted factors (a 0-1 basis), the products of the factors in each part (times lc, reduced modulo P, made primitive) are tested as divisors of f, first modulo 2 and then over \mathbb{Z}. If all of them divide, the factors are appended to final_fac with multiplicity exp and 1 is returned; otherwise 0 is returned and final_fac is unchanged.
Internal functions#
These functions support the Zassenhaus recombination. A subset of the r modular factors is encoded in an array s of length r whose entries are factor indices i \ge 0 for the factors in the subset and -i - 1 for the others.
void zassenhaus_subset_first(slong * s, slong r, slong m)Sets s to the first subset of size m of its r entries, the first m entries.
int zassenhaus_subset_next(slong * s, slong r)Advances s to the next subset of the same size in a fixed order and returns 1, or returns 0 if it was the last.
Removes the entries of the current subset from s, moving the remaining entries to the front, and sets it to the next subset of the same size m of the remaining entries, returning 1, or returns 0 if there is none.
Records the degrees d for which a factor of degree d is still possible, given the degrees of the modular factors modulo several primes: a true factor of degree d is a product of modular factors of total degree d modulo every prime.
Initialise and free Z.
void zassenhaus_prune_set_degree(zassenhaus_prune_t Z, slong d)Sets the degree of the polynomial to be factored to d \ge 1 and marks all degrees 0, \ldots, d as possible.
void zassenhaus_prune_add_factor(zassenhaus_prune_t Z, slong deg, slong exp)Add the degrees of the modular factors for one prime: after zassenhaus_prune_start_add_factors, each call to zassenhaus_prune_add_factor records exp factors of degree deg, and zassenhaus_prune_end_add_factors intersects the set of possible degrees with the set of subset sums of the recorded degrees. The degrees must add up to the degree given to zassenhaus_prune_set_degree; otherwise an exception is raised.
int zassenhaus_prune_degree_is_possible(const zassenhaus_prune_t Z, slong d)Returns whether a factor of degree d is still possible.
int zassenhaus_prune_must_be_irreducible(const zassenhaus_prune_t Z)Returns whether no degree strictly between 0 and the degree of the polynomial is possible, which proves the polynomial irreducible.
References#
- [Yun1976] D. Y. Y. Yun. On square-free decomposition algorithms. Proceedings of the 1976 ACM Symposium on Symbolic and Algebraic Computation (SYMSAC '76), 26–35. https://doi.org/10.1145/800205.806320
- [vHo2002] M. van Hoeij. Factoring polynomials and the knapsack problem. Journal of Number Theory 95 (2002), 167–189. https://doi.org/10.1006/jnth.2001.2763
- [HvHN2011] W. Hart, M. van Hoeij and A. Novocin. Practical polynomial factoring in polynomial time. ISSAC 2011, 163–170. https://doi.org/10.1145/1993886.1993915
- [Coh1996] Cohen, Henri : A course in computational algebraic number theory, Springer, 1996
The FLINT team, “fmpz_poly_factor.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fmpz_poly_factor/index.html (generated 2026-10-20).
@misc{flint-doc-fmpz-poly-factor-index,
author = {{The FLINT team}},
title = {{fmpz\_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/fmpz_poly_factor/index.html},
note = {Generated 2026-10-20}
}