ALL: Add flint

This commit is contained in:
2014-05-19 00:03:37 +02:00
parent a15ef46ea6
commit d51d8e3652
3752 changed files with 446416 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <gmp.h>
#include "flint.h"
#include "nmod_poly.h"
void
nmod_poly_factor_clear(nmod_poly_factor_t fac)
{
slong i;
for (i = 0; i < fac->alloc; i++)
nmod_poly_clear(fac->p + i);
flint_free(fac->p);
flint_free(fac->exp);
}

View File

@@ -0,0 +1,40 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <gmp.h>
#include "flint.h"
#include "nmod_poly.h"
void
nmod_poly_factor_concat(nmod_poly_factor_t res, const nmod_poly_factor_t fac)
{
slong i;
for (i = 0; i < fac->num; i++)
nmod_poly_factor_insert(res, fac->p + i, fac->exp[i]);
}

View File

@@ -0,0 +1,218 @@
/*=============================================================================
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) 2010 William Hart
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2011 Sebastian Pancratz
******************************************************************************/
*******************************************************************************
Factorisation
*******************************************************************************
void nmod_poly_factor_init(nmod_poly_factor_t fac)
Initialises \code{fac} for use. An \code{nmod_poly_factor_t}
represents a polynomial in factorised form as a product of
polynomials with associated exponents.
void nmod_poly_factor_clear(nmod_poly_factor_t fac)
Frees all memory associated with \code{fac}.
void nmod_poly_factor_realloc(nmod_poly_factor_t fac, slong alloc)
Reallocates the factor structure to provide space for
precisely \code{alloc} factors.
void nmod_poly_factor_fit_length(nmod_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 nmod_poly_factor_set(nmod_poly_factor_t res, const nmod_poly_factor_t fac)
Sets \code{res} to the same factorisation as \code{fac}.
void nmod_poly_factor_print(const nmod_poly_factor_t fac)
Prints the entries of \code{fac} to standard output.
void nmod_poly_factor_insert(nmod_poly_factor_t fac,
const nmod_poly_t poly, slong exp)
Inserts the factor \code{poly} with multiplicity \code{exp} into
the factorisation \code{fac}.
If \code{fac} already contains \code{poly}, then \code{exp} simply
gets added to the exponent of the existing entry.
void nmod_poly_factor_concat(nmod_poly_factor_t res,
const nmod_poly_factor_t fac)
Concatenates two factorisations.
This is equivalent to calling \code{nmod_poly_factor_insert()}
repeatedly with the individual factors of \code{fac}.
Does not support aliasing between \code{res} and \code{fac}.
void nmod_poly_factor_pow(nmod_poly_factor_t fac, slong exp)
Raises \code{fac} to the power \code{exp}.
ulong nmod_poly_remove(nmod_poly_t f, const nmod_poly_t p)
Removes the highest possible power of \code{p} from \code{f} and
returns the exponent.
int nmod_poly_is_irreducible(const nmod_poly_t f)
Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0.
int nmod_poly_is_irreducible_ddf(const nmod_poly_t f)
Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0.
Uses fast distinct-degree factorisation.
int nmod_poly_is_irreducible_rabin(const nmod_poly_t f)
Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0.
Uses Rabin irreducibility test.
int _nmod_poly_is_squarefree(mp_srcptr f, slong len, nmod_t mod)
Returns 1 if \code{(f, len)} is squarefree, and 0 otherwise. As a
special case, the zero polynomial is not considered squarefree.
There are no restrictions on the length.
int nmod_poly_is_squarefree(const nmod_poly_t f)
Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special
case, the zero polynomial is not considered squarefree.
void nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f)
Sets \code{res} to a square-free factorization of \code{f}.
int nmod_poly_factor_equal_deg_prob(nmod_poly_t factor,
flint_rand_t state, const nmod_poly_t pol, slong d)
Probabilistic equal degree factorisation of \code{pol} into
irreducible factors of degree \code{d}. If it passes, a factor is
placed in factor and 1 is returned, otherwise 0 is returned and
the value of factor is undetermined.
Requires that \code{pol} be monic, non-constant and squarefree.
void nmod_poly_factor_equal_deg(nmod_poly_factor_t factors,
const nmod_poly_t pol, slong d)
Assuming \code{pol} is a product of irreducible factors all of
degree \code{d}, finds all those factors and places them in factors.
Requires that \code{pol} be monic, non-constant and squarefree.
void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res,
const nmod_poly_t poly, slong * const *degs)
Factorises a monic non-constant squarefree polymnomial \code{poly}
of degree n into factors $f[d]$ such that for $1 \leq d \leq n$
$f[d]$ is the product of the monic irreducible factors of \code{poly}
of degree $d$. Factors $f[d]$ are stored in \code{res}, and the degree $d$
of the irreducible factors is stored in \code{degs} in the same order
as the factors.
Requires that \code{degs} has enough space for $(n/2)+1 * sizeof(slong)$.
void nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res,
const nmod_poly_t f)
Factorises a non-constant polynomial \code{f} into monic irreducible
factors using the Cantor-Zassenhaus algorithm.
void nmod_poly_factor_berlekamp(nmod_poly_factor_t res, const nmod_poly_t f)
Factorises a non-constant, squarefree polynomial \code{f} into monic
irreducible factors using the Berlekamp algorithm.
void nmod_poly_factor_kaltofen_shoup(nmod_poly_factor_t res,
const nmod_poly_t poly)
Factorises a non-constant polynomial \code{f} into monic irreducible
factors using the fast version of Cantor-Zassenhaus algorithm proposed by
Kaltofen and Shoup (1998). More precisely this algorithm uses a
“baby step/giant step” strategy for the distinct-degree factorization
step.
mp_limb_t nmod_poly_factor_with_berlekamp(nmod_poly_factor_t res,
const nmod_poly_t f)
Factorises a general polynomial \code{f} into monic irreducible factors
and returns the leading coefficient of \code{f}, or 0 if \code{f}
is the zero polynomial.
This function first checks for small special cases, deflates \code{f}
if it is of the form $p(x^m)$ for some $m > 1$, then performs a
square-free factorisation, and finally runs Berlekamp on all the
individual square-free factors.
mp_limb_t nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t res,
const nmod_poly_t f)
Factorises a general polynomial \code{f} into monic irreducible factors
and returns the leading coefficient of \code{f}, or 0 if \code{f}
is the zero polynomial.
This function first checks for small special cases, deflates \code{f}
if it is of the form $p(x^m)$ for some $m > 1$, then performs a
square-free factorisation, and finally runs Cantor-Zassenhaus on all the
individual square-free factors.
mp_limb_t nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t res,
const nmod_poly_t f)
Factorises a general polynomial \code{f} into monic irreducible factors
and returns the leading coefficient of \code{f}, or 0 if \code{f}
is the zero polynomial.
This function first checks for small special cases, deflates \code{f}
if it is of the form $p(x^m)$ for some $m > 1$, then performs a
square-free factorisation, and finally runs Kaltofen-Shoup on all the
individual square-free factors.
mp_limb_t nmod_poly_factor(nmod_poly_factor_t res, const nmod_poly_t f)
Factorises a general polynomial \code{f} into monic irreducible factors
and returns the leading coefficient of \code{f}, or 0 if \code{f}
is the zero polynomial.
This function first checks for small special cases, deflates \code{f}
if it is of the form $p(x^m)$ for some $m > 1$, then performs a
square-free factorisation, and finally runs either Cantor-Zassenhaus
or Berlekamp on all the individual square-free factors.
Currently Cantor-Zassenhaus is used by default unless the modulus is 2, in
which case Berlekamp is used.

View File

@@ -0,0 +1,191 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <gmp.h>
#include <math.h>
#include "flint.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
#define ZASSENHAUS 0
#define BERLEKAMP 1
#define KALTOFEN 2
static __inline__ void
__nmod_poly_factor1(nmod_poly_factor_t res, const nmod_poly_t f, int algorithm)
{
if (algorithm == KALTOFEN)
nmod_poly_factor_kaltofen_shoup(res, f);
else if (algorithm == ZASSENHAUS)
nmod_poly_factor_cantor_zassenhaus(res, f);
else
nmod_poly_factor_berlekamp(res, f);
}
mp_limb_t
__nmod_poly_factor(nmod_poly_factor_t result,
const nmod_poly_t input, int algorithm)
{
nmod_poly_t monic_input;
nmod_poly_factor_t sqfree_factors, factors;
mp_limb_t leading_coeff;
slong i, len;
len = input->length;
if (len <= 1)
{
if (len == 0)
return 0;
else
return input->coeffs[0];
}
leading_coeff = *nmod_poly_lead(input);
nmod_poly_init_preinv(monic_input, input->mod.n, input->mod.ninv);
nmod_poly_make_monic(monic_input, input);
if (len == 2)
{
nmod_poly_factor_insert(result, monic_input, 1);
nmod_poly_clear(monic_input);
return input->coeffs[1];
}
nmod_poly_factor_init(sqfree_factors);
nmod_poly_factor_squarefree(sqfree_factors, monic_input);
nmod_poly_clear(monic_input);
/* Run CZ on each of the square-free factors */
for (i = 0; i < sqfree_factors->num; i++)
{
nmod_poly_factor_init(factors);
__nmod_poly_factor1(factors, sqfree_factors->p + i, algorithm);
nmod_poly_factor_pow(factors, sqfree_factors->exp[i]);
nmod_poly_factor_concat(result, factors);
nmod_poly_factor_clear(factors);
}
nmod_poly_factor_clear(sqfree_factors);
return leading_coeff;
}
mp_limb_t
__nmod_poly_factor_deflation(nmod_poly_factor_t result,
const nmod_poly_t input, int algorithm)
{
slong i;
ulong deflation;
if (input->length <= 1)
{
if (input->length == 0)
return 0;
else
return input->coeffs[0];
}
deflation = nmod_poly_deflation(input);
if (deflation == 1)
{
return __nmod_poly_factor(result, input, algorithm);
}
else
{
nmod_poly_factor_t def_res;
nmod_poly_t def;
mp_limb_t leading_coeff;
nmod_poly_init_preinv(def, input->mod.n, input->mod.ninv);
nmod_poly_deflate(def, input, deflation);
nmod_poly_factor_init(def_res);
leading_coeff = __nmod_poly_factor(def_res, def, algorithm);
nmod_poly_clear(def);
for (i = 0; i < def_res->num; i++)
{
/* Inflate */
nmod_poly_t pol;
nmod_poly_init_preinv(pol, input->mod.n, input->mod.ninv);
nmod_poly_inflate(pol, def_res->p + i, deflation);
/* Factor inflation */
if (def_res->exp[i] == 1)
__nmod_poly_factor(result, pol, algorithm);
else
{
nmod_poly_factor_t t;
nmod_poly_factor_init(t);
__nmod_poly_factor(t, pol, algorithm);
nmod_poly_factor_pow(t, def_res->exp[i]);
nmod_poly_factor_concat(result, t);
nmod_poly_factor_clear(t);
}
nmod_poly_clear(pol);
}
nmod_poly_factor_clear(def_res);
return leading_coeff;
}
}
mp_limb_t
nmod_poly_factor_with_berlekamp(nmod_poly_factor_t result,
const nmod_poly_t input)
{
return __nmod_poly_factor_deflation(result, input, BERLEKAMP);
}
mp_limb_t
nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t result,
const nmod_poly_t input)
{
return __nmod_poly_factor_deflation(result, input, ZASSENHAUS);
}
mp_limb_t
nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t result,
const nmod_poly_t input)
{
return __nmod_poly_factor_deflation(result, input, KALTOFEN);
}
mp_limb_t
nmod_poly_factor(nmod_poly_factor_t result, const nmod_poly_t input)
{
mp_limb_t p = input->mod.n;
unsigned int bits = FLINT_BIT_COUNT (p);
slong n = nmod_poly_degree(input);
if (n < 10 + 50 / bits)
return __nmod_poly_factor_deflation(result, input, ZASSENHAUS);
else
return __nmod_poly_factor_deflation(result, input, KALTOFEN);
}

View File

@@ -0,0 +1,238 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
#include "nmod_mat.h"
#include "ulong_extras.h"
#include "profiler.h"
#include "perm.h"
static void
nmod_poly_to_nmod_mat_col(nmod_mat_t mat, slong col, nmod_poly_t poly)
{
slong i;
for (i = 0; i < poly->length; i++)
nmod_mat_entry(mat, i, col) = poly->coeffs[i];
for ( ; i < mat->r; i++)
nmod_mat_entry(mat, i, col) = UWORD(0);
}
static void
nmod_mat_col_to_nmod_poly_shifted(nmod_poly_t poly, nmod_mat_t mat,
slong col, slong * shift)
{
slong i, j, rows = mat->r;
nmod_poly_fit_length(poly, rows);
for (i = 0, j = 0; j < rows; j++)
{
if (shift[j])
poly->coeffs[j] = 0;
else
{
poly->coeffs[j] = nmod_mat_entry(mat, i, col);
i++;
}
}
poly->length = rows;
_nmod_poly_normalise(poly);
}
static void
__nmod_poly_factor_berlekamp(nmod_poly_factor_t factors,
flint_rand_t state, const nmod_poly_t f)
{
const mp_limb_t p = nmod_poly_modulus(f);
const slong n = nmod_poly_degree(f);
nmod_poly_factor_t fac1, fac2;
nmod_poly_t x, x_p;
nmod_poly_t x_pi, x_pi2;
nmod_poly_t Q;
nmod_mat_t matrix;
mp_limb_t coeff;
slong i, nullity, col, row, *shift;
nmod_poly_t *basis;
if (f->length <= 2)
{
nmod_poly_factor_insert(factors, f, 1);
return;
}
/* Step 1, we compute x^p mod f in F_p[X]/<f> */
nmod_poly_init(x, p);
nmod_poly_init(x_p, p);
nmod_poly_set_coeff_ui(x, 1, 1);
nmod_poly_powmod_ui_binexp(x_p, x, p, f);
nmod_poly_clear(x);
/* Step 2, compute the matrix for the Berlekamp Map */
nmod_mat_init(matrix, n, n, p);
nmod_poly_init(x_pi, p);
nmod_poly_init(x_pi2, p);
nmod_poly_set_coeff_ui(x_pi, 0, 1);
for (i = 0; i < n; i++)
{
/* Q - I */
nmod_poly_set(x_pi2, x_pi);
coeff = nmod_poly_get_coeff_ui(x_pi2, i);
if (coeff)
nmod_poly_set_coeff_ui(x_pi2, i, coeff - 1);
else
nmod_poly_set_coeff_ui(x_pi2, i, p - 1);
nmod_poly_to_nmod_mat_col(matrix, i, x_pi2);
nmod_poly_mulmod(x_pi, x_pi, x_p, f);
}
nmod_poly_clear(x_p);
nmod_poly_clear(x_pi);
nmod_poly_clear(x_pi2);
/* Row reduce Q - I */
nullity = n - nmod_mat_rref(matrix);
/* Find a basis for the nullspace */
basis = (nmod_poly_t *) flint_malloc(nullity * sizeof(nmod_poly_t));
shift = (slong *) flint_calloc(n, sizeof(slong));
col = 1; /* first column is always zero */
row = 0;
shift[0] = 1;
for (i = 1; i < nullity; i++)
{
nmod_poly_init(basis[i], p);
while (nmod_mat_entry(matrix, row, col))
{
row++;
col++;
}
nmod_mat_col_to_nmod_poly_shifted(basis[i], matrix, col, shift);
nmod_poly_set_coeff_ui(basis[i], col, p - 1);
shift[col] = 1;
col++;
}
flint_free(shift);
nmod_mat_clear(matrix);
/* we are done */
if (nullity == 1)
{
nmod_poly_factor_insert(factors, f, 1);
flint_free(basis);
}
else
{
/* Generate random linear combinations */
nmod_poly_t factor, b, power, g;
nmod_poly_init(factor, p);
nmod_poly_init(b, p);
nmod_poly_init(power, p);
nmod_poly_init(g, p);
while (1)
{
do
{
nmod_poly_zero(factor);
for (i = 1; i < nullity; i++)
{
nmod_poly_scalar_mul_nmod(b, basis[i], n_randint(state, p));
nmod_poly_add(factor, factor, b);
}
nmod_poly_set_coeff_ui(factor, 0, n_randint(state, p));
if (!nmod_poly_is_zero(factor))
nmod_poly_make_monic(factor, factor);
}
while (nmod_poly_is_one(factor) || nmod_poly_is_zero(factor));
nmod_poly_gcd(g, f, factor);
if (nmod_poly_length(g) != 1) break;
if (p > 3)
nmod_poly_powmod_ui_binexp(power, factor, p >> 1, f);
else
nmod_poly_set(power, factor);
power->coeffs[0] = n_addmod(power->coeffs[0], p - 1, p);
_nmod_poly_normalise(power);
nmod_poly_gcd(g, power, f);
if (nmod_poly_length(g) != 1)
break;
}
for (i = 1; i < nullity; i++)
nmod_poly_clear(basis[i]);
flint_free(basis);
nmod_poly_clear(power);
nmod_poly_clear(factor);
nmod_poly_clear(b);
if (!nmod_poly_is_zero(g))
nmod_poly_make_monic(g, g);
nmod_poly_factor_init(fac1);
nmod_poly_factor_init(fac2);
__nmod_poly_factor_berlekamp(fac1, state, g);
nmod_poly_init(Q, p);
nmod_poly_div(Q, f, g);
if (!nmod_poly_is_zero(Q))
nmod_poly_make_monic(Q, Q);
__nmod_poly_factor_berlekamp(fac2, state, Q);
nmod_poly_factor_concat(factors, fac1);
nmod_poly_factor_concat(factors, fac2);
nmod_poly_factor_clear(fac1);
nmod_poly_factor_clear(fac2);
nmod_poly_clear(Q);
nmod_poly_clear(g);
}
}
void
nmod_poly_factor_berlekamp(nmod_poly_factor_t factors, const nmod_poly_t f)
{
flint_rand_t r;
flint_randinit(r);
__nmod_poly_factor_berlekamp(factors, r, f);
flint_randclear(r);
}

View File

@@ -0,0 +1,76 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "nmod_poly.h"
void
nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res, const nmod_poly_t f)
{
nmod_poly_t h, v, g, x;
slong i, j, num;
nmod_poly_init_preinv(h, f->mod.n, f->mod.ninv);
nmod_poly_init_preinv(g, f->mod.n, f->mod.ninv);
nmod_poly_init_preinv(v, f->mod.n, f->mod.ninv);
nmod_poly_init_preinv(x, f->mod.n, f->mod.ninv);
nmod_poly_set_coeff_ui(h, 1, 1);
nmod_poly_set_coeff_ui(x, 1, 1);
nmod_poly_make_monic(v, f);
i = 0;
do
{
i++;
nmod_poly_powmod_ui_binexp(h, h, f->mod.n, v);
nmod_poly_sub(h, h, x);
nmod_poly_gcd(g, h, v);
nmod_poly_add(h, h, x);
if (g->length != 1)
{
nmod_poly_make_monic(g, g);
num = res->num;
nmod_poly_factor_equal_deg(res, g, i);
for (j = num; j < res->num; j++)
res->exp[j] = nmod_poly_remove(v, res->p + j);
}
}
while (v->length >= 2*i + 3);
if (v->length > 1)
nmod_poly_factor_insert(res, v, 1);
nmod_poly_clear(g);
nmod_poly_clear(h);
nmod_poly_clear(v);
nmod_poly_clear(x);
}

View File

@@ -0,0 +1,213 @@
/*=============================================================================
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) 2012 Lina Kulakova
Copyright (C) 2013 Martin Lee
******************************************************************************/
#undef ulong
#define ulong ulongxx/* interferes with system includes */
#include <math.h>
#undef ulong
#include <gmp.h>
#define ulong mp_limb_t
#include "nmod_poly.h"
void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res,
const nmod_poly_t poly, slong * const *degs)
{
nmod_poly_t f, g, v, vinv, reducedH0, tmp;
nmod_poly_t *h, *H, *I;
slong i, j, l, m, n, index, d;
nmod_mat_t HH, HHH;
double beta;
n = nmod_poly_degree(poly);
nmod_poly_init_preinv(v, poly->mod.n, poly->mod.ninv);
nmod_poly_make_monic(v, poly);
if (n == 1)
{
nmod_poly_factor_insert (res, v, 1);
(*degs)[0]= 1;
nmod_poly_clear (v);
return;
}
beta = 0.5 * (1. - (log(2) / log(n)));
l = ceil(pow (n, beta));
m = ceil(0.5 * n / l);
/* initialization */
nmod_poly_init_preinv(f, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(g, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(vinv, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(reducedH0, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(tmp, poly->mod.n, poly->mod.ninv);
if (!(h = flint_malloc((2 * m + l + 1) * sizeof(nmod_poly_struct))))
{
flint_printf("Exception (nmod_poly_factor_distinct_deg):\n");
flint_printf("Not enough memory.\n");
abort();
}
H = h + (l + 1);
I = H + m;
for (i = 0; i < l + 1; i++)
nmod_poly_init_preinv(h[i], poly->mod.n, poly->mod.ninv);
for (i = 0; i < m; i++)
{
nmod_poly_init_preinv(H[i], poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(I[i], poly->mod.n, poly->mod.ninv);
}
nmod_poly_reverse(vinv, v, v->length);
nmod_poly_inv_series(vinv, vinv, v->length);
/* compute baby steps: h[i]=x^{p^i}mod v */
nmod_poly_set_coeff_ui(h[0], 1, 1);
nmod_poly_powmod_x_ui_preinv(h[1], poly->mod.n, v, vinv);
if (FLINT_BIT_COUNT(poly->mod.n) > ((n_sqrt(v->length - 1) + 1) * 3) / 4)
{
nmod_mat_init(HH, n_sqrt (v->length - 1) + 1, v->length - 1,
poly->mod.n);
nmod_poly_precompute_matrix(HH, h[1], v, vinv);
for (i = 2; i < l + 1; i++)
nmod_poly_compose_mod_brent_kung_precomp_preinv(h[i], h[i - 1],
HH, v, vinv);
nmod_mat_clear(HH);
}
else
{
for (i = 2; i < l + 1; i++)
nmod_poly_powmod_ui_binexp_preinv(h[i], h[i - 1], poly->mod.n,
v, vinv);
}
/* compute coarse distinct-degree factorisation */
index = 0;
nmod_poly_set(H[0], h[l]);
nmod_poly_set(reducedH0, H[0]);
nmod_mat_init(HH, n_sqrt(v->length - 1) + 1, v->length - 1, poly->mod.n);
nmod_poly_precompute_matrix(HH, reducedH0, v, vinv);
d = 1;
for (j = 0; j < m; j++)
{
/* compute giant steps: H[j]=x^{p^(lj)}mod v */
if (j > 0)
{
if (I[j - 1]->length > 1)
{
_nmod_poly_reduce_matrix_mod_poly(HHH, HH, v);
nmod_mat_clear(HH);
nmod_mat_init_set(HH, HHH);
nmod_mat_clear(HHH);
nmod_poly_rem(reducedH0, reducedH0, v);
nmod_poly_rem(tmp, H[j - 1], v);
nmod_poly_compose_mod_brent_kung_precomp_preinv(H[j], tmp, HH,
v, vinv);
}
else
nmod_poly_compose_mod_brent_kung_precomp_preinv(H[j], H[j - 1],
HH, v, vinv);
}
/* compute interval polynomials */
nmod_poly_set_coeff_ui(I[j], 0, 1);
for (i = l - 1; (i >= 0) && (2 * d <= v->length - 1); i--, d++)
{
nmod_poly_rem(tmp, h[i], v);
nmod_poly_sub(tmp, H[j], tmp);
nmod_poly_mulmod_preinv(I[j], tmp, I[j], v, vinv);
}
/* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */
/* F_j is stored on the place of I_j */
nmod_poly_gcd(I[j], v, I[j]);
if (I[j]->length > 1)
{
nmod_poly_remove(v, I[j]);
nmod_poly_reverse(vinv, v, v->length);
nmod_poly_inv_series(vinv, vinv, v->length);
}
if (v->length - 1 < 2 * d)
{
break;
}
}
if (v->length > 1)
{
nmod_poly_factor_insert(res, v, 1);
(*degs)[index++] = v->length - 1;
}
/* compute fine distinct-degree factorisation */
for (j = 0; j < m; j++)
{
if (I[j]->length - 1 > (j + 1) * l || j == 0)
{
nmod_poly_set(g, I[j]);
for (i = l - 1; i >= 0 && (g->length > 1); i-- )
{
/* compute f^{[l*(j+1)-i]} */
nmod_poly_sub(tmp, H[j], h[i]);
nmod_poly_gcd(f, g, tmp);
if (f->length > 1)
{
/* insert f^{[l*(j+1)-i]} into res */
nmod_poly_make_monic(f, f);
nmod_poly_factor_insert(res, f, 1);
(*degs)[index++] = l * (j + 1) - i;
nmod_poly_remove(g, f);
}
}
}
else if (I[j]->length > 1)
{
nmod_poly_make_monic(I[j], I[j]);
nmod_poly_factor_insert(res, I[j], 1);
(*degs)[index++] = I[j]->length-1;
}
}
/* cleanup */
nmod_poly_clear(f);
nmod_poly_clear(g);
nmod_poly_clear(reducedH0);
nmod_poly_clear(v);
nmod_poly_clear(vinv);
nmod_poly_clear(tmp);
nmod_mat_clear (HH);
for (i = 0; i < l + 1; i++)
nmod_poly_clear(h[i]);
for (i = 0; i < m; i++)
{
nmod_poly_clear(H[i]);
nmod_poly_clear(I[i]);
}
flint_free(h);
}

View File

@@ -0,0 +1,61 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "nmod_poly.h"
#include "ulong_extras.h"
void
nmod_poly_factor_equal_deg(nmod_poly_factor_t factors,
const nmod_poly_t pol, slong d)
{
if (pol->length == d + 1)
{
nmod_poly_factor_insert(factors, pol, 1);
}
else
{
nmod_poly_t f, g;
flint_rand_t state;
nmod_poly_init_preinv(f, pol->mod.n, pol->mod.ninv);
flint_randinit(state);
while (!nmod_poly_factor_equal_deg_prob(f, state, pol, d)) {};
flint_randclear(state);
nmod_poly_init_preinv(g, pol->mod.n, pol->mod.ninv);
nmod_poly_div(g, pol, f);
nmod_poly_factor_equal_deg(factors, f, d);
nmod_poly_clear(f);
nmod_poly_factor_equal_deg(factors, g, d);
nmod_poly_clear(g);
}
}

View File

@@ -0,0 +1,107 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include "nmod_poly.h"
#include "ulong_extras.h"
int
nmod_poly_factor_equal_deg_prob(nmod_poly_t factor,
flint_rand_t state, const nmod_poly_t pol, slong d)
{
nmod_poly_t a, b, c, polinv;
mpz_t exp;
int res = 1;
slong i;
if (pol->length <= 1)
{
flint_printf("Exception (nmod_poly_factor_equal_deg_prob). \n");
flint_printf("Input polynomial is linear.\n");
abort();
}
nmod_poly_init_preinv(a, pol->mod.n, pol->mod.ninv);
do {
nmod_poly_randtest(a, state, pol->length - 1);
} while (a->length <= 1);
nmod_poly_gcd(factor, a, pol);
if (factor->length != 1)
{
nmod_poly_clear(a);
return 1;
}
nmod_poly_init_preinv(b, pol->mod.n, pol->mod.ninv);
nmod_poly_init_preinv(polinv, pol->mod.n, pol->mod.ninv);
nmod_poly_reverse(polinv, pol, pol->length);
nmod_poly_inv_series(polinv, polinv, polinv->length);
mpz_init(exp);
if (pol->mod.n > 2)
{
/* compute a^{(p^d-1)/2} rem pol */
flint_mpz_ui_pow_ui(exp, pol->mod.n, d);
flint_mpz_sub_ui(exp, exp, 1);
mpz_tdiv_q_2exp(exp, exp, 1);
nmod_poly_powmod_mpz_binexp_preinv(b, a, exp, pol, polinv);
}
else
{
/* compute b = (a^{2^{d-1}}+a^{2^{d-2}}+...+a^4+a^2+a) rem pol */
nmod_poly_rem(b, a, pol);
nmod_poly_init_preinv(c, pol->mod.n, pol->mod.ninv);
nmod_poly_set(c, b);
for (i = 1; i < d; i++)
{
/* c = a^{2^i} = (a^{2^{i-1}})^2 */
nmod_poly_powmod_ui_binexp_preinv(c, c, 2, pol, polinv);
nmod_poly_add(b, b, c);
}
nmod_poly_rem(b, b, pol);
nmod_poly_clear(c);
}
mpz_clear(exp);
b->coeffs[0] = n_submod(b->coeffs[0], 1, pol->mod.n);
nmod_poly_gcd(factor, b, pol);
if ((factor->length <= 1) || (factor->length == pol->length)) res = 0;
nmod_poly_clear(polinv);
nmod_poly_clear(a);
nmod_poly_clear(b);
return res;
}

View File

@@ -0,0 +1,82 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <math.h>
#include "nmod_poly.h"
void nmod_poly_factor_kaltofen_shoup(nmod_poly_factor_t res,
const nmod_poly_t poly)
{
nmod_poly_t v;
nmod_poly_factor_t sq_free, dist_deg;
slong i, j, k, l, res_num, dist_deg_num;
slong *degs;
nmod_poly_init_preinv(v, poly->mod.n, poly->mod.ninv);
nmod_poly_make_monic(v, poly);
if (poly->length <= 2)
{
nmod_poly_factor_insert (res, v, 1);
nmod_poly_clear (v);
return;
}
if (!(degs = flint_malloc(nmod_poly_degree(poly) * sizeof(slong))))
{
flint_printf("Exception (nmod_poly_factor_kaltofen_shoup): \n");
flint_printf("Not enough memory.\n");
abort();
}
/* compute squarefree factorisation */
nmod_poly_factor_init(sq_free);
nmod_poly_factor_squarefree(sq_free, v);
/* compute distinct-degree factorisation */
nmod_poly_factor_init(dist_deg);
for (i = 0; i < sq_free->num; i++)
{
dist_deg_num = dist_deg->num;
nmod_poly_factor_distinct_deg(dist_deg, sq_free->p + i, &degs);
/* compute equal-degree factorisation */
for (j = dist_deg_num, l = 0; j < dist_deg->num; j++, l++)
{
res_num = res->num;
nmod_poly_factor_equal_deg(res, dist_deg->p + j, degs[l]);
for (k = res_num; k < res->num; k++)
res->exp[k] = nmod_poly_remove(v, res->p + k);
}
}
flint_free(degs);
nmod_poly_clear(v);
nmod_poly_factor_clear(dist_deg);
nmod_poly_factor_clear(sq_free);
}

View File

@@ -0,0 +1,150 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "nmod_poly.h"
#include "ulong_extras.h"
void
nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f)
{
nmod_poly_t f_d, g, g_1;
mp_limb_t p;
slong deg, i;
if (f->length <= 1)
{
res->num = 0;
return;
}
if (f->length == 2)
{
nmod_poly_factor_insert(res, f, 1);
return;
}
p = nmod_poly_modulus(f);
deg = nmod_poly_degree(f);
/* Step 1, look at f', if it is zero then we are done since f = h(x)^p
for some particular h(x), clearly f(x) = sum a_k x^kp, k <= deg(f) */
nmod_poly_init(g_1, p);
nmod_poly_init(f_d, p);
nmod_poly_init(g, p);
nmod_poly_derivative(f_d, f);
/* Case 1 */
if (nmod_poly_is_zero(f_d))
{
nmod_poly_factor_t new_res;
nmod_poly_t h;
nmod_poly_init(h, p);
for (i = 0; i <= deg / p; i++) /* this will be an integer since f'=0 */
{
nmod_poly_set_coeff_ui(h, i, nmod_poly_get_coeff_ui(f, i * p));
}
/* Now run square-free on h, and return it to the pth power */
nmod_poly_factor_init(new_res);
nmod_poly_factor_squarefree(new_res, h);
nmod_poly_factor_pow(new_res, p);
nmod_poly_factor_concat(res, new_res);
nmod_poly_clear(h);
nmod_poly_factor_clear(new_res);
}
else
{
nmod_poly_t h, z;
nmod_poly_gcd(g, f, f_d);
nmod_poly_div(g_1, f, g);
i = 1;
nmod_poly_init(h, p);
nmod_poly_init(z, p);
/* Case 2 */
while (!nmod_poly_is_one(g_1))
{
nmod_poly_gcd(h, g_1, g);
nmod_poly_div(z, g_1, h);
/* out <- out.z */
if (z->length > 1)
{
nmod_poly_factor_insert(res, z, 1);
nmod_poly_make_monic(res->p + (res->num - 1),
res->p + (res->num - 1));
if (res->num)
res->exp[res->num - 1] *= i;
}
i++;
nmod_poly_set(g_1, h);
nmod_poly_div(g, g, h);
}
nmod_poly_clear(h);
nmod_poly_clear(z);
nmod_poly_make_monic(g, g);
if (!nmod_poly_is_one(g))
{
/* so now we multiply res with square-free(g^1/p) ^ p */
nmod_poly_t g_p; /* g^(1/p) */
nmod_poly_factor_t new_res_2;
nmod_poly_init(g_p, p);
for (i = 0; i <= nmod_poly_degree(g) / p; i++)
nmod_poly_set_coeff_ui(g_p, i, nmod_poly_get_coeff_ui(g, i*p));
nmod_poly_factor_init(new_res_2);
/* square-free(g^(1/p)) */
nmod_poly_factor_squarefree(new_res_2, g_p);
nmod_poly_factor_pow(new_res_2, p);
nmod_poly_factor_concat(res, new_res_2);
nmod_poly_clear(g_p);
nmod_poly_factor_clear(new_res_2);
}
}
nmod_poly_clear(g_1);
nmod_poly_clear(f_d);
nmod_poly_clear(g);
}

View File

@@ -0,0 +1,39 @@
/*=============================================================================
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 Sebastian Pancratz
Copyright (C) 2008, 2009 William Hart
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
void nmod_poly_factor_fit_length(nmod_poly_factor_t fac, slong len)
{
if (len > fac->alloc)
{
/* At least double number of allocated coeffs */
if (len < 2 * fac->alloc)
len = 2 * fac->alloc;
nmod_poly_factor_realloc(fac, len);
}
}

View File

@@ -0,0 +1,46 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_poly.h"
void
nmod_poly_factor_init(nmod_poly_factor_t fac)
{
slong i;
fac->alloc = 5;
fac->num = 0;
fac->p = flint_malloc(sizeof(nmod_poly_struct) * 5);
fac->exp = flint_malloc(sizeof(slong) * 5);
for (i = 0; i < 5; i++)
nmod_poly_init_preinv(fac->p + i, 1, 0);
}

View File

@@ -0,0 +1,67 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
void
nmod_poly_factor_insert(nmod_poly_factor_t fac,
const nmod_poly_t poly, slong exp)
{
slong i;
if (poly->length <= 1)
return;
for (i = 0; i < fac->num; i++)
{
if (nmod_poly_equal(poly, fac->p + i))
{
fac->exp[i] += exp;
return;
}
}
if (fac->alloc == fac->num)
{
slong new_size = 2 * fac->alloc;
fac->p = flint_realloc(fac->p, sizeof(nmod_poly_struct) * new_size);
fac->exp = flint_realloc(fac->exp, sizeof(slong) * new_size);
for (i = fac->alloc; i < new_size; i++)
nmod_poly_init_preinv(fac->p + i, 1, 0);
fac->alloc = new_size;
}
nmod_poly_set(fac->p + (fac->num), poly);
(fac->p + (fac->num))->mod = poly->mod;
fac->exp[fac->num] = exp;
fac->num++;
}

View File

@@ -0,0 +1,42 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Lina Kulakova
Copyright (C) 2013 Martin Lee
******************************************************************************/
#include "nmod_poly.h"
int
nmod_poly_is_irreducible(const nmod_poly_t f)
{
if (nmod_poly_length(f) > 2)
{
return nmod_poly_is_irreducible_ddf(f);
}
return 1;
}

View File

@@ -0,0 +1,140 @@
/*=============================================================================
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) 2012 Lina Kulakova
Copyright (C) 2013 Martin Lee
******************************************************************************/
#undef ulong
#define ulong ulongxx/* interferes with system includes */
#include <math.h>
#undef ulong
#include <gmp.h>
#define ulong mp_limb_t
#include "nmod_poly.h"
int nmod_poly_is_irreducible_ddf(const nmod_poly_t poly)
{
nmod_poly_t f, v, vinv, reducedH0, tmp;
nmod_poly_t *h, *H, *I;
slong i, j, l, m, n, d;
double beta;
int result= 1;
n = nmod_poly_degree(poly);
if (n < 2)
return 1;
if (!nmod_poly_is_squarefree(poly))
return 0;
beta = 0.5 * (1. - (log(2) / log(n)));
l = ceil(pow (n, beta));
m = ceil(0.5 * n / l);
/* initialization */
nmod_poly_init_preinv(f, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(v, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(vinv, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(reducedH0, poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(tmp, poly->mod.n, poly->mod.ninv);
if (!(h = flint_malloc((2 * m + l + 1) * sizeof(nmod_poly_struct))))
{
flint_printf("Exception (nmod_poly_is_irreducible_ddf):\n");
flint_printf("Not enough memory.\n");
abort();
}
H = h + (l + 1);
I = H + m;
for (i = 0; i < l + 1; i++)
nmod_poly_init_preinv(h[i], poly->mod.n, poly->mod.ninv);
for (i = 0; i < m; i++)
{
nmod_poly_init_preinv(H[i], poly->mod.n, poly->mod.ninv);
nmod_poly_init_preinv(I[i], poly->mod.n, poly->mod.ninv);
}
nmod_poly_make_monic(v, poly);
nmod_poly_reverse(vinv, v, v->length);
nmod_poly_inv_series(vinv, vinv, v->length);
/* compute baby steps: h[i]=x^{p^i}mod v */
nmod_poly_set_coeff_ui(h[0], 1, 1);
for (i = 1; i < l + 1; i++)
nmod_poly_powmod_ui_binexp_preinv(h[i], h[i - 1], poly->mod.n, v, vinv); /* may be for large l use compose_mod instead */
/* compute coarse distinct-degree factorisation */
nmod_poly_set(H[0], h[l]);
nmod_poly_set(reducedH0, H[0]);
d= 1;
for (j = 0; j < m; j++)
{
/* compute giant steps: H[j]=x^{p^(lj)}mod s */
if (j > 0)
{
nmod_poly_rem (reducedH0, reducedH0, v);
nmod_poly_rem (tmp, H[j - 1], v);
nmod_poly_compose_mod_brent_kung_preinv(H[j], tmp, reducedH0, v, vinv);
}
/* compute interval polynomials */
nmod_poly_set_coeff_ui(I[j], 0, 1);
for (i = l - 1; (i >= 0) && (2 * d <= v->length - 1); i--, d++)
{
nmod_poly_rem(tmp, h[i], v);
nmod_poly_sub(tmp, H[j], tmp);
nmod_poly_mulmod_preinv (I[j], tmp, I[j], v, vinv);
}
/* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */
/* F_j is stored on the place of I_j */
nmod_poly_gcd(I[j], v, I[j]);
if (I[j]->length > 1)
{
result= 0;
break;
}
}
nmod_poly_clear(f);
nmod_poly_clear(reducedH0);
nmod_poly_clear(v);
nmod_poly_clear(vinv);
nmod_poly_clear(tmp);
for (i = 0; i < l + 1; i++)
nmod_poly_clear(h[i]);
for (i = 0; i < m; i++)
{
nmod_poly_clear(H[i]);
nmod_poly_clear(I[i]);
}
flint_free (h);
return result;
}

View File

@@ -0,0 +1,111 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "nmod_poly.h"
#include "ulong_extras.h"
void
nmod_poly_powpowmod(nmod_poly_t res, const nmod_poly_t pol,
ulong exp, ulong exp2, const nmod_poly_t f)
{
nmod_poly_t pow;
ulong i;
nmod_poly_init_preinv(pow, f->mod.n, f->mod.ninv);
nmod_poly_powmod_ui_binexp(pow, pol, exp, f);
nmod_poly_set(res, pow);
if (!nmod_poly_equal(pow, pol))
for (i = 1; i < exp2; i++)
nmod_poly_powmod_ui_binexp(res, res, exp, f);
nmod_poly_clear(pow);
}
int
nmod_poly_is_irreducible_rabin(const nmod_poly_t f)
{
if (nmod_poly_length(f) > 2)
{
const mp_limb_t p = nmod_poly_modulus(f);
const slong n = nmod_poly_degree(f);
nmod_poly_t a, x, x_p;
nmod_poly_init(a, p);
nmod_poly_init(x, p);
nmod_poly_init(x_p, p);
nmod_poly_set_coeff_ui(x, 1, 1);
/* Compute x^q mod f */
nmod_poly_powpowmod(x_p, x, p, n, f);
if (!nmod_poly_is_zero(x_p))
nmod_poly_make_monic(x_p, x_p);
/* Now do the irreducibility test */
if (!nmod_poly_equal(x_p, x))
{
nmod_poly_clear(a);
nmod_poly_clear(x);
nmod_poly_clear(x_p);
return 0;
}
else
{
n_factor_t factors;
slong i;
n_factor_init(&factors);
n_factor(&factors, n, 1);
for (i = 0; i < factors.num; i++)
{
nmod_poly_powpowmod(a, x, p, n / factors.p[i], f);
nmod_poly_sub(a, a, x);
if (!nmod_poly_is_zero(a))
nmod_poly_make_monic(a, a);
nmod_poly_gcd(a, a, f);
if (a->length != 1)
{
nmod_poly_clear(a);
nmod_poly_clear(x);
nmod_poly_clear(x_p);
return 0;
}
}
}
nmod_poly_clear(a);
nmod_poly_clear(x);
nmod_poly_clear(x_p);
}
return 1;
}

View File

@@ -0,0 +1,60 @@
/*=============================================================================
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 Fredrik Johansson
******************************************************************************/
#include "nmod_poly.h"
#include "mpn_extras.h"
#include "ulong_extras.h"
int
_nmod_poly_is_squarefree(mp_srcptr f, slong len, nmod_t mod)
{
mp_ptr fd, g;
slong dlen;
int res;
if (len <= 2)
return len != 0;
fd = flint_malloc(sizeof(mp_limb_t) * 2 * (len - 1));
g = fd + len - 1;
_nmod_poly_derivative(fd, f, len, mod);
dlen = len - 1;
MPN_NORM(fd, dlen);
if (dlen)
res = (_nmod_poly_gcd(g, f, len, fd, dlen, mod) == 1);
else
res = 0; /* gcd(f, 0) = f, and len(f) > 2 */
flint_free(fd);
return res;
}
int
nmod_poly_is_squarefree(const nmod_poly_t f)
{
return _nmod_poly_is_squarefree(f->coeffs, f->length, f->mod);
}

View File

@@ -0,0 +1,39 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
void
nmod_poly_factor_pow(nmod_poly_factor_t fac, slong exp)
{
slong i;
for (i = 0; i < fac->num; i++)
fac->exp[i] *= exp;
}

View File

@@ -0,0 +1,44 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_poly.h"
void
nmod_poly_factor_print(const nmod_poly_factor_t fac)
{
slong i;
for (i = 0; i < fac->num; i++)
{
nmod_poly_print(fac->p + i);
flint_printf(" ^ %wd\n", fac->exp[i]);
}
}

View File

@@ -0,0 +1,353 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_poly.h"
#define NP 100 /* number of moduli */
#define ND 8 /* number of degrees */
/*
Benchmarking code for factorisation in nmod_poly.
Test how the relation between n (degree of polynomial) and p
affects working time for Cantor-Zassenhaus, Berlekamp and
Kaltofen-Shoup algorithms. p and n are chosen independently.
*/
int main(void)
{
FLINT_TEST_INIT(state);
nmod_poly_t f, g;
nmod_poly_factor_t res;
mp_limb_t modulus;
int i, j, k, n, num;
double t, T1, T2, T3, T4;
const slong degs[] = {8, 16, 32, 64, 128, 256, 512, 1024};
const int iter_count[] = {10000, 5000, 1000, 500, 300, 100, 50, 20};
flint_printf("Random polynomials\n");
for (i = 0; i < NP; i++)
{
modulus = n_randtest_prime(state, 0);
flint_printf("========== p: %wu\n", modulus);
fflush(stdout);
for (j = 0; j < ND; j++)
{
n = degs[j];
flint_printf(">>>>>n: %d\n", n);
fflush(stdout);
T1 = 0;
T2 = 0;
T3 = 0;
for (k = 0; k < iter_count[j]; k++)
{
nmod_poly_init(f, modulus);
nmod_poly_randtest_not_zero(f, state, n);
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_cantor_zassenhaus(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_berlekamp(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_kaltofen_shoup(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
nmod_poly_clear(f);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
}
/* This code checks whether nmod_poly_factor
made a correct choice between CZ, B and KS */
flint_printf("Check choice correctness\n");
for (i = 0; i < NP; i++)
{
modulus = n_randtest_prime(state, 0);
flint_printf("========== p: %wu\n", modulus);
fflush(stdout);
for (j = 0; j < ND; j++)
{
n = degs[j];
flint_printf(">>>>>n: %d\n", n);
fflush(stdout);
T1 = 0;
T2 = 0;
T3 = 0;
T4 = 0;
for (k = 0; k < iter_count[j]; k++)
{
nmod_poly_init(f, modulus);
nmod_poly_randtest_not_zero(f, state, n);
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_cantor_zassenhaus(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_berlekamp(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_kaltofen_shoup(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T4 += t;
nmod_poly_clear(f);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf F: %.2lf\n", T1, T2, T3, T4);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
}
flint_printf("Irreducible polynomials\n");
for (i = 0; i < NP; i++)
{
modulus = n_randtest_prime(state, 0);
flint_printf("========== p: %wu\n", modulus);
fflush(stdout);
for (j = 0; j < ND; j++)
{
n = degs[j];
flint_printf(">>>>>n: %d\n", n);
fflush(stdout);
T1 = 0;
T2 = 0;
T3 = 0;
for (k = 0; k < iter_count[j]; k++)
{
nmod_poly_init(f, modulus);
nmod_poly_randtest_irreducible(f, state, n);
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_cantor_zassenhaus(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_berlekamp(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_kaltofen_shoup(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
nmod_poly_clear(f);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
}
flint_printf("Product of two irreducible polynomials\n");
for (i = 0; i < NP; i++)
{
modulus = n_randtest_prime(state, 0);
flint_printf("========== p: %wu\n", modulus);
fflush(stdout);
for (j = 0; j < ND; j++)
{
n = (degs[j] >> 1);
flint_printf(">>>>>n: %d\n", n);
fflush(stdout);
T1 = 0;
T2 = 0;
T3 = 0;
for (k = 0; k < iter_count[j]; k++)
{
nmod_poly_init(f, modulus);
nmod_poly_init(g, modulus);
nmod_poly_randtest_irreducible(f, state, n);
nmod_poly_randtest_irreducible(g, state, n);
nmod_poly_mul(f, f, g);
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_cantor_zassenhaus(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_berlekamp(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_kaltofen_shoup(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
nmod_poly_clear(f);
nmod_poly_clear(g);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
}
flint_printf("Product of 8 small irreducible polynomials\n");
for (i = 0; i < NP; i++)
{
modulus = n_randtest_prime(state, 0);
flint_printf("========== p: %wu\n", modulus);
fflush(stdout);
for (j = 1; j < ND; j++)
{
n = (degs[j] >> 3);
flint_printf(">>>>>n: %d\n", n);
fflush(stdout);
T1 = 0;
T2 = 0;
T3 = 0;
for (k = 0; k < iter_count[j]; k++)
{
nmod_poly_init(f, modulus);
nmod_poly_init(g, modulus);
nmod_poly_randtest_irreducible(f, state, n);
for (num = 1; num < 8; num++)
{
nmod_poly_randtest_irreducible(g, state, n);
nmod_poly_mul(f, f, g);
}
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_cantor_zassenhaus(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_with_berlekamp(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
nmod_poly_factor_init(res);
nmod_poly_factor_kaltofen_shoup(res, f);
nmod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
nmod_poly_clear(f);
nmod_poly_clear(g);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
}
flint_randclear(state);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,75 @@
/*=============================================================================
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) 2013 Martin Lee
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_poly.h"
int main (void)
{
double t;
nmod_poly_t f, g, h;
for (int i= 15001;i < 16000; i++)
{
nmod_poly_init2 (f, 17, i/2+1);
nmod_poly_init2 (g, 17, i+1);
nmod_poly_set_coeff_ui (f, i/2, 1);
nmod_poly_set_coeff_ui (f, 1, 1);
nmod_poly_set_coeff_ui (f, 0, ((i%17)*(i%17)+3) % 17);
nmod_poly_set_coeff_ui (g, i, 1);
nmod_poly_set_coeff_ui (g, i/2+1, 1);
nmod_poly_set_coeff_ui (g, 1, ((i % 17)+1)%17);
nmod_poly_set_coeff_ui (g, 0, 15);
nmod_poly_init (h, 17);
nmod_poly_gcd (h, f, g);
if (!nmod_poly_is_one (h))
{
flint_printf ("i= %d\n", i);
nmod_poly_factor_t factors;
nmod_poly_factor_init (factors);
t= clock();
nmod_poly_factor (factors, h);
t = (clock() - t) / CLOCKS_PER_SEC;
flint_printf("factorization %.2lf\n", t);
nmod_poly_factor_clear (factors);
}
nmod_poly_clear (f);
nmod_poly_clear (g);
nmod_poly_clear (h);
}
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,77 @@
/*=============================================================================
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 Sebastian Pancratz
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
void nmod_poly_factor_realloc(nmod_poly_factor_t fac, slong alloc)
{
if (alloc == 0) /* Clear up, reinitialise */
{
nmod_poly_factor_clear(fac);
nmod_poly_factor_init(fac);
}
else if (fac->alloc) /* Realloc */
{
if (fac->alloc > alloc)
{
slong i;
for (i = alloc; i < fac->num; i++)
nmod_poly_clear(fac->p + i);
fac->p = flint_realloc(fac->p, alloc * sizeof(nmod_poly_struct));
fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong));
fac->alloc = alloc;
}
else if (fac->alloc < alloc)
{
slong i;
fac->p = flint_realloc(fac->p, alloc * sizeof(nmod_poly_struct));
fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong));
for (i = fac->alloc; i < alloc; i++)
{
nmod_poly_init_preinv(fac->p + i, 1, 0);
fac->exp[i] = WORD(0);
}
fac->alloc = alloc;
}
}
else /* Nothing allocated already so do it now */
{
slong i;
fac->p = flint_malloc(alloc * sizeof(nmod_poly_struct));
fac->exp = flint_calloc(alloc, sizeof(slong));
for (i = 0; i < alloc; i++)
nmod_poly_init_preinv(fac->p + i, 1, 0);
fac->num = 0;
fac->alloc = alloc;
}
}

View File

@@ -0,0 +1,58 @@
/*=============================================================================
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 Sebastian Pancratz
******************************************************************************/
#include "flint.h"
#include "nmod_poly.h"
void nmod_poly_factor_set(nmod_poly_factor_t res, const nmod_poly_factor_t fac)
{
if (res != fac)
{
if (fac->num == 0)
{
nmod_poly_factor_clear(res);
nmod_poly_factor_init(res);
}
else
{
slong i;
nmod_poly_factor_fit_length(res, fac->num);
for (i = 0; i < fac->num; i++)
{
nmod_poly_set(res->p + i, fac->p + i);
(res->p + i)->mod = (fac->p + i)->mod;
res->exp[i] = fac->exp[i];
}
for ( ; i < res->num; i++)
{
nmod_poly_zero(res->p + i);
res->exp[i] = 0;
}
res->num = fac->num;
}
}
}

View File

@@ -0,0 +1,271 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor....");
fflush(stdout);
/* Default algorithm */
for (iter = 0; iter < 10 * flint_test_multiplier(); iter++)
{
int result = 1;
nmod_poly_t pol1, poly, quot, rem, product;
nmod_poly_factor_t res;
mp_limb_t modulus, lead = 1;
slong length, num, i, j;
ulong exp[5], prod1;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(pol1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(quot, modulus);
nmod_poly_init(rem, modulus);
nmod_poly_zero(pol1);
nmod_poly_set_coeff_ui(pol1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if (poly->length)
nmod_poly_make_monic(poly, poly);
}
while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2));
exp[0] = n_randint(state, 30) + 1;
prod1 = exp[0];
for (i = 0; i < exp[0]; i++)
nmod_poly_mul(pol1, pol1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
nmod_poly_randtest(poly, state, length);
if (poly->length)
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(quot, rem, pol1, poly);
}
}
while ((!nmod_poly_is_irreducible(poly)) ||
(poly->length < 2) || (rem->length == 0));
exp[i] = n_randint(state, 30) + 1;
prod1 *= exp[i];
for (j = 0; j < exp[i]; j++)
nmod_poly_mul(pol1, pol1, poly);
}
nmod_poly_factor_init(res);
switch (n_randint(state, 3))
{
case 0:
lead = nmod_poly_factor(res, pol1);
break;
case 1:
lead = nmod_poly_factor_with_berlekamp(res, pol1);
break;
case 2:
if (modulus == 2)
lead = nmod_poly_factor(res, pol1);
else
lead = nmod_poly_factor_with_cantor_zassenhaus(res, pol1);
break;
}
result &= (res->num == num);
if (!result)
{
flint_printf("Error: number of factors incorrect, %wd, %wd\n",
res->num, num);
abort();
}
nmod_poly_init(product, pol1->mod.n);
nmod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
nmod_poly_mul(product, product, res->p + i);
nmod_poly_scalar_mul_nmod(product, product, lead);
result &= nmod_poly_equal(pol1, product);
if (!result)
{
flint_printf("Error: product of factors does not equal original polynomial\n");
nmod_poly_print(pol1); flint_printf("\n");
nmod_poly_print(product); flint_printf("\n");
abort();
}
nmod_poly_clear(product);
nmod_poly_clear(quot);
nmod_poly_clear(rem);
nmod_poly_clear(pol1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
}
/* Test deflation trick */
for (iter = 0; iter < 10 * flint_test_multiplier(); iter++)
{
nmod_poly_t pol1, poly, quot, rem;
nmod_poly_factor_t res, res2;
mp_limb_t modulus;
slong length, num, i, j;
slong exp[5], prod1;
ulong inflation;
int found;
do {
modulus = n_randtest_prime(state, 0);
} while (modulus == 2); /* To compare with CZ */
nmod_poly_init(pol1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(quot, modulus);
nmod_poly_init(rem, modulus);
nmod_poly_zero(pol1);
nmod_poly_set_coeff_ui(pol1, 0, 1);
inflation = n_randint(state, 7) + 1;
length = n_randint(state, 7) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if (poly->length)
nmod_poly_make_monic(poly, poly);
}
while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2));
nmod_poly_inflate(poly, poly, inflation);
exp[0] = n_randint(state, 6) + 1;
prod1 = exp[0];
for (i = 0; i < exp[0]; i++)
nmod_poly_mul(pol1, pol1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 6) + 2;
nmod_poly_randtest(poly, state, length);
if (poly->length)
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(quot, rem, pol1, poly);
}
}
while ((!nmod_poly_is_irreducible(poly)) ||
(poly->length < 2) || (rem->length == 0));
exp[i] = n_randint(state, 6) + 1;
prod1 *= exp[i];
nmod_poly_inflate(poly, poly, inflation);
for (j = 0; j < exp[i]; j++)
nmod_poly_mul(pol1, pol1, poly);
}
nmod_poly_factor_init(res);
nmod_poly_factor_init(res2);
switch (n_randint(state, 3))
{
case 0:
nmod_poly_factor(res, pol1);
break;
case 1:
nmod_poly_factor_with_berlekamp(res, pol1);
break;
case 2:
nmod_poly_factor_with_cantor_zassenhaus(res, pol1);
break;
}
nmod_poly_factor_cantor_zassenhaus(res2, pol1);
if (res->num != res2->num)
{
flint_printf("FAIL: different number of factors found\n");
abort();
}
for (i = 0; i < res->num; i++)
{
found = 0;
for (j = 0; j < res2->num; j++)
{
if (nmod_poly_equal(res->p + i, res2->p + j) &&
res->exp[i] == res2->exp[j])
{
found = 1;
break;
}
}
if (!found)
{
flint_printf("FAIL: factor not found\n");
abort();
}
}
nmod_poly_clear(quot);
nmod_poly_clear(rem);
nmod_poly_clear(pol1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
nmod_poly_factor_clear(res2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,110 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor_berlekamp....");
fflush(stdout);
for (iter = 0; iter < 20 * flint_test_multiplier(); iter++)
{
int result = 1;
nmod_poly_t pol1, poly, quot, rem;
nmod_poly_factor_t res;
mp_limb_t modulus;
slong i, length, num;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(pol1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(quot, modulus);
nmod_poly_init(rem, modulus);
length = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(pol1, state, length);
if (pol1->length)
nmod_poly_make_monic(pol1, pol1);
}
while ((!nmod_poly_is_irreducible(pol1)) || (pol1->length < 2));
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 10) + 2;
nmod_poly_randtest(poly, state, length);
if (poly->length)
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(quot, rem, pol1, poly);
}
}
while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2)
|| (rem->length == 0));
nmod_poly_mul(pol1, pol1, poly);
}
nmod_poly_factor_init(res);
nmod_poly_factor_berlekamp(res, pol1);
result = (res->num == num);
if (!result)
{
flint_printf("FAIL: %wu, %wd, %wd\n", modulus, num, res->num);
abort();
}
nmod_poly_clear(quot);
nmod_poly_clear(rem);
nmod_poly_clear(pol1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,144 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor_cantor_zassenhaus....");
fflush(stdout);
for (iter = 0; iter < 20 * flint_test_multiplier(); iter++)
{
int result = 1;
nmod_poly_t pol1, poly, quot, rem;
nmod_poly_t product;
nmod_poly_factor_t res;
mp_limb_t modulus, lead;
slong i, j, length, num;
slong prod1, exp[5];
modulus = n_randtest_prime(state, 0);
nmod_poly_init(pol1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(quot, modulus);
nmod_poly_init(rem, modulus);
nmod_poly_zero(pol1);
nmod_poly_set_coeff_ui(pol1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if(!nmod_poly_is_zero(poly))
nmod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)));
exp[0] = n_randint(state, 30) + 1;
prod1 = exp[0];
for (i = 0; i < exp[0]; i++)
nmod_poly_mul(pol1, pol1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
nmod_poly_randtest(poly, state, length);
if(!nmod_poly_is_zero(poly))
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(quot, rem, pol1, poly);
}
}
while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2) ||
(rem->length == 0));
exp[i] = n_randint(state, 30) + 1;
prod1 *= exp[i];
for (j = 0; j < exp[i]; j++)
nmod_poly_mul(pol1, pol1, poly);
}
nmod_poly_factor_init(res);
nmod_poly_factor_cantor_zassenhaus(res, pol1);
result &= (res->num == num);
if (!result)
{
flint_printf("Error: number of factors incorrect, %wd, %wd\n",
res->num, num);
}
nmod_poly_init(product, pol1->mod.n);
nmod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
nmod_poly_mul(product, product, res->p + i);
lead = pol1->coeffs[pol1->length - 1];
nmod_poly_scalar_mul_nmod(product, product, lead);
result &= nmod_poly_equal(pol1, product);
if (!result)
{
flint_printf("Error: product of factors does not equal original polynomial\n");
nmod_poly_print(pol1); flint_printf("\n");
nmod_poly_print(product); flint_printf("\n");
}
if (!result)
abort();
nmod_poly_clear(product);
nmod_poly_clear(quot);
nmod_poly_clear(rem);
nmod_poly_clear(pol1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,130 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor_distinct_deg....");
fflush(stdout);
for (iter = 0; iter < 200; iter++)
{
nmod_poly_t poly1, poly, q, r, product;
nmod_poly_factor_t res;
mp_limb_t modulus, lead;
slong i, length, num;
slong *degs;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(poly1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(q, modulus);
nmod_poly_init(r, modulus);
nmod_poly_zero(poly1);
nmod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if (poly->length)
nmod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)));
nmod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
nmod_poly_randtest(poly, state, length);
if (poly->length)
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)) ||
(r->length == 0));
nmod_poly_mul(poly1, poly1, poly);
}
if (!(degs = flint_malloc((poly1->length - 1) * sizeof(slong))))
{
flint_printf("Fatal error: not enough memory.");
abort();
}
nmod_poly_factor_init(res);
nmod_poly_factor_distinct_deg(res, poly1, &degs);
nmod_poly_init_preinv(product, poly1->mod.n, poly1->mod.ninv);
nmod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
nmod_poly_mul(product, product, res->p + i);
lead = poly1->coeffs[poly1->length - 1];
nmod_poly_scalar_mul_nmod(product, product, lead);
if (!nmod_poly_equal(poly1, product))
{
flint_printf("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n"); nmod_poly_print(poly1); flint_printf("\n");
flint_printf("product:\n"); nmod_poly_print(product); flint_printf("\n");
abort();
}
flint_free(degs);
nmod_poly_clear(product);
nmod_poly_clear(q);
nmod_poly_clear(r);
nmod_poly_clear(poly1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,135 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include <stdlib.h>
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor_kaltofen_shoup....");
fflush(stdout);
for (iter = 0; iter < 200; iter++)
{
nmod_poly_t poly1, poly, q, r, product;
nmod_poly_factor_t res;
mp_limb_t modulus, lead;
slong i, j, length, num;
slong exp[5];
modulus = n_randtest_prime(state, 0);
nmod_poly_init(poly1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(q, modulus);
nmod_poly_init(r, modulus);
nmod_poly_zero(poly1);
nmod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if (poly->length)
nmod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)));
exp[0] = n_randint(state, 30) + 1;
for (i = 0; i < exp[0]; i++)
nmod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
nmod_poly_randtest(poly, state, length);
if (poly->length)
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)) ||
(r->length == 0));
exp[i] = n_randint(state, 30) + 1;
for (j = 0; j < exp[i]; j++)
nmod_poly_mul(poly1, poly1, poly);
}
nmod_poly_factor_init(res);
nmod_poly_factor_kaltofen_shoup(res, poly1);
if (res->num != num)
{
flint_printf("Error: number of factors incorrect: %wd != %wd\n", res->num, num);
abort();
}
nmod_poly_init_preinv(product, poly1->mod.n, poly1->mod.ninv);
nmod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
nmod_poly_mul(product, product, res->p + i);
lead = poly1->coeffs[poly1->length - 1];
nmod_poly_scalar_mul_nmod(product, product, lead);
if (!nmod_poly_equal(poly1, product))
{
flint_printf("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n"); nmod_poly_print(poly1); flint_printf("\n");
flint_printf("product:\n"); nmod_poly_print(product); flint_printf("\n");
abort();
}
nmod_poly_clear(product);
nmod_poly_clear(q);
nmod_poly_clear(r);
nmod_poly_clear(poly1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,140 @@
/*=============================================================================
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) 2007 David Howden
Copyright (C) 2007, 2008, 2009, 2010 William Hart
Copyright (C) 2008 Richard Howell-Peak
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor_squarefree....");
fflush(stdout);
for (iter = 0; iter < 30 * flint_test_multiplier(); iter++)
{
int result = 1;
nmod_poly_t pol1, poly, quot, rem;
nmod_poly_factor_t res;
mp_limb_t modulus;
slong exp[5], prod1;
slong length, i, j, num;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(pol1, modulus);
nmod_poly_init(poly, modulus);
nmod_poly_init(quot, modulus);
nmod_poly_init(rem, modulus);
nmod_poly_zero(pol1);
nmod_poly_set_coeff_ui(pol1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if(!nmod_poly_is_zero(poly))
nmod_poly_make_monic(poly, poly);
}
while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2));
exp[0] = n_randprime(state, 5, 0);
prod1 = exp[0];
for (i = 0; i < exp[0]; i++)
nmod_poly_mul(pol1, pol1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
nmod_poly_randtest(poly, state, length);
if (poly->length)
{
nmod_poly_make_monic(poly, poly);
nmod_poly_divrem(quot, rem, pol1, poly);
}
}
while ((!nmod_poly_is_irreducible(poly)) ||
(poly->length < 2) || (rem->length == 0));
do exp[i] = n_randprime(state, 5, 0);
while (prod1 % exp[i] == 0);
prod1 *= exp[i];
for (j = 0; j < exp[i]; j++)
nmod_poly_mul(pol1, pol1, poly);
}
nmod_poly_factor_init(res);
nmod_poly_factor_squarefree(res, pol1);
result &= (res->num == num);
if (result)
{
ulong prod2 = 1;
for (i = 0; i < num; i++)
prod2 *= res->exp[i];
result &= (prod1 == prod2);
}
if (!result)
{
flint_printf("Error: exp don't match. Modulus = %wu\n", modulus);
for (i = 0; i < res->num; i++)
flint_printf("%wd ", res->exp[i]);
flint_printf("\n");
for (i = 0; i < num; i++)
flint_printf("%wd ", exp[i]);
flint_printf("\n");
abort();
}
nmod_poly_clear(quot);
nmod_poly_clear(rem);
nmod_poly_clear(pol1);
nmod_poly_clear(poly);
nmod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,109 @@
/*=============================================================================
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 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("is_irreducible....");
fflush(stdout);
for (iter = 0; iter < 200 * flint_test_multiplier(); iter++)
{
nmod_poly_t poly, poly2, poly3;
nmod_poly_factor_t factors;
mp_limb_t modulus;
slong length, length2;
int result = 1;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(poly, modulus);
nmod_poly_init(poly2, modulus);
nmod_poly_init(poly3, modulus);
length = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if(!nmod_poly_is_zero(poly))
nmod_poly_make_monic(poly, poly);
}
while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2));
nmod_poly_factor_init(factors);
nmod_poly_factor_berlekamp(factors, poly);
result &= (factors->num == 1);
if (!result)
{
flint_printf("FAIL:\n");
flint_printf("Irreducible polynomial should not have non-trivial factors!\n");
flint_printf("poly = "), nmod_poly_print(poly), flint_printf("\n");
abort();
}
nmod_poly_factor_clear(factors);
length2 = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(poly2, state, length2);
if(!nmod_poly_is_zero(poly2))
nmod_poly_make_monic(poly2, poly2);
}
while ((!nmod_poly_is_irreducible(poly2)) || (poly2->length < 2));
nmod_poly_mul(poly3, poly, poly2);
result &= !nmod_poly_is_irreducible(poly3);
if (!result)
{
flint_printf("Error: reducible polynomial declared irreducible!\n");
nmod_poly_print(poly3); flint_printf("\n");
abort();
}
nmod_poly_clear(poly);
nmod_poly_clear(poly2);
nmod_poly_clear(poly3);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,115 @@
/*=============================================================================
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 Fredrik Johansson
Copyright (C) 2013 Martin Lee
******************************************************************************/
#undef ulong
#define ulong ulongxx/* interferes with system includes */
#include <stdlib.h>
#include <stdio.h>
#undef ulong
#include <gmp.h>
#define ulong mp_limb_t
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("is_irreducible_ddf....");
fflush(stdout);
for (iter = 0; iter < 200 * flint_test_multiplier(); iter++)
{
nmod_poly_t poly, poly2, poly3;
mp_limb_t modulus;
slong length, length2;
int result = 1;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(poly, modulus);
nmod_poly_init(poly2, modulus);
nmod_poly_init(poly3, modulus);
length = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if(!nmod_poly_is_zero(poly))
nmod_poly_make_monic(poly, poly);
}
while ((poly->length < 2));
result &= (nmod_poly_is_irreducible_rabin (poly) == nmod_poly_is_irreducible_ddf (poly));
if (!result)
{
flint_printf("FAIL:\n");
flint_printf("result of is_irreducible and is_irreducible_ddf does not coincide\n");
flint_printf("poly = "), nmod_poly_print(poly), flint_printf("\n");
abort();
}
length2 = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(poly2, state, length2);
if(!nmod_poly_is_zero(poly2))
nmod_poly_make_monic(poly2, poly2);
}
while ((!nmod_poly_is_irreducible_rabin(poly2)) || (poly2->length < 2));
nmod_poly_mul(poly3, poly, poly2);
result &= !nmod_poly_is_irreducible_ddf(poly3);
if (!result)
{
flint_printf("Error: reducible polynomial declared irreducible!\n");
nmod_poly_print(poly3); flint_printf("\n");
abort();
}
nmod_poly_clear(poly);
nmod_poly_clear(poly2);
nmod_poly_clear(poly3);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,118 @@
/*=============================================================================
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 Fredrik Johansson
******************************************************************************/
#undef ulong
#define ulong ulongxx/* interferes with system includes */
#include <stdlib.h>
#include <stdio.h>
#undef ulong
#include <gmp.h>
#define ulong mp_limb_t
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("is_irreducible_rabin....");
fflush(stdout);
for (iter = 0; iter < 200 * flint_test_multiplier(); iter++)
{
nmod_poly_t poly, poly2, poly3;
nmod_poly_factor_t factors;
mp_limb_t modulus;
slong length, length2;
int result = 1;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(poly, modulus);
nmod_poly_init(poly2, modulus);
nmod_poly_init(poly3, modulus);
length = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(poly, state, length);
if(!nmod_poly_is_zero(poly))
nmod_poly_make_monic(poly, poly);
}
while ((!nmod_poly_is_irreducible_rabin(poly)) || (poly->length < 2));
nmod_poly_factor_init(factors);
nmod_poly_factor_berlekamp(factors, poly);
result &= (factors->num == 1);
if (!result)
{
flint_printf("FAIL:\n");
flint_printf("Irreducible polynomial should not have non-trivial factors!\n");
flint_printf("poly = "), nmod_poly_print(poly), flint_printf("\n");
abort();
}
nmod_poly_factor_clear(factors);
length2 = n_randint(state, 10) + 2;
do
{
nmod_poly_randtest(poly2, state, length2);
if(!nmod_poly_is_zero(poly2))
nmod_poly_make_monic(poly2, poly2);
}
while ((!nmod_poly_is_irreducible_rabin(poly2)) || (poly2->length < 2));
nmod_poly_mul(poly3, poly, poly2);
result &= !nmod_poly_is_irreducible_rabin(poly3);
if (!result)
{
flint_printf("Error: reducible polynomial declared irreducible!\n");
nmod_poly_print(poly3); flint_printf("\n");
abort();
}
nmod_poly_clear(poly);
nmod_poly_clear(poly2);
nmod_poly_clear(poly3);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,106 @@
/*=============================================================================
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 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "nmod_vec.h"
#include "nmod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("is_squarefree....");
fflush(stdout);
for (iter = 0; iter < 200 * flint_test_multiplier(); iter++)
{
nmod_poly_t poly, Q, R, t;
mp_limb_t modulus;
slong i, num_factors, exp, max_exp;
int v, result;
modulus = n_randtest_prime(state, 0);
nmod_poly_init(poly, modulus);
nmod_poly_init(t, modulus);
nmod_poly_init(Q, modulus);
nmod_poly_init(R, modulus);
nmod_poly_set_coeff_ui(poly, 0, n_randint(state, modulus));
num_factors = n_randint(state, 5);
max_exp = 0;
for (i = 0; i < num_factors; i++)
{
do {
nmod_poly_randtest(t, state, n_randint(state, 10));
} while (!nmod_poly_is_irreducible(t) ||
(nmod_poly_length(t) < 2));
exp = n_randint(state, 4) + 1;
if (n_randint(state, 2) == 0)
exp = 1;
nmod_poly_divrem(Q, R, poly, t);
if (!nmod_poly_is_zero(R))
{
nmod_poly_pow(t, t, exp);
nmod_poly_mul(poly, poly, t);
max_exp = FLINT_MAX(exp, max_exp);
}
}
v = nmod_poly_is_squarefree(poly);
if (v == 1)
result = (max_exp <= 1 && !nmod_poly_is_zero(poly));
else
result = (max_exp > 1 || nmod_poly_is_zero(poly));
if (!result)
{
flint_printf("FAIL: %wu, %wd, %d\n", modulus, max_exp, v);
nmod_poly_print(poly); flint_printf("\n");
abort();
}
nmod_poly_clear(poly);
nmod_poly_clear(t);
nmod_poly_clear(Q);
nmod_poly_clear(R);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}