Multivariate Hensel lifting
- Cost
- Dense lifting of factors of with degrees costs coefficient operations up to logarithmic factors in the worst case; sparse lifting is polynomial in the number of terms of the factors.
Hensel lifting is the step that turns a factorisation of a univariate (or bivariate) image of into a factorisation of itself. FLINT uses it in the factoring algorithms (Factorisation), in the EEZ-GCD algorithm (Hensel lifting) and, over finite fields, in the corresponding nmod_mpoly and fq_nmod_mpoly code. The setting is that of Wang [WanRot1975; Wan1978] with the notation of Schultz's notes [Sch-mpoly]; see also [GCL1992, Ch. 6] and [GG2003, §15].
Throughout, is the main variable, is the evaluation point for the other variables, and for a polynomial we write . Lifting proceeds from to , then , and so on: at stage the factorisation is lifted to by computing the Taylor coefficients of the in one at a time.
Uniqueness#
A factorisation can only be lifted if it is determined by its image, and the leading coefficients in are the obstruction: if , then also for any unit of the coefficient ring, and over a factor of the leading coefficient can move between and without changing the images up to scalars. The lifting therefore assumes that the leading coefficients are known (Leading coefficients explains how they are found).
Lemma 1 (Uniqueness of the lifted factors). Let be an integral domain, , , and suppose that , that , and that the images are pairwise coprime in , where is the fraction field of . If satisfy , and , then for all .
Proof. Suppose not, and let be the largest integer such that for all . Write , with not all zero. Since the leading coefficients agree, . Expanding modulo gives . Then divides , hence divides by coprimality, and by the degree bound, for every ; a contradiction.
Multivariate partial fractions#
Each lifting step needs the solution of a multivariate diophantine equation: given pairwise coprime and , find with
Dividing by , this is the partial fraction decomposition .
Lemma 2 (Univariate partial fractions). Over a field , if are pairwise coprime and , then has a unique solution, given by .
Proof. Reducing modulo gives , and is invertible modulo ; together with this determines . With these , the difference of the two sides of is divisible by every , hence by their product, and has smaller degree, so it is zero.
Over the solution has rational coefficients in general; the lifting needs to know whether an integral solution exists. fmpz_poly_pfrac_precomp solves modulo a power of a prime for which the stay coprime, checks the candidate by exact division, and increases until a bound on the solutions obtained from Cramer's rule and Hadamard's inequality (in terms of the norms of the and their resultants) shows that no integral solution exists if the check still fails.
With more variables, the solution is computed variable by variable, as a dense interpolation in Taylor coefficients.
Input: ; ; whose images are pairwise coprime; degree bounds . Output: satisfying for the , or failure.
- If , solve with Lemma 2 (over : as described above) and return.
- Otherwise, for : let be the -th Taylor coefficient in of , solve for and the recursively, giving , and add to . Fail if a recursive call fails or a exceeds the degree bound in .
Theorem 3. If has a solution with (and similarly for the other variables), Algorithm 1 returns it, and the solution is unique.
Proof. Uniqueness follows as in Lemma 1: two solutions differ by a solution of the homogeneous equation, whose lowest nonzero Taylor coefficients in would solve the homogeneous equation for the , which by induction (down to Lemma 2) only has the zero solution. The Taylor coefficient of order of , given the coefficients of order less than of the , is an equation of the same form for the coefficients of order with the , so the recursion computes the solution coefficient by coefficient.
fmpz_mpoly_pfrac implements Algorithm 1, keeping the products and their Taylor expansions for every level in an fmpz_mpoly_pfrac_t prepared by fmpz_mpoly_pfrac_init. When the Taylor coefficients are just the coefficients in , and the expansion is replaced by a conversion to a univariate polynomial in . Wang [Wan1978] recommends lifting modulo a power of a prime; FLINT's dense lifting instead works with exact integer coefficients in all variables, and only the univariate base case computes modulo prime powers [Sch-mpoly].
The lifting step#
Input: ; factors of whose leading coefficients in have already been replaced by the correct ones in ; the degree of in . Output: factors with , or failure.
- Write , with only known (apart from the leading coefficients).
- For : let be the -th Taylor coefficient of ; solve with Algorithm 1 at level ; add to . Fail if there is no solution or if .
The Taylor coefficient only depends on the coefficients with , and FLINT has three ways to compute it:
- the quintic version (
_hlift_quintic, for many factors) keeps the error and recomputes it after each step, dividing by to extract ; it finishes by checking ; - the quartic version (
_hlift_quartic, for ) computes incrementally from the Taylor coefficients, using partial products , , ...; _hlift_quartic2specialises this to : .
The names refer to the exponent of the degree in the dense cost, as in [Sch-mpoly]. The quartic versions do not verify the final product; the callers check the factors by exact division.
Theorem 4 (Correctness of the lifting step). If has a factorisation with (up to the known leading coefficients) and the conditions of Lemma 1 hold, then Algorithm 2 computes it. If it returns failure, no such factorisation exists.
Proof. By induction on , after step the agree with the modulo : the Taylor coefficient of order of is an equation for the coefficients , which by Theorem 3 has a unique solution, found by the algorithm. Since , the lifting is complete after steps. If the factorisation does not exist, either some equation has no solution, the degrees exceed , or the final product differs from .
Bivariate lifting modulo prime powers#
For the bivariate factorisation of fmpz_bpoly_factor the factors of have no known leading coefficients. They are made monic modulo and lifted in with the monic normalisation (_bivar_lift_quartic2, _bivar_lift_quartic and _bivar_lift_quintic in fmpz_mpoly_factor/bpoly_factor.c), to a precision in given by the degree of and its leading coefficient; the true factors are then found by recombination (Dense bivariate factorisation). The prime power is chosen above a bound on the coefficients of the factors.
Sparse Hensel lifting#
Dense lifting costs a polynomial in the dense size , which is prohibitive for sparse polynomials in many variables. Zippel's sparse Hensel lifting [Zip1981] and Kaltofen's variant [Kal1985] assume, as in sparse interpolation, that each Taylor coefficient of a factor in the new variable has the same support in the previous variables as the factor itself; the coefficients are then found from bivariate (in ) factorisations of at the points () by solving transposed Vandermonde systems (Sparse interpolation in Hensel lifting). Monagan and Tuncer [MonTun2020] analyse the cost and the probability of failure.
FLINT's fmpz_mpoly_factor_irred_zippel reduces modulo a word-size prime , lifts the first two variables densely and the others with nmod_mpoly_hlift_zippel over , and then lifts the factors from to by -adic Newton iteration on the same supports (the static function fmpz_mfactor_lift_prime_power_zippel). The result is verified by division.
Leading coefficients#
Before lifting, the leading coefficient must be distributed among the factors. If is an integer, it can be imposed on every factor, at the price of a power multiplied into and removed at the end (the integer content of each lifted factor). Otherwise the factors of must be assigned to the right factors of . Two methods are implemented, both needing the factorisation of (FLINT factors it recursively).
Wang's method#
Lemma 5 (Wang's leading coefficient condition). Let with and distinct irreducible nonconstant . Let be the factorisation of the primitive squarefree into irreducible factors, and suppose that with and primitive irreducible, with . If is a prime that divides but divides neither nor any , , then the exponent of in is
Proof. Write with . Then and , and evaluating at gives . Multiplying by , , where divides and is therefore not divisible by . Taking -adic valuations gives .
If every has such a prime, all exponents are determined [Wan1978]; the integer parts are not, and are handled by multiplying by a power of the remaining integer factor, which is removed again as the content of the lifted factors. fmpz_mpoly_factor_lcc_wang checks a sequential form of the condition (each must keep a nontrivial factor after removing all primes of and of ; it returns 0 otherwise, and another point is tried) and computes the exponents by removing the values from in the order with fmpz_remove. The condition fails for evaluation points with small values, in particular for when has factors without constant term, which is why FLINT first tries the point only when the input is dense enough, then random points.
For example, let with and , so that , , and , , . At the values are pairwise coprime, and with . Removing , and from leaves after one division by and one by , so ; from only is removed, so . At , on the other hand, the values have no private primes and the point is rejected.
Kaltofen's method#
Kaltofen [Kal1985] determines the distribution of the factors of one variable at a time from bivariate factorisations: for each , the bivariate image is factored with factors matched to the univariate factors (by fmpz_bpoly_factor_ordered, which lifts the in ); the leading coefficients of these bivariate factors are univariate in and show which factors of the image of go where; these are lifted back to the factors of involving . This works without Wang's condition, and fmpz_mpoly_factor_irred_wang falls back to it when the condition fails (fmpz_mpoly_factor_lcc_kaltofen, fmpz_mpoly_factor_lcc_kaltofen_step).
Since only coprime factors can be lifted, the step for works with squarefree parts. The leading coefficients of the bivariate factors (polynomials in , primitive) are replaced by their squarefree decompositions, which are then refined by GCDs into a single set of pairwise coprime squarefree bases. Let be the product of the distinct irreducible factors of that involve , a squarefree polynomial. If the product of the bases equals the primitive part of , the bases are lifted by Algorithm 2 to a factorisation of into polynomials in all variables (the images of the bases are coprime, so Lemma 1 applies). Each lifted base, raised to its multiplicity, is assigned to the factors whose bivariate leading coefficient contained it, and divided out of the factorisation of . When all of has been distributed, the integer content is assigned by comparing the contents of the bivariate leading coefficients with those of the assigned parts.
If neither method distributes the whole leading coefficient, the remaining part is imposed on every factor as for an integer leading coefficient, or the Zassenhaus method of Zassenhaus-style lifting, which lifts without leading coefficient information, is used.
Use in FLINT#
- Partial fractions:
fmpz_poly_pfrac_precompute,fmpz_poly_pfrac_precomp(Lemma 2),fmpz_mpoly_pfrac_init,fmpz_mpoly_pfrac(Algorithm 1). - Lifting:
fmpz_mpoly_hlift(Algorithm 2), dispatching to_hlift_quartic2,_hlift_quarticand_hlift_quintic;_fmpz_mpoly_get_lead0and_fmpz_mpoly_set_lead0to impose leading coefficients; the analoguesnmod_mpoly_hliftandfq_nmod_mpoly_hliftover finite fields. - Bivariate lifting:
fmpz_bpoly_factor,fmpz_bpoly_factor_ordered. - Sparse lifting:
nmod_mpoly_hlift_zippel,fmpz_mpoly_factor_irred_zippel. - Leading coefficients:
fmpz_mpoly_factor_lcc_wang(Lemma 5),fmpz_mpoly_factor_lcc_kaltofen. - Users:
fmpz_mpoly_factor_irred_wang,fmpz_mpoly_factor_irred_zippel,fmpz_mpoly_factor_irred_zassenhaus,fmpz_mpolyl_gcd_hensel, and the finite field factoring and GCD code (Factoring over finite fields, GCDs over small finite fields).
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)int fmpz_mpoly_pfrac(slong l, fmpz_mpoly_t t, const slong * degs, fmpz_mpoly_pfrac_t Iv, const fmpz_mpoly_ctx_t ctx)int fmpz_poly_pfrac_precomp(fmpz_poly_struct * c, const fmpz_poly_t A, fmpz_poly_pfrac_t Iv)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)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)void fmpz_bpoly_factor(fmpz_poly_t c, fmpz_tpoly_t F, fmpz_bpoly_t B)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)Referenced from#
- Factorisation (algorithm)
- Greatest common divisors (algorithm)
- Factoring over finite fields (algorithm)
- GCDs over small finite fields (algorithm)
- Multivariate polynomials: representations and algorithms (overview)
- Sparse interpolation (algorithm)
- fmpz_mod_mpoly.h (module)
- fmpz_mod_mpoly_factor.h (module)
- Factoring multivariate polynomials over the integers
- fmpz_mpoly_factor.h (module)
fmpz_mpoly_hlift- fq_nmod_mpoly.h (module)
- fq_nmod_mpoly_factor.h (module)
- fq_zech_mpoly_factor.h (module)
- nmod_mpoly.h (module)
- nmod_mpoly_factor.h (module)
References#
- [WanRot1975] P. S. Wang and L. P. Rothschild. Factoring multivariate polynomials over the integers. Mathematics of Computation 29 (1975), 935–950. https://doi.org/10.1090/S0025-5718-1975-0396471-3
- [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
- [Sch-mpoly] D. Schultz. Algorithms for multivariate polynomials. Notes in the FLINT source tree, src/mpoly/doc/MPolyAlgorithms.tex.
- [GCL1992] K. O. Geddes, S. R. Czapor and G. Labahn. Algorithms for computer algebra. Springer, 1992. https://doi.org/10.1007/b102438
- [GG2003] J. von zur Gathen and J. Gerhard, Modern Computer Algebra, second edition, Cambridge University Press (2003)
- [Zip1981] R. Zippel. Newton's iteration and the sparse Hensel algorithm. Proceedings of SYMSAC 1981, ACM, 68–72. https://doi.org/10.1145/800206.806373
- [Kal1985] E. Kaltofen. Sparse Hensel lifting. EUROCAL '85, Lecture Notes in Computer Science 204, Springer, 1985, 4–17. https://doi.org/10.1007/3-540-15984-3_230
- [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
The FLINT team, “Multivariate Hensel lifting,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/multivariate/hensel-lifting.html (generated 2026-11-02).
@misc{flint-doc-algorithms-multivariate-hensel-lifting,
author = {{The FLINT team}},
title = {{Multivariate Hensel lifting}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/algorithms/multivariate/hensel-lifting.html},
note = {Generated 2026-11-02}
}