/*============================================================================= This file is part of FLINT. FLINT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. FLINT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FLINT; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =============================================================================*/ /****************************************************************************** Copyright (C) 2011 Andy Novocin Copyright (C) 2011 Sebastian Pancratz ******************************************************************************/ ******************************************************************************* Memory management ******************************************************************************* void fmpz_poly_factor_init(fmpz_poly_factor_t fac) Initialises a new factor structure. void fmpz_poly_factor_init2(fmpz_poly_factor_t fac, slong alloc) Initialises a new factor structure, providing space for at least \code{alloc} factors. void fmpz_poly_factor_realloc(fmpz_poly_factor_t fac, slong alloc) Reallocates the factor structure to provide space for precisely \code{alloc} factors. void fmpz_poly_factor_fit_length(fmpz_poly_factor_t fac, slong len) Ensures that the factor structure has space for at least \code{len} factors. This functions takes care of the case of repeated calls by always at least doubling the number of factors the structure can hold. void fmpz_poly_factor_clear(fmpz_poly_factor_t fac) Releases all memory occupied by the factor structure. ******************************************************************************* Manipulating factors ******************************************************************************* void fmpz_poly_factor_set(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac) Sets \code{res} to the same factorisation as \code{fac}. void fmpz_poly_factor_insert(fmpz_poly_factor_t fac, const fmpz_poly_t p, slong e) Adds the primitive polynomial $p^e$ to the factorisation \code{fac}. Assumes that $\deg(p) \geq 2$ and $e \neq 0$. void fmpz_poly_factor_concat(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac) Concatenates two factorisations. This is equivalent to calling \code{fmpz_poly_factor_insert()} repeatedly with the individual factors of \code{fac}. Does not support aliasing between \code{res} and \code{fac}. ******************************************************************************* Input and output ******************************************************************************* void fmpz_poly_factor_print(const fmpz_poly_factor_t fac) Prints the entries of \code{fac} to standard output. ******************************************************************************* Factoring algorithms ******************************************************************************* void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, fmpz_poly_t F) Takes as input a polynomial $F$ and a freshly initialized factor structure \code{fac}. Updates \code{fac} to contain a factorization of $F$ into (not necessarily irreducible) factors that themselves have no repeated factors. None of the returned factors will have the same exponent. That is we return $g_i$ and unique $e_i$ such that \begin{equation*} F = c \prod_{i} g_i^{e_i} \end{equation*} where $c$ is the signed content of $F$ and $\gcd(g_i, g_i') = 1$. 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) Takes as input a factor structure \code{lifted_fac} containing a squarefree factorization of the polynomial $F \bmod p$. The algorithm does a brute force search for irreducible factors of $F$ over the integers, and each factor is raised to the power \code{exp}. The impact of the algorithm is to augment a factorization of \code{F^exp} to the factor structure \code{final_fac}. void _fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, slong exp, fmpz_poly_t f, slong cutoff) This is the internal wrapper of Zassenhaus. It will attempt to find a small prime such that $f$ modulo $p$ has a minimal number of factors. If it cannot find a prime giving less than \code{cutoff} factors it aborts. Then it decides a $p$-adic precision to lift the factors to, hensel lifts, and finally calls Zassenhaus recombination. Assumes that $\len(f) \geq 2$. Assumes that $f$ is primitive. Assumes that the constant coefficient of $f$ is non-zero. Note that this can be easily achieved by taking out factors of the form $x^k$ before calling this routine. void fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, fmpz_poly_t F) A wrapper of the Zassenhaus factoring algorithm, which takes as input any polynomial $F$, and stores a factorization in \code{final_fac}. The complexity will be exponential in the number of local factors we find for the components of a squarefree factorization of $F$.