FLINT3.7.0-dev
Module · 115 functions

fmpz_mpoly_factor.h

#include <flint/fmpz_mpoly_factor.h>

This module factors polynomials in Z[x0,…,xn−1]\mathbb{Z}[x_0, \ldots, x_{n-1}] (see fmpz_mpoly.h). A factorisation is stored as an fmpz_mpoly_factor_t: an integer constant times a product of polynomial bases raised to positive exponents. fmpz_mpoly_factor_content splits off the content and the powers of variables, fmpz_mpoly_factor_squarefree computes a squarefree factorisation, and fmpz_mpoly_factor the factorisation into irreducible polynomials. The factoring strategy and an example are on the function page Factoring multivariate polynomials over the integers, and the algorithms are explained in Factorisation and Multivariate Hensel lifting.

The header also declares the internal machinery shared by the factoring code and by the GCD code of fmpz_mpoly: GCD algorithms on lex contexts, modular reduction and reconstruction, multivariate partial fractions and Hensel lifting, and dense bivariate polynomials with their factorisation and resultant. These functions are documented below for developers; their interfaces may change between releases.

Types#

A factored polynomial c∏i<numpieic \prod_{i < \mathit{num}} p_i^{e_i}. The fields are constant (the integer cc), constant_den (a denominator for cc, which stays 1 in this module and is used by the factored denominators of fmpz_mpoly_q), poly (the bases pip_i, an array of fmpz_mpoly_struct), exp (the exponents eie_i, an array of fmpz), num and alloc. The bases of a factorisation returned by the factoring functions are nonconstant with positive leading coefficient, and the exponents are positive.

Memory management#

Initialise f as the empty product with constant 1, with room for alloc factors in the second version.

Change the allocation to exactly alloc factors (freeing the factors beyond it, and everything if alloc≤0\mathit{alloc} \le 0), respectively ensure room for at least len factors.

Frees the memory used by f.

Basic manipulation#

Swaps f and g in constant time.

Sets f to a copy of g (the field constant_den is not copied).

Returns the number of bases of f.

Set cc to the constant of f. The fmpq version uses constant_den as the denominator.

Set pp to, respectively swap pp with, the base of index ii.

Returns the exponent of the base of index ii, which must fit an slong.

Set f to the constant aa, 0 or 1, with no bases.

Append the factor AeA^e to f, copying AA, respectively swapping it in (so that AA is left with an unspecified value). No normalisation is done.

Sorts the factors by increasing exponent, and factors with equal exponents by fmpz_mpoly_cmp. Since the irreducible factorisation returned by fmpz_mpoly_factor has distinct bases with positive leading coefficients, two such factorisations of the same polynomial are identical after sorting.

Compares f and g by their constants, then their numbers of factors, then factor by factor (exponent, then base by fmpz_mpoly_cmp). Returns a negative, zero or positive value. This is a total order on the stored data, not a comparison of the products.

Sets AA to the product represented by f (ignoring constant_den). Returns 0 if an exponent is negative or a power cannot be computed, and 1 otherwise.

Returns whether f expands to AA.

void fmpz_mpoly_factor_print_pretty(const fmpz_mpoly_factor_t f, const char ** vars, const fmpz_mpoly_ctx_t ctx)

Prints f in the form c*(p1)^e1*(p2)^e2*..., using the variable names vars (or x1, x2, ... if vars is NULL).

Factorisation#

The factoring functions return 1 for success and 0 for failure, in which case f is unspecified. They fail only when an intermediate result is unreasonably large, for example when a polynomial with exponents beyond one word cannot be repacked, and not for ordinary inputs. They overwrite f: its initial value does not matter.

Sets f to a factorisation of AA into an integer constant (the content of AA with the sign of its leading coefficient), powers of the variables, and polynomials with exponent 1 that are primitive with respect to each variable they involve. The latter are found by repeatedly splitting off the content with respect to one variable; they are neither squarefree nor irreducible in general. For constant AA, f is that constant with no bases.

Full documentation

Sets f to a factorisation of AA whose bases are primitive, squarefree and pairwise coprime. A base with exponent kk is a product of irreducible factors of AA of multiplicity exactly kk, but the factors of a given multiplicity may be spread over several bases (one for each piece found by fmpz_mpoly_factor_content). To get a single base for each multiplicity, sort with fmpz_mpoly_factor_sort and multiply the bases with equal exponents.

Full documentation

Sets f to the factorisation of AA into an integer constant and distinct irreducible polynomials with positive leading coefficients. The constant is the signed content of AA and is not factored into primes. See Factoring multivariate polynomials over the integers.

Full documentation

Versions of fmpz_mpoly_factor restricted to one method for the hard case (a squarefree primitive polynomial that is not handled by the special cases for few variables or low degree): Wang's algorithm with dense Hensel lifting, sparse Hensel lifting in Zippel's style, or lifting without leading coefficient information followed by recombination. The result is the same; these functions exist for testing and benchmarking.

Full documentation
int fmpz_mpoly_factor_irred(fmpz_mpoly_factor_t f, const fmpz_mpoly_ctx_t ctx, unsigned int algo)

Replaces each base of f by its irreducible factors, with the exponent of the base, using the methods in the bit set algo of MPOLY_FACTOR_USE_ZAS, MPOLY_FACTOR_USE_WANG and MPOLY_FACTOR_USE_ZIP (or MPOLY_FACTOR_USE_ALL). Each base must be squarefree, have positive leading coefficient and be primitive with respect to each variable it involves.

int fmpz_mpoly_factor_bound_si(fmpz_t B, const fmpz_t A, const slong * degs, slong nvars)

Sets BB to a bound on the coefficients of the divisors of a polynomial ff whose coefficients are bounded by AA in absolute value and whose degrees in its nn = nvars variables are d0,…,dn−1d_0, \ldots, d_{n-1} (degs): B=∣A∣⋅(⌊⌈∏i(di+1)/2n⌉⌋+1)⋅2∑idiB = |A| \cdot (\lfloor \sqrt{\lceil \prod_i (d_i + 1) / 2^{n} \rceil} \rfloor + 1) \cdot 2^{\sum_i d_i}, and B=0B = 0 if some di<0d_i < 0. Returns 0 if the degree sum overflows and 1 otherwise. fmpz_mpolyl_gcd_zippel uses this bound to decide when to give up on a modular reconstruction and start over.

GCD algorithms on lex contexts#

The GCD driver works in a lex context in the variables that occur in the inputs, in an order chosen for the algorithm, with exponents shifted by the minimal exponents and divided by common strides. The functions named fmpz_mpolyl_* require such a lex context and single-word exponents, with all inputs and outputs packed with the same number of bits. See Greatest common divisors and Greatest common divisors.

int _fmpz_mpoly_gcd_algo(fmpz_mpoly_t G, fmpz_mpoly_t Abar, fmpz_mpoly_t Bbar, const fmpz_mpoly_t A, const fmpz_mpoly_t B, const fmpz_mpoly_ctx_t ctx, unsigned int algo)

The GCD driver behind fmpz_mpoly_gcd and its variants, for nonzero AA and BB: handles the easy cases, estimates degrees and term counts of the GCD, and dispatches to the algorithms allowed by the bit set algo of MPOLY_GCD_USE_* flags. Abar and Bbar may be NULL if the cofactors are not wanted. Returns 1 for success.

void fmpz_mpoly_to_mpolyl_perm_deflate(fmpz_mpoly_t A, const fmpz_mpoly_ctx_t lctx, const fmpz_mpoly_t B, const fmpz_mpoly_ctx_t ctx, const slong * perm, const ulong * shift, const ulong * stride)
void fmpz_mpoly_from_mpolyl_perm_inflate(fmpz_mpoly_t A, flint_bitcnt_t Abits, const fmpz_mpoly_ctx_t ctx, const fmpz_mpoly_t B, const fmpz_mpoly_ctx_t lctx, const slong * perm, const ulong * shift, const ulong * stride)

Convert from ctx to the context lctx, whose variable kk is variable perm[k] of ctx with exponents mapped by e↦(e−s)/te \mapsto (e - s)/t for the shift ss and stride tt of that variable, and back, packing the result into Abits bits. The results are sorted. See mpoly_to_mpolyl_perm_deflate.

Brown's dense multimodular algorithm [Bro1971] for the GCD and cofactors of nonzero AA and BB. The integer contents are removed from AA and BB, which are modified. Images are computed with nmod_mpolyn_gcd_brown_smprime modulo primes p>2FLINT_BITS−1p > 2^{\mathrm{FLINT\_BITS}-1} not dividing the GCD γ\gamma of the leading coefficients, scaled to have leading coefficient γ mod p\gamma \bmod p and combined by Chinese remaindering, discarding images of too large degree. The loop stops when the product mm of the primes exceeds twice γ\gamma times the larger height of AA and BB and the reconstructed HH, AˉH\bar A_H, BˉH\bar B_H satisfy 2min⁡(∥H∥∞∥AˉH∥1,∥H∥1∥AˉH∥∞)<m2 \min(\|H\|_\infty \|\bar A_H\|_1, \|H\|_1 \|\bar A_H\|_\infty) < m and likewise for BB; this proves HAˉH=γAH \bar A_H = \gamma A and HBˉH=γBH \bar B_H = \gamma B without a division. Iv (possibly NULL) supplies degree bounds for the images. The threaded version computes images for different primes in parallel using the given thread pool handles; it is not used by fmpz_mpoly_gcd. Return 0 if the primes run out.

Zippel's sparse modular GCD [Zip1979] for AA and BB in at least two variables that are primitive as polynomials in x0x_0 over Z[x1,…,xn−1]\mathbb{Z}[x_1, \ldots, x_{n-1}]: the GCD modulo one prime fixes the monomials (the shape), and the images modulo further primes are computed by solving for the coefficients of that shape. The coefficients are reconstructed by Chinese remaindering, and the result is verified by division. The bound of fmpz_mpoly_factor_bound_si on the inputs decides when a reconstruction is abandoned.

The sparse GCD of Hu and Monagan [HuMon2016] for AA and BB in at least three variables that are primitive as polynomials in x0,x1x_0, x_1 over Z[x2,…,xn−1]\mathbb{Z}[x_2, \ldots, x_{n-1}]: bivariate GCDs in x0,x1x_0, x_1 modulo primes, with the remaining variables evaluated at powers of random points, are interpolated with the Berlekamp–Massey algorithm, and the result is verified by division. Gamma, a polynomial in x2,…x_2, \ldots that is a multiple of the leading coefficient of the GCD in x0,x1x_0, x_1 (in practice the GCD of the leading coefficients of AA and BB), is imposed on the images.

The EEZ-GCD algorithm [Wan1980] for AA and BB in at least two variables that are primitive as polynomials in x0x_0, given an upper bound Gdeg on the degree in x0x_0 of the GCD: the variables x1,…x_1, \ldots are evaluated at small integers, the univariate GCD is computed, and the factorisation G⋅AˉG \cdot \bar A of AA, of BB, or of a combination μ1A+μ2B\mu_1 A + \mu_2 B in which the two factors are coprime, is lifted with fmpz_mpoly_hlift.

Modular reduction and reconstruction#

Set Ap=A mod pA_p = A \bmod p, and AA to the lift of ApA_p with coefficients in the symmetric range (−p/2,p/2](-p/2, p/2]. Both contexts have the same variables and the polynomials are packed with the same number of bits.

int fmpz_mpoly_interp_mcrt_p(flint_bitcnt_t * coeffbits, fmpz_mpoly_t H, const fmpz_mpoly_ctx_t ctx, const fmpz_t m, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctxp)

Replaces HH, known modulo mm, by the polynomial with coefficients in the symmetric range modulo mpmp that is congruent to HH modulo mm and to AA modulo pp. HH and AA must have the same monomials. Returns whether HH changed, and sets *coeffbits to the largest bit length of its new coefficients.

void fmpz_mpoly_interp_reduce_p_mpolyn(nmod_mpolyn_t E, const nmod_mpoly_ctx_t pctx, const fmpz_mpoly_t A, const fmpz_mpoly_ctx_t ctx)
void fmpz_mpoly_interp_lift_p_mpolyn(fmpz_mpoly_t A, const fmpz_mpoly_ctx_t ctx, const nmod_mpolyn_t B, const nmod_mpoly_ctx_t pctx)
int fmpz_mpoly_interp_crt_p_mpolyn(fmpz_mpoly_t F, fmpz_mpoly_t T, const fmpz_mpoly_ctx_t ctx, fmpz_t modulus, const nmod_mpolyn_t A, const nmod_mpoly_ctx_t pctx)

The same operations with the image in recursive form Fp[x0,…,xn−2][xn−1]\mathbb{F}_p[x_0, \ldots, x_{n-2}][x_{n-1}] (an nmod_mpolyn_t, whose coefficients are univariate in the last variable), as used by Brown's algorithm. The CRT version updates FF so that it is unchanged modulo modulus and congruent to AA modulo pp, without assuming that the monomials match; it uses TT as scratch space, returns whether FF changed, and does not update modulus.

Vectors of polynomials#

A growable vector of polynomials (fields coeffs, alloc, length), used for lists of factors and for expansions in powers of xi−αx_i - \alpha.

Initialise an empty vector, free it, swap two vectors in constant time, and ensure room for length entries.

void fmpz_mpolyv_print_pretty(const fmpz_mpolyv_t poly, const char ** x, const fmpz_mpoly_ctx_t ctx)

Prints the entries, one per line, as coeff[i]: ....

Sets entry ii to the nonzero polynomial cc by swapping (so cc is left with an unspecified value), extending the vector with zero entries if needed.

The first writes B=∑iAi⋅xalphaiB = \sum_i A_i \cdot \mathit{xalpha}^i by repeated division with remainder by xalpha; for xalpha=xj−α\mathit{xalpha} = x_j - \alpha the AiA_i are the Taylor coefficients of BB at xj=αx_j = \alpha. The second evaluates such an expansion by Horner's rule and packs the result into Abits bits.

Sets gg to the GCD of the Alen polynomials in AA, with positive leading coefficient, starting with the two shortest ones. Returns 0 if a GCD computation failed.

Divide each polynomial of AA exactly by cc, respectively multiply each by cc.

Negates the nonzero polynomial AA if its leading coefficient is negative.

Partial fractions and Hensel lifting#

These functions implement the multivariate Hensel lifting described in Multivariate Hensel lifting. Given A≡∏ifi mod (xm−α)A \equiv \prod_i f_i \bmod (x_m - \alpha) with the correct leading coefficients, the factors are lifted one power of xm−αx_m - \alpha at a time, each step solving a multivariate partial fraction problem t=∑iδi∏j≠ifjt = \sum_i \delta_i \prod_{j \ne i} f_j in the variables x0,…,xm−1x_0, \ldots, x_{m-1}, recursively down to a univariate problem over Z\mathbb{Z}.

Precomputed data for univariate partial fraction problems over Z\mathbb{Z} with fixed denominators b0,…,br−1b_0, \ldots, b_{r-1}, solved modulo a power of a prime and checked by division.

Prepares Iv for the r≥2r \ge 2 nonconstant denominators bi∈Z[x]b_i \in \mathbb{Z}[x]: computes the products bi+1⋯br−1b_{i+1} \cdots b_{r-1}, the resultants that bound the size of solutions, a prime pp for which the bib_i stay coprime modulo pp, and the corresponding inverses. Returns 0 if r<2r < 2, some bib_i is constant, or two of them are not coprime.

Solves A/∏ibi=∑ici/biA / \prod_i b_i = \sum_i c_i / b_i for ci∈Z[x]c_i \in \mathbb{Z}[x] with deg⁡ci<deg⁡bi\deg c_i < \deg b_i for i<r−1i < r - 1. The solution is computed modulo a power pkp^k of the prime and checked by exact division; on failure the precision is raised until a Cramer–Hadamard bound on the solution shows that no integer solution exists. Returns 1 if a solution exists and 0 otherwise, so a return value of 0 is a proof.

Precomputed data for multivariate partial fraction problems with rr fixed denominators β0,…,βr−1\beta_0, \ldots, \beta_{r-1} in the variables x0,…,xwx_0, \ldots, x_w: their images βj(l)\beta_j^{(l)} under xk=αk−1x_k = \alpha_{k-1} for k>lk > l (mbetas), the products ∏j≠iβj(l)\prod_{j \ne i} \beta_j^{(l)} and their Taylor expansions in xl−αl−1x_l - \alpha_{l-1}, and the solutions deltas at each level ll.

int fmpz_mpoly_pfrac_init(fmpz_mpoly_pfrac_t Iv, flint_bitcnt_t bits, slong r, slong w, const fmpz_mpoly_struct * betas, const fmpz * alpha, const fmpz_mpoly_ctx_t ctx)

Prepare for the rr denominators betas in the variables x0,…,xwx_0, \ldots, x_w and the evaluation point (α0,…,αw−1)(\alpha_0, \ldots, \alpha_{w-1}) for x1,…,xwx_1, \ldots, x_w, in a lex context with bits bits. The univariate images in x0x_0 must keep their degrees and be pairwise coprime; if not, the initialisation throws an error. Free the data.

Solves t=∑iδi∏j≠iβj(l)t = \sum_i \delta_i \prod_{j \ne i} \beta_j^{(l)} in the variables x0,…,xlx_0, \ldots, x_l with deg⁡x0δi<deg⁡x0βi\deg_{x_0} \delta_i < \deg_{x_0} \beta_i and deg⁡xkδi\deg_{x_k} \delta_i at most what the bound degs[k] allows, storing the solution in Iv->deltas + l*r. For l=0l = 0 this is a univariate problem; for l>0l > 0 the Taylor coefficients of tt in xl−αl−1x_l - \alpha_{l-1} are processed in turn, each by a call at level l−1l - 1. tt is destroyed. Returns 1 if a solution exists, 0 if no solution satisfies the degree bounds, and −1-1 if tt cannot be repacked to the working bits.

int fmpz_mpoly_hlift(slong m, fmpz_mpoly_struct * f, slong r, const fmpz * alpha, const fmpz_mpoly_t A, const slong * degs, const fmpz_mpoly_ctx_t ctx)

Lifts the r≥2r \ge 2 factors fif_i of A≡∏ifi mod (xm−αm−1)A \equiv \prod_i f_i \bmod (x_m - \alpha_{m-1}), in a lex context with single-word exponents, to factors in the variables x0,…,xmx_0, \ldots, x_m. The leading coefficients of the fif_i in x0x_0 must already be the correct ones (polynomials in all of x1,…,xmx_1, \ldots, x_m), and degs are the degrees of AA. The lifting runs up to degree degs[m] in xm−αm−1x_m - \alpha_{m-1}; it uses the error update of the quartic method, specialised for r=2r = 2, when r<20r < 20, and recomputes the product of the factors (quintic method) otherwise. Returns 0 if a partial fraction problem has no solution or the degrees exceed degs[m], in which case there is no factorisation of AA with these images and leading coefficients. Only the quintic version checks at the end that A=∏ifiA = \prod_i f_i; the callers verify the factors by division in any case. See The lifting step.

In a lex context, set cc to the leading coefficient of AA as a polynomial in x0x_0 (a polynomial in the other variables), and set AA to BB with that leading coefficient replaced by cc.

Dense bivariate polynomials#

A dense bivariate polynomial ∑ici(y)xi\sum_i c_i(y) x^i over Z\mathbb{Z}, stored as an array coeffs of length univariate polynomials (fmpz_poly_struct) in yy, with room for alloc. The leading coefficient coeffs[length - 1] is nonzero.

Memory management: initialise as zero, free, swap in constant time, ensure room for at least len coefficients in xx (realloc never shrinks), and set to zero.

Return a pointer to the leading coefficient in xx, the degree in xx, and the degree in yy (both −1-1 for zero).

void fmpz_bpoly_set_coeff(fmpz_bpoly_t A, slong exp0, slong exp1, const fmpz_t c)

Sets the coefficient of xexp0yexp1x^{\mathit{exp0}} y^{\mathit{exp1}} to the nonzero integer cc.

void fmpz_bpoly_print_pretty(fmpz_bpoly_t A, const char * var0, const char * var1)

Prints AA as a sum of terms (c(y))*x^i, with the given names for xx and yy.

Convert between a multivariate polynomial in the variables of index var0 (for xx) and var1 (for yy) and a dense bivariate polynomial. The first requires single-word exponents and ignores the exponents of the other variables; the second packs the result into Abits bits.

int fmpz_bpoly_resultant(fmpz_poly_t res, const fmpz_bpoly_t A, const fmpz_bpoly_t B, int proved)

Set res to the resultant of AA and BB with respect to xx, a polynomial in yy, by reduction modulo word-size primes, resultants of the images and Chinese remaindering. If proved is nonzero, enough primes are used for their product to exceed twice a Hadamard-type bound on the coefficients of the resultant, which makes the result exact; otherwise the reconstruction stops once it has been left unchanged by primes whose product exceeds 21002^{100}, which is a heuristic. Return 0 if no image could be computed. The underscore version works in place on the coefficient arrays, whose contents it removes, and requires lenA≥lenB≥2\mathit{lenA} \ge \mathit{lenB} \ge 2. This is the dense case of fmpz_mpoly_resultant and the modular resultant of the generic polynomial module; see Bivariate resultants by evaluation and interpolation.

A growable vector of fmpz_bpoly_struct (fields coeffs, alloc, length), used for lists of bivariate factors.

Initialise an empty vector, free it, swap in constant time, and ensure room for len entries.

Factors the squarefree bivariate polynomial BB of positive degree in xx: sets cc to its content as a polynomial in xx over Z[y]\mathbb{Z}[y] and FF to the irreducible factors of the primitive part. The point α\alpha is the first of 0,1,−1,2,−2,…0, 1, -1, 2, -2, \ldots for which B(x,α)B(x, \alpha) keeps its degree and is squarefree; B(x,α)B(x, \alpha) is factored with fmpz_poly_factor, the factors are lifted in (Z/pkZ)[[y−α]][x](\mathbb{Z}/p^k\mathbb{Z})[[y - \alpha]][x] to a precision given by a bound on the factors, and recombined by trying subsets. BB is destroyed. If BB is not squarefree, the search for α\alpha does not terminate.

As fmpz_bpoly_factor, with the point α\alpha and the squarefree factorisation Bevalf of B(x,α)B(x, \alpha) given (with at least two factors). On success there is one factor in FF for each factor of Bevalf, in the same order. Returns 1 on success, 0 if the lifted factors do not correspond one to one with the factors of Bevalf, and −1-1 if BB is not primitive (with its content in cc). Used by Kaltofen's leading coefficient method.

Irreducible factorisation internals#

Appends a squarefree factorisation of AeA^e to f, where AA is primitive with respect to each variable. Constant and monomial AA are handled directly; otherwise Yun's algorithm [Yun1976] is run with respect to the first variable in which AA has a nonzero derivative. AA is destroyed. Returns 0 if a GCD failed for every variable.

int fmpz_mpoly_factor_irred_wang(fmpz_mpolyv_t fac, const fmpz_mpoly_t A, const fmpz_mpoly_factor_t lcAfac, int lcAfac_irred, const fmpz_mpoly_t lcA, const fmpz_mpoly_ctx_t ctx, flint_rand_t state, zassenhaus_prune_t Z, int allow_shift)
int fmpz_mpoly_factor_irred_zippel(fmpz_mpolyv_t fac, const fmpz_mpoly_t A, const fmpz_mpoly_factor_t lcAfac, int lcAfac_irred, const fmpz_mpoly_t lcA, const fmpz_mpoly_ctx_t ctx, flint_rand_t state, zassenhaus_prune_t Z)

Set fac to the irreducible factors of AA, which must be squarefree, primitive with respect to each variable and have positive leading coefficient, in a lex context with at least two variables. lcA is the leading coefficient of AA in x0x_0 and lcAfac a squarefree factorisation of it, irreducible if lcAfac_irred is nonzero. Z collects the degrees of the factors of univariate images and can prove irreducibility early.

The Wang version evaluates x1,…x_1, \ldots at 00 and, if allow_shift is nonzero, then at random points of growing size, distributes the leading coefficient with fmpz_mpoly_factor_lcc_wang or fmpz_mpoly_factor_lcc_kaltofen, and lifts the factors one variable at a time with fmpz_mpoly_hlift. The Zippel version lifts modulo a prime with sparse Hensel lifting and then pp-adically. The Zassenhaus version lifts without leading coefficient information and recombines subsets of the lifted factors. Return 1 on success, 0 if the method failed (another method or point may succeed), and −1-1 on an exceptional failure such as exponents that no longer fit one word.

int fmpz_mpoly_factor_lcc_wang(fmpz_mpoly_struct * lc_divs, const fmpz_mpoly_factor_t lcAfac, const fmpz_t Auc, const fmpz_poly_struct * Auf, slong r, const fmpz * alpha, const fmpz_mpoly_ctx_t ctx)

Wang's leading coefficient determination [Wan1978]. Given the irreducible factorisation lcAfac of the leading coefficient of AA in x0x_0 and the factorisation Auc∏i<rAufi\mathit{Auc} \prod_{i < r} \mathit{Auf}_i of A(x0,α)A(x_0, \alpha), sets lc_divs[i] to the predicted leading coefficient of the ii-th factor of AA: the product of the powers of the factors of the leading coefficient whose values at α\alpha divide the leading coefficient of Aufi\mathit{Auf}_i, times an integer. Returns 0 if the evaluation point fails Wang's condition, that each factor of the leading coefficient evaluates to an integer with a prime divisor not dividing Auc\mathit{Auc} times the constant and the values of the other factors.

int fmpz_mpoly_factor_lcc_kaltofen(fmpz_mpoly_struct * divs, const fmpz_mpoly_factor_t lcAf_, const fmpz_mpoly_t A, slong r, const fmpz * alpha, slong * degs, const fmpz_poly_factor_t uf, const fmpz_mpoly_ctx_t ctx)

Kaltofen's leading coefficient determination [Kal1985]. For each variable xvx_v, v≥1v \ge 1, the bivariate image of AA in x0,xvx_0, x_v (all other variables evaluated at α\alpha) is factored with fmpz_bpoly_factor_ordered in the order of the univariate factors uf, and the leading coefficients of its factors show how the squarefree factors lcAf_ of the leading coefficient of AA involving xvx_v are distributed; these are multiplied into divs. Returns 1 if the whole leading coefficient has been distributed, 0 if only part of it was, and −1-1 if the evaluation point is unusable.

One step of fmpz_mpoly_factor_lcc_kaltofen for the variable xvx_v: given the squarefree factorisation Af of the remaining part of the leading coefficient and the univariate leading coefficients Au[i] in xvx_v of the bivariate factors, lifts the matching factors of the image of Af to all variables, multiplies them into divs[i] and removes them from Af. Returns 1 on success and 0 if the images do not match.

Sets ee to AA with xi=αi−1x_i = \alpha_{i-1} for every i≥1i \ge 1 other than vv, as a polynomial in xvx_v. Returns 0 if an evaluation failed or the result involves x0x_0.

void _fmpz_mpoly_eval_rest_to_poly(fmpz_poly_t E, const fmpz_mpoly_t A, const fmpz * alphas, const fmpz_mpoly_ctx_t ctx)
int _fmpz_mpoly_evaluate_rest_fmpz(fmpz * E, slong * starts, slong * ends, slong * stops, ulong * es, const fmpz * Acoeffs, const ulong * Aexps, slong Alen, slong var, const fmpz * alphas, const slong * offsets, const slong * shifts, slong N, ulong mask, slong nvars)

The first sets E=A(x0,α0,…,αn−2)E = A(x_0, \alpha_0, \ldots, \alpha_{n-2}) for AA in a lex context with single-word exponents. The second is its kernel: for a block of Alen terms of a lex polynomial whose exponents agree in the variables before var, it evaluates the variables from var on at alphas (indexed from var) by a recursive Horner scheme and puts the value in E[0]; starts, ends, stops, es and the further entries of EE are work arrays of length nvars, and offsets and shifts locate the exponent fields.

Apply the change of variables found by mpoly_compression_set. The first builds LL in the compressed lex context Lctx from the coefficients Acoeffs, which are swapped in, and the compressed exponents stored in M, then sorts it and makes its leading coefficient positive. The second maps LL (typically a factor of the compressed polynomial, whose coefficients are swapped out) back to Actx with Abits bits, divides by the largest monomial dividing it, sorts, and makes the leading coefficient positive.

void tuple_print(fmpz * alpha, slong n)
void tuple_next(fmpz * alpha, slong n)
void tuple_saturate(fmpz * alpha, slong n, slong m)

Helpers for enumerating evaluation points in Nn\mathbb{N}^n: print a tuple, step to the next tuple (all tuples with a given sum are visited before the sum increases), and move the entries after index mm into entry mm (making it 1 if the first m+1m + 1 entries would all be zero) so that one of the first m+1m + 1 entries changes at the next step.

References#

Cite this page

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