FLINT3.7.0-dev

Factorisation

Synopsis#include <flint/nmod_mpoly_factor.h>
int nmod_mpoly_factor_content(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx)source

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.

int nmod_mpoly_factor_squarefree(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx)source

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.

int nmod_mpoly_factor_separable(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, int sep)source

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

int nmod_mpoly_factor(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx)source

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

int nmod_mpoly_factor_zassenhaus(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx)source
int nmod_mpoly_factor_wang(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx)source
int nmod_mpoly_factor_zippel(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx)source
int nmod_mpoly_factor_algo(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, unsigned int algo)source

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.

These functions factor a polynomial A∈Fp[x1,…,xm]A \in \mathbb{F}_p[x_1, \ldots, x_m], pp prime, as

A=c∏i=1kfiei,A = c \prod_{i=1}^{k} f_i^{e_i},

where c∈Fpc \in \mathbb{F}_p is the leading coefficient of AA and the bases fif_i are monic. nmod_mpoly_factor_content only separates the monomial content and the contents with respect to each variable; nmod_mpoly_factor_squarefree returns squarefree, pairwise coprime bases; nmod_mpoly_factor returns the irreducible factorisation, in which the bases are irreducible and pairwise distinct. The order of the factors is not specified; nmod_mpoly_factor_sort sorts them by exponent and then by nmod_mpoly_cmp, which makes the output canonical. The zero polynomial gives c=0c = 0 and no factors, a nonzero constant gives c=Ac = A and no factors.

All functions return 1 for success. They return 0 only in extreme cases (exponents of more than one word after removing the content, or no usable evaluation points or extension fields), and f is then undefined.

AlgorithmFactoring over finite fieldsThe multivariate factorisation pipeline of nmod_mpoly_factor and fq_nmod_mpoly_factor, with what is specific to characteristic pp: separable factorisation with pp-th roots, deflation by powers of pp, 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.

Characteristic pp#

Two features of characteristic pp appear in the output. First, a polynomial with zero derivative in every variable is a pp-th power: over Fp\mathbb{F}_p, ∑ecexpe=(∑ecexe)p\sum_e c_e x^{pe} = (\sum_e c_e x^e)^p. The squarefree decomposition therefore extracts pp-th roots by dividing exponents, and multiplicities divisible by pp come out naturally; in the example below, (x3+yz+1)3=x9+y3z3+1(x^3 + yz + 1)^3 = x^9 + y^3z^3 + 1 over F3\mathbb{F}_3. Second, factoring needs evaluation points at which the polynomial keeps its degree and stays squarefree. When Fp\mathbb{F}_p does not have enough of them, the polynomial is factored over an extension Fpk\mathbb{F}_{p^k} and the conjugate factors under the Frobenius automorphism are multiplied back together. Both are invisible to the caller.

nmod_mpoly_factor_separable with sep = 1 refines the squarefree decomposition so that each base gg satisfies, for each variable, ∂g/∂xi=0\partial g/\partial x_i = 0 or gcd⁡(g,∂g/∂xi)=1\gcd(g, \partial g/\partial x_i) = 1. This is the input format of the irreducible factorisation.

The variants nmod_mpoly_factor_zassenhaus, nmod_mpoly_factor_wang and nmod_mpoly_factor_zippel restrict the method used to lift factorisations of bivariate images to all variables (recombination of lifted factors, Wang's leading coefficient method with dense Hensel lifting, or sparse Hensel lifting); nmod_mpoly_factor_algo takes a bit mask of these methods. nmod_mpoly_factor uses all of them, choosing the order from the density of the polynomial; see Choosing among the methods.

Example#

Over F3\mathbb{F}_3, the squarefree decomposition of a polynomial with a cube factor, and its irreducible factorisation; then a factorisation over F2\mathbb{F}_2, where x4+y4=(x+y)4x^4 + y^4 = (x + y)^4:

Examplenmod_mpoly_factor_char_p.cchecked by make checkdoc
#include <flint/flint.h>
#include <flint/nmod_mpoly.h>
#include <flint/nmod_mpoly_factor.h>

static void print_factor(const char * name, nmod_mpoly_factor_t f,
                         const char ** vars, const nmod_mpoly_ctx_t ctx)
{
    slong i;
    flint_printf("%s: %wu", name, nmod_mpoly_factor_get_constant_ui(f, ctx));
    for (i = 0; i < nmod_mpoly_factor_length(f, ctx); i++)
    {
        flint_printf(" * (");
        nmod_mpoly_print_pretty(f->poly + i, vars, ctx);
        flint_printf(")^%wd", nmod_mpoly_factor_get_exp_si(f, i, ctx));
    }
    flint_printf("\n");
}

int main(void)
{
    nmod_mpoly_ctx_t ctx;
    nmod_mpoly_t a;
    nmod_mpoly_factor_t f;
    const char * vars[] = {"x", "y", "z"};

    nmod_mpoly_ctx_init(ctx, 3, ORD_LEX, 3);
    nmod_mpoly_init(a, ctx);
    nmod_mpoly_factor_init(f, ctx);

    nmod_mpoly_set_str_pretty(a, "2*y^2*(x^3 + y*z + 1)^3*(x^2 + y^2 + z^2)*(x^2 - y^2 + z)", vars, ctx);
    flint_printf("a has %wd terms\n", nmod_mpoly_length(a, ctx));

    nmod_mpoly_factor_squarefree(f, a, ctx);
    nmod_mpoly_factor_sort(f, ctx);
    print_factor("squarefree", f, vars, ctx);

    nmod_mpoly_factor(f, a, ctx);
    nmod_mpoly_factor_sort(f, ctx);
    print_factor("irreducible", f, vars, ctx);

    /* over F_2: x^4 + y^4 = (x + y)^4, and a factorisation needing extensions */
    nmod_mpoly_ctx_set_modulus(ctx, 2);
    nmod_mpoly_set_str_pretty(a, "(x^2*y + x*z^2 + y*z + 1)*(x^3 + y^2*z + x*z + z + 1)*(x^4 + y^4)", vars, ctx);
    nmod_mpoly_factor(f, a, ctx);
    nmod_mpoly_factor_sort(f, ctx);
    print_factor("over F_2", f, vars, ctx);

    nmod_mpoly_factor_clear(f, ctx);
    nmod_mpoly_clear(a, ctx);
    nmod_mpoly_ctx_clear(ctx);
    return 0;
}
Output
a has 21 terms
squarefree: 2 * (x^4+x^2*z^2+x^2*z+2*y^4+2*y^2*z^2+y^2*z+z^3)^1 * (y)^2 * (x^3+y*z+1)^3
irreducible: 2 * (x^2+2*y^2+z)^1 * (x^2+y^2+z^2)^1 * (y)^2 * (x^3+y*z+1)^3
over F_2: 1 * (x^2*y+x*z^2+y*z+1)^1 * (x^3+x*z+y^2*z+z+1)^1 * (x+y)^4

The squarefree decomposition keeps the two factors of multiplicity 1 together as one base; the irreducible factorisation separates them. The program switches to F2\mathbb{F}_2 with nmod_mpoly_ctx_set_modulus, which is allowed because both a and f are completely overwritten before they are used again. nmod_mpoly_factor_get_exp_si takes a non-const factorisation.

Cite this page

The FLINT team, “Factorisation (nmod_mpoly_factor.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/nmod_mpoly_factor/factor.html (generated 2026-11-02).