FLINT3.7.0-dev
Module · 98 functions

nmod_mpoly_factor.h

#include <flint/nmod_mpoly_factor.h>

This module factors polynomials of nmod_mpoly.h over a prime field \mathbb{F}_p with word-size p. A factorisation is stored in an nmod_mpoly_factor_t as a constant times a product of powers of polynomials. nmod_mpoly_factor computes the irreducible factorisation, nmod_mpoly_factor_squarefree a squarefree one; the content of a polynomial with respect to each variable is split off first, and in characteristic p the squarefree decomposition also extracts p-th powers, which over a prime field are obtained by dividing exponents by p.

The irreducible factors of a squarefree polynomial are found by evaluating all variables but two at random points, factoring the bivariate image (by Hensel lifting and linear-algebra recombination of a univariate factorisation), and lifting the bivariate factors back one variable at a time, either by Wang's leading coefficient method with Hensel lifting [Wan1978], by sparse Hensel lifting in the style of Zippel and of Monagan and Tuncer [MonTun2020], or by Zassenhaus-style recombination [Zas1969]. When \mathbb{F}_p is too small to supply good evaluation points, the same algorithms run over extension fields \mathbb{F}_{p^k}, and the factors found there are combined into factors over \mathbb{F}_p along their orbits under the Frobenius automorphism; see Factoring over finite fields, and Multivariate Hensel lifting for the lifting steps.

AlgorithmFactoring over finite fieldsThe multivariate factorisation pipeline of nmod_mpoly_factor and fq_nmod_mpoly_factor, with what is specific to characteristic p: separable factorisation with p-th roots, deflation by powers of p, factoring over extension fields with recombination of Frobenius orbits when the field is too small for good evaluation points, quadratic equations in characteristic 2, bivariate factorisation with recombination by linear algebra, and Wang's leading coefficients along random curves.

The factorisation functions are described in detail in Factorisation.

Types and memory management#

A factorisation c \prod_{i=0}^{k-1} f_i^{e_i} of a polynomial over \mathbb{F}_p, with the fields constant (c, a ulong), poly (the bases f_i, an array of nmod_mpoly_struct), exp (the exponents e_i, an array of fmpz), num (k) and alloc. All bases belong to the context passed with the factorisation.

Initialise f as the empty product with constant 1; nmod_mpoly_factor_init2 also allocates space for alloc factors.

Frees the memory used by f.

Change the allocation of f to alloc factors (truncating the product if it is longer), or ensure space for at least len factors.

Basic manipulation#

Swap f and g efficiently, and set f to a copy of g.

Sets f to the empty product with constant 1.

Return the number k of factors and the constant c of f.

Set p to the base f_i of index i, or swap p with it, where 0 \le i < k.

Returns the exponent e_i of index i, which must fit an slong.

Append the factor A^e to f, copying A.

nmod_mpoly_factor_expand sets A to the product c \prod_i f_i^{e_i} and returns 1, or returns 0 if an exponent is negative or a power is too large to compute. nmod_mpoly_factor_matches returns whether f expands to a.

Sorts the factors of f by increasing exponent, and factors with equal exponents by nmod_mpoly_cmp.

Compares two factorisations, first by constant, then by number of factors, then factor by factor (exponent, then base by nmod_mpoly_cmp). Returns -1, 0 or 1. Factorisations of the same polynomial compare equal after nmod_mpoly_factor_sort.

void nmod_mpoly_factor_print_pretty(const nmod_mpoly_factor_t f, const char ** vars, const nmod_mpoly_ctx_t ctx)

Prints f as the constant followed by one line *(base)^exp per factor, with the variable names vars.

Factorisation#

These functions assume that the modulus is prime, which is not checked. They set f to a factorisation of A, independently of the initial value of f, and return 1 for success. They return 0 (leaving f undefined) only if the exponents of A need more than one word per field after the content has been removed, or an algorithm runs out of evaluation points or extension fields, which does not happen for inputs of practical size. In the result, the constant is the leading coefficient of A and the bases are monic. A zero polynomial gives the constant 0 and no factors.

Sets f to a factorisation of A whose bases are variables and polynomials that are primitive with respect to every variable, that is, have no factor independent of some variable that they involve. This is the first step of the other functions.

Full documentation

Sets f to a factorisation of A whose bases are squarefree and pairwise coprime. Bases with equal exponents are not multiplied together; to get the product of all irreducible factors of a given multiplicity, sort with nmod_mpoly_factor_sort and multiply the bases with that exponent.

Full documentation

With sep = 0 this is nmod_mpoly_factor_squarefree. With sep = 1, each base g in addition satisfies, for every variable x_i, either \partial g/\partial x_i = 0 or \gcd(g, \partial g/\partial x_i) = 1, with \partial g/\partial x_i \ne 0 for at least one i; this is the form required by the irreducible factorisation.

Full documentation

Sets f to the factorisation of A into irreducible factors over \mathbb{F}_p: the bases are monic, irreducible and pairwise distinct.

Full documentation
int nmod_mpoly_factor_algo(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, unsigned int algo)

As nmod_mpoly_factor, but lifting the bivariate factorisation with only one method: Zassenhaus-style recombination after lifting a univariate factorisation, Wang's leading coefficient method with dense Hensel lifting, or sparse Hensel lifting. nmod_mpoly_factor_algo takes a bit mask algo of MPOLY_FACTOR_USE_ZAS, MPOLY_FACTOR_USE_WANG, MPOLY_FACTOR_USE_ZIP (or MPOLY_FACTOR_USE_ALL). Polynomials in one or two variables are always factored by the univariate and bivariate algorithms.

Full documentation

Internal functions#

These functions are used by the factoring algorithms and by the GCD algorithms of nmod_mpoly. Their interfaces may change without notice.

Conversions and vectors#

void nmod_mpoly_get_bpoly(n_bpoly_t A, const nmod_mpoly_t B, slong var0, slong var1, const nmod_mpoly_ctx_t ctx)

Convert between B, a polynomial in the variables of indices var0 and var1 only, and the dense bivariate n_bpoly_t A in which var0 is the main (outer) variable; nmod_mpoly_set_bpoly produces exponents of Abits bits.

Convert between a polynomial in the variables varx and vary and an n_polyun_t with exponents in varx and n_poly_t coefficients in vary.

_nmod_mpoly_get_lead0 sets c to the leading coefficient of A viewed as a polynomial in variable 0 (a polynomial in the other variables). _nmod_mpoly_set_lead0 sets A to B with that leading coefficient replaced by c.

A vector of nmod_mpoly_t, with the fields coeffs, alloc and length.

void nmod_mpolyv_print_pretty(const nmod_mpolyv_t poly, const char ** x, const nmod_mpoly_ctx_t ctx)

Memory management of vectors; nmod_mpolyv_set_coeff swaps c into position i, extending the vector with zeros.

Convert between B and the vector of its coefficients in the expansion B = \sum_i A_i\, \mathit{xalpha}^i in powers of xalpha, which is of the form x_j - \alpha; the coefficients do not involve x_j. nmod_mpoly_from_mpolyv produces exponents of Abits bits.

The GCD of the Alen polynomials A (returning 1 for success), and exact division or multiplication of all of them by c.

void _n_poly_vec_mod_mul_poly(n_poly_struct * A, slong Alen, const n_poly_t g, const nmod_t ctx)

Operations on vectors of univariate polynomials: maximum degree, multiplication by an invertible scalar or by g, exact division by g, the monic GCD g of the entries, and division by it.

Apply the compression M (computed by mpoly_compression_set, see mpoly.h) to the terms Acoeffs of length Alen, giving L in the context Lctx with fewer variables, and undo it, giving A with Abits exponent bits. A compression is an invertible monomial change of variables that removes unused variables and redundancy in the exponents.

void nmod_mpolyu3_print_pretty(const nmod_mpolyu_t A, const char * var0, const char * var1, const char * var2, const char ** vars, const nmod_mpoly_ctx_t ctx)

Check an nmod_mpolyu_t, and print one whose exponents pack three main variables with the names var0, var1, var2.

Bivariate factorisation#

int n_bpoly_mod_factor_smprime(n_poly_t c, n_tpoly_t F, n_bpoly_t B, int allow_shift, nmod_t ctx)

Factors the bivariate polynomial B in x (main variable) and y, which must be separable in x: sets c to its content with respect to x and F to its irreducible factors. Evaluates y = \alpha for \alpha \in \mathbb{F}_p (only \alpha = 0 if allow_shift is zero), factors the univariate image, lifts the factors y-adically by Hensel lifting and recombines them with the linear algebra on logarithmic derivatives of Lecerf [Lec2006] (Bivariate factorisation). Returns 0 if no suitable \alpha exists in \mathbb{F}_p. B is destroyed.

As n_bpoly_mod_factor_smprime, but reduces y modulo irreducible polynomials m(y) of increasing degree, factors the image over \mathbb{F}_p[y]/(m) \cong \mathbb{F}_{p^d}, lifts m-adically and recombines. Always succeeds.

Helpers of the recombination: nmod_mat_is_reduced returns whether every column of N contains exactly one nonzero entry, equal to 1, so that the rows describe a partition of the local factors. nmod_mat_init_nullspace_tr initialises X to a matrix whose rows are a basis of the right nullspace of tmp (which is destroyed).

int n_bpoly_mod_pfrac(slong r, n_bpoly_struct * C, slong * C_deg1_bound, n_bpoly_t A, n_bpoly_struct * B, nmod_t mod)
int n_polyu3_mod_hlift(slong r, n_polyun_struct * BB, n_polyu_t A, n_polyu_struct * B, ulong beta, slong degree_inner, nmod_t ctx)

Hensel lifting of a factorisation of a bivariate (or, for n_polyu3_mod_hlift, trivariate) polynomial A modulo y - \alpha to a factorisation modulo (y - \alpha)^{d} with d = degree_inner + 1, for two factors B0, B1 or r factors B; the cubic versions evaluate and interpolate in the other variable. n_bpoly_mod_pfrac solves the corresponding partial fraction equation. They return 1 for success and 0 if the lifted factors do not multiply to A.

Multivariate lifting#

Precomputed data for solving the multivariate partial fraction equations \sum_i \delta_i \prod_{j \ne i} \beta_j = t during Hensel lifting.

int nmod_mpoly_pfrac_init(nmod_mpoly_pfrac_t Iv, flint_bitcnt_t bits, slong l, slong r, const nmod_mpoly_struct * betas, const ulong * alpha, const nmod_mpoly_ctx_t ctx)

nmod_mpoly_pfrac_init prepares Iv for the r factors betas in l + 1 variables with the evaluation points alpha, and returns 0 if the factors are not pairwise coprime at the evaluation points. nmod_mpoly_pfrac solves the equation for the right-hand side t in the first r + 1 variables with degree bounds deg, returning 1 for success.

int nmod_mpoly_hlift(slong m, nmod_mpoly_struct * f, slong r, const ulong * alpha, const nmod_mpoly_t A, const slong * degs, const nmod_mpoly_ctx_t ctx)
int nmod_mpoly_hlift_zippel(slong m, nmod_mpoly_struct * B, slong r, const ulong * alpha, const nmod_mpoly_t A, const slong * degs, const nmod_mpoly_ctx_t ctx, flint_rand_t state)

Given factors f[0], ..., f[r-1] with A = \prod_i f_i modulo x_m - \alpha_{m-1} and degree bounds degs, lift them to a factorisation of A in the variables x_0, \ldots, x_m: by dense Hensel lifting, or by sparse interpolation of the lifted coefficients. Return 1 for success.

int nmod_mpoly_factor_lcc_wang(nmod_mpoly_struct * lc_divs, const nmod_mpoly_factor_t lcAfac, const n_poly_t Auc, const n_bpoly_struct * Auf, slong r, const n_poly_struct * alpha, const nmod_mpoly_ctx_t ctx)

Wang's leading coefficient distribution [Wan1978] along a curve: given the factorisation lcAfac of the leading coefficient of A, and the content Auc \in \mathbb{F}_p[Y] and the r factors Auf of the bivariate image of A under the substitution of the polynomials alpha[i] \in \mathbb{F}_p[Y] for the variables other than the main one, sets lc_divs to the true leading coefficients of the factors (up to constants) (Leading coefficients over a finite field). Returns 1 for success and 0 if the curve is unlucky.

Set fac (or Af) to the irreducible factors of the monic squarefree A in lexicographic order with at least three variables, given for the Wang and Zippel methods the factorisation lcAfac of the leading coefficient lcA in variable 0. The smprime versions use evaluation points in \mathbb{F}_p; the medprime versions map A to \mathbb{F}_{p^k} represented by fq_zech (with p^k \le 10^6), factor there and combine Frobenius-conjugate factors; the lgprime versions do the same with fq_nmod and no bound on k. Return 1 for success, 0 if they ran out of evaluation points or extension degrees, and -1 for a failure that other evaluation points would not fix (for example exponents that do not fit one word).

As nmod_mpoly_factor_separable for a monic A whose content has been removed.

int _nmod_mpoly_evaluate_rest_n_poly(n_poly_struct * E, slong * starts, slong * ends, slong * stops, ulong * es, const ulong * Acoeffs, const ulong * Aexps, slong Alen, slong var, const n_poly_struct * alphas, const slong * offsets, const slong * shifts, slong N, ulong mask, slong nvars, nmod_t ctx)

Evaluate all variables after the first one or two at given points (or at given univariate polynomials), giving univariate or bivariate images; and set A from a bivariate polynomial in variable 0 and var.

Sparse interpolation#

int nmod_mpolyl_gcds_zippel(nmod_mpoly_t G, const ulong * Gmarks, slong Gmarkslen, nmod_mpoly_t A, nmod_mpoly_t B, slong *perm, slong l, slong var, const nmod_mpoly_ctx_t ctx, flint_rand_t state, slong * Gdegbound, n_poly_t Amarks, n_poly_t Bmarks)

Zippel's GCD algorithm in a lexicographic context, as used by the factoring code: gcdp interpolates the variables up to var with points in \mathbb{F}_p, gcds solves for the coefficients of the assumed monomial structure G (marked by Gmarks).

void mpoly_monomial_evals_nmod(n_poly_t EH, const ulong * Aexps, slong Alen, flint_bitcnt_t Abits, n_poly_struct * alpha_caches, slong start, slong stop, const mpoly_ctx_t mctx, const nmod_t fpctx)
void mpoly1_monomial_evals_nmod(n_polyun_t EH, const ulong * Aexps, flint_bitcnt_t Abits, const ulong * Amarks, slong Amarkslen, n_poly_struct * alpha_caches, slong m, const mpoly_ctx_t mctx, const nmod_t fpctx)
void mpoly2_monomial_evals_nmod(n_polyun_t EH, const ulong * Aexps, flint_bitcnt_t Abits, ulong * Amarks, slong Amarkslen, n_poly_struct * alpha_caches, slong m, const mpoly_ctx_t mctx, const nmod_t fpctx)

Evaluate the monomials of a polynomial at powers of the evaluation points cached in alpha_caches, keeping zero, one or two main variables symbolic; used to set up the Vandermonde systems of sparse interpolation.

Sparse interpolation of the coefficients of a polynomial with known monomial structure H: start collecting req_images images in Z, add the image A (returning 0 if its support does not match), and solve the transposed Vandermonde systems, returning 1 for success and 0 or -1 if the images are inconsistent with the assumed structure.

References#

  • [Wan1978] P. S. Wang. An improved multivariate polynomial factoring algorithm. Mathematics of Computation 32 (1978), 1215–1231. https://doi.org/10.1090/S0025-5718-1978-0568284-3
  • [MonTun2020] M. Monagan and B. Tuncer. The complexity of sparse Hensel lifting and sparse polynomial factorization. Journal of Symbolic Computation 99 (2020), 189–230. https://doi.org/10.1016/j.jsc.2019.05.001
  • [Zas1969] H. Zassenhaus. On Hensel factorization, I. Journal of Number Theory 1 (1969), 291–311. https://doi.org/10.1016/0022-314X(69)90047-X
  • [Lec2006] G. Lecerf. Sharp precision in Hensel lifting for bivariate polynomial factorization. Mathematics of Computation 75 (2006), 921–933.
Cite this page

The FLINT team, “nmod_mpoly_factor.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/nmod_mpoly_factor/index.html (generated 2026-10-20).