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,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
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include <gmp.h>
#include "flint.h"
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_clear(fmpz_mod_poly_factor_t fac)
{
slong i;
for (i = 0; i < fac->alloc; i++)
fmpz_mod_poly_clear(fac->poly + i);
flint_free(fac->poly);
flint_free(fac->exp);
}

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
******************************************************************************/
#include <gmp.h>
#include "flint.h"
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_concat(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_factor_t fac)
{
slong i;
for (i = 0; i < fac->num; i++)
fmpz_mod_poly_factor_insert(res, fac->poly + i, fac->exp[i]);
}

View File

@@ -0,0 +1,174 @@
/*=============================================================================
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) 2009, 2008 William Hart
Copyright (C) 2011 Sebastian Pancratz
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
*******************************************************************************
Factorisation
*******************************************************************************
void fmpz_mod_poly_factor_init(fmpz_mod_poly_factor_t fac)
Initialises \code{fac} for use. An \code{fmpz_mod_poly_factor_t}
represents a polynomial in factorised form as a product of
polynomials with associated exponents.
void fmpz_mod_poly_factor_clear(fmpz_mod_poly_factor_t fac)
Frees all memory associated with \code{fac}.
void fmpz_mod_poly_factor_realloc(fmpz_mod_poly_factor_t fac, slong alloc)
Reallocates the factor structure to provide space for
precisely \code{alloc} factors.
void fmpz_mod_poly_factor_fit_length(fmpz_mod_poly_factor_t fac, slong len)
Ensures that the factor structure has space for at
least \code{len} factors. This function takes care
of the case of repeated calls by always, at least
doubling the number of factors the structure can hold.
void fmpz_mod_poly_factor_set(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_factor_t fac)
Sets \code{res} to the same factorisation as \code{fac}.
void fmpz_mod_poly_factor_print(const fmpz_mod_poly_factor_t fac)
Prints the entries of \code{fac} to standard output.
void fmpz_mod_poly_factor_insert(fmpz_mod_poly_factor_t fac,
const fmpz_mod_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 fmpz_mod_poly_factor_concat(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_factor_t fac)
Concatenates two factorisations.
This is equivalent to calling \code{fmpz_mod_poly_factor_insert()}
repeatedly with the individual factors of \code{fac}.
Does not support aliasing between \code{res} and \code{fac}.
void fmpz_mod_poly_factor_pow(fmpz_mod_poly_factor_t fac, slong exp)
Raises \code{fac} to the power \code{exp}.
int fmpz_mod_poly_is_irreducible(const fmpz_mod_poly_t f)
Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0.
int fmpz_mod_poly_is_irreducible_ddf(const fmpz_mod_poly_t f)
Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0.
Uses fast distinct-degree factorisation.
int fmpz_mod_poly_is_irreducible_rabin(const fmpz_mod_poly_t f)
Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0.
Uses Rabin irreducibility test.
int _fmpz_mod_poly_is_squarefree(const fmpz * f, slong len, const fmpz_t p)
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 fmpz_mod_poly_is_squarefree(const fmpz_mod_poly_t f)
Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special
case, the zero polynomial is not considered squarefree.
int fmpz_mod_poly_factor_equal_deg_prob(fmpz_mod_poly_t factor,
flint_rand_t state, const fmpz_mod_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 \code{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 fmpz_mod_poly_factor_equal_deg(fmpz_mod_poly_factor_t factors,
const fmpz_mod_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 fmpz_mod_poly_factor_distinct_deg(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t poly, slong * const *degs)
Factorises a monic non-constant squarefree polynomial \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 fmpz_mod_poly_factor_squarefree(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t f)
Sets \code{res} to a squarefree factorization of \code{f}.
void fmpz_mod_poly_factor(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t f)
Factorises a non-constant polynomial \code{f} into monic irreducible
factors choosing the best algorithm for given modulo and degree.
Choise is based on heuristic measurments.
void fmpz_mod_poly_factor_cantor_zassenhaus(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t f)
Factorises a non-constant polynomial \code{f} into monic irreducible
factors using the Cantor-Zassenhaus algorithm.
void fmpz_mod_poly_factor_kaltofen_shoup(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t poly)
Factorises a non-constant polynomial \code{poly} 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''<27> strategy for the distinct-degree factorization
step.
void fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors,
const fmpz_mod_poly_t f)
Factorises a non-constant polynomial \code{f} into monic irreducible
factors using the Berlekamp algorithm.

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) 2012 Lina Kulakova
******************************************************************************/
#include <math.h>
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t f)
{
slong n = fmpz_mod_poly_degree(f);
mp_bitcnt_t bits = fmpz_bits(&f->p);
if (5 * bits + n > 75)
fmpz_mod_poly_factor_kaltofen_shoup(res, f);
else
fmpz_mod_poly_factor_cantor_zassenhaus(res, f);
}

View File

@@ -0,0 +1,303 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
#include "profiler.h"
#include "perm.h"
static void
fmpz_mod_poly_to_fmpz_mat_col(fmpz_mat_t mat, slong col, fmpz_mod_poly_t poly)
{
slong i;
for (i = 0; i < poly->length; i++)
fmpz_set(fmpz_mat_entry(mat, i, col), poly->coeffs + i);
for (; i < mat->r; i++)
fmpz_zero(fmpz_mat_entry(mat, i, col));
}
static void
fmpz_mat_col_to_fmpz_mod_poly_shifted(fmpz_mod_poly_t poly, fmpz_mat_t mat,
slong col, slong *shift)
{
slong i, j, rows = mat->r;
fmpz_mod_poly_fit_length(poly, rows);
for (i = 0, j = 0; j < rows; j++)
{
if (shift[j])
fmpz_zero(poly->coeffs + j);
else
{
fmpz_set(poly->coeffs + j, fmpz_mat_entry(mat, i, col));
i++;
}
}
_fmpz_mod_poly_set_length(poly, rows);
_fmpz_mod_poly_normalise(poly);
}
static void
__fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors,
flint_rand_t state, const fmpz_mod_poly_t f)
{
const slong n = fmpz_mod_poly_degree(f);
fmpz_mod_poly_factor_t fac1, fac2;
fmpz_mod_poly_t x, x_p;
fmpz_mod_poly_t x_pi, x_pi2;
fmpz_mod_poly_t Q, r;
fmpz_mat_t matrix;
fmpz_t coeff, p, q, mul, pow;
slong i, nullity, col, row;
slong *shift, *perm;
fmpz_mod_poly_t *basis;
if (f->length <= 2)
{
fmpz_mod_poly_factor_insert(factors, f, 1);
return;
}
fmpz_init(coeff);
fmpz_init(mul);
fmpz_init_set(p, &f->p);
/* q = p - 1 */
fmpz_init_set(q, p);
fmpz_sub_ui(q, q, 1);
fmpz_mod(q, q, p);
/* pow = (p-1)/2 */
fmpz_init(pow);
if (fmpz_cmp_ui(p, 3) > 0)
{
fmpz_set(pow, q);
fmpz_divexact_ui(pow, pow, 2);
}
/* Step 1, compute x^p mod f in F_p[X]/<f> */
fmpz_mod_poly_init(x, p);
fmpz_mod_poly_init(x_p, p);
fmpz_mod_poly_set_coeff_ui(x, 1, 1);
fmpz_mod_poly_powmod_fmpz_binexp(x_p, x, p, f);
fmpz_mod_poly_clear(x);
/* Step 2, compute the matrix for the Berlekamp Map */
fmpz_mat_init(matrix, n, n);
fmpz_mod_poly_init(x_pi, p);
fmpz_mod_poly_init(x_pi2, p);
fmpz_mod_poly_set_coeff_ui(x_pi, 0, 1);
for (i = 0; i < n; i++)
{
/* Q - I */
fmpz_mod_poly_set(x_pi2, x_pi);
fmpz_mod_poly_get_coeff_fmpz(coeff, x_pi2, i);
if (!fmpz_is_zero(coeff))
{
fmpz_sub_ui(coeff, coeff, 1);
fmpz_mod(coeff, coeff, p);
fmpz_mod_poly_set_coeff_fmpz(x_pi2, i, coeff);
}
else
{
fmpz_mod_poly_set_coeff_fmpz(x_pi2, i, q);
}
fmpz_mod_poly_to_fmpz_mat_col(matrix, i, x_pi2);
fmpz_mod_poly_mulmod(x_pi, x_pi, x_p, f);
}
fmpz_mod_poly_clear(x_p);
fmpz_mod_poly_clear(x_pi);
fmpz_mod_poly_clear(x_pi2);
/* Row reduce Q - I */
perm = _perm_init(n);
nullity = n - fmpz_mat_rref_mod(perm, matrix, p);
_perm_clear(perm);
/* Find a basis for the nullspace */
basis =
(fmpz_mod_poly_t *) flint_malloc(nullity * sizeof(fmpz_mod_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++)
{
fmpz_mod_poly_init(basis[i], p);
while (!fmpz_is_zero(fmpz_mat_entry(matrix, row, col)))
{
row++;
col++;
}
fmpz_mat_col_to_fmpz_mod_poly_shifted(basis[i], matrix, col, shift);
fmpz_mod_poly_set_coeff_fmpz(basis[i], col, q);
shift[col] = 1;
col++;
}
flint_free(shift);
fmpz_mat_clear(matrix);
/* we are done */
if (nullity == 1)
{
fmpz_mod_poly_factor_insert(factors, f, 1);
}
else
{
/* Generate random linear combinations */
fmpz_mod_poly_t factor, b, power, g;
fmpz_mod_poly_init(factor, p);
fmpz_mod_poly_init(b, p);
fmpz_mod_poly_init(power, p);
fmpz_mod_poly_init(g, p);
while (1)
{
do
{
fmpz_mod_poly_zero(factor);
for (i = 1; i < nullity; i++)
{
fmpz_randm(mul, state, p);
fmpz_mod_poly_scalar_mul_fmpz(b, basis[i], mul);
fmpz_mod_poly_add(factor, factor, b);
}
fmpz_randm(coeff, state, p);
fmpz_mod_poly_set_coeff_fmpz(factor, 0, coeff);
if (!fmpz_mod_poly_is_zero(factor))
fmpz_mod_poly_make_monic(factor, factor);
}
while (fmpz_mod_poly_is_zero(factor) ||
(factor->length < 2 && fmpz_is_one(factor->coeffs)));
fmpz_mod_poly_gcd(g, f, factor);
if (fmpz_mod_poly_length(g) != 1)
break;
if (fmpz_cmp_ui(p, 3) > 0)
fmpz_mod_poly_powmod_fmpz_binexp(power, factor, pow, f);
else
fmpz_mod_poly_set(power, factor);
fmpz_add(power->coeffs, power->coeffs, q);
fmpz_mod(power->coeffs, power->coeffs, p);
_fmpz_mod_poly_normalise(power);
fmpz_mod_poly_gcd(g, power, f);
if (fmpz_mod_poly_length(g) != 1)
break;
}
fmpz_mod_poly_clear(power);
fmpz_mod_poly_clear(factor);
fmpz_mod_poly_clear(b);
if (!fmpz_mod_poly_is_zero(g))
fmpz_mod_poly_make_monic(g, g);
fmpz_mod_poly_factor_init(fac1);
fmpz_mod_poly_factor_init(fac2);
__fmpz_mod_poly_factor_berlekamp(fac1, state, g);
fmpz_mod_poly_init(Q, p);
fmpz_mod_poly_init(r, p);
fmpz_mod_poly_divrem(Q, r, f, g);
fmpz_mod_poly_clear(r);
if (!fmpz_mod_poly_is_zero(Q))
fmpz_mod_poly_make_monic(Q, Q);
__fmpz_mod_poly_factor_berlekamp(fac2, state, Q);
fmpz_mod_poly_factor_concat(factors, fac1);
fmpz_mod_poly_factor_concat(factors, fac2);
fmpz_mod_poly_factor_clear(fac1);
fmpz_mod_poly_factor_clear(fac2);
fmpz_mod_poly_clear(Q);
fmpz_mod_poly_clear(g);
}
for (i = 1; i < nullity; i++)
fmpz_mod_poly_clear(basis[i]);
flint_free(basis);
fmpz_clear(coeff);
fmpz_clear(p);
fmpz_clear(q);
fmpz_clear(mul);
fmpz_clear(pow);
}
void
fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors,
const fmpz_mod_poly_t f)
{
slong i;
flint_rand_t r;
fmpz_mod_poly_t v;
fmpz_mod_poly_factor_t sq_free;
fmpz_mod_poly_init(v, &f->p);
fmpz_mod_poly_make_monic(v, f);
/* compute squarefree factorisation */
fmpz_mod_poly_factor_init(sq_free);
fmpz_mod_poly_factor_squarefree(sq_free, v);
/* run Berlekamp algorithm for all squarefree factors */
flint_randinit(r);
for (i = 0; i < sq_free->num; i++)
{
__fmpz_mod_poly_factor_berlekamp(factors, r, sq_free->poly + i);
}
flint_randclear(r);
/* compute multiplicities of factors in f */
for (i = 0; i < factors->num; i++)
factors->exp[i] = fmpz_mod_poly_remove(v, factors->poly + i);
fmpz_mod_poly_clear(v);
fmpz_mod_poly_factor_clear(sq_free);
}

View File

@@ -0,0 +1,78 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_cantor_zassenhaus(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t f)
{
fmpz_mod_poly_t h, v, g, x;
slong i, j, num;
fmpz_mod_poly_init(h, &f->p);
fmpz_mod_poly_init(g, &f->p);
fmpz_mod_poly_init(v, &f->p);
fmpz_mod_poly_init(x, &f->p);
fmpz_mod_poly_set_coeff_ui(h, 1, 1);
fmpz_mod_poly_set_coeff_ui(x, 1, 1);
fmpz_mod_poly_make_monic(v, f);
i = 0;
do
{
i++;
fmpz_mod_poly_powmod_fmpz_binexp(h, h, &f->p, v);
fmpz_mod_poly_sub(h, h, x);
fmpz_mod_poly_gcd(g, h, v);
fmpz_mod_poly_add(h, h, x);
if (g->length != 1)
{
fmpz_mod_poly_make_monic(g, g);
num = res->num;
fmpz_mod_poly_factor_equal_deg(res, g, i);
for (j = num; j < res->num; j++)
res->exp[j] = fmpz_mod_poly_remove(v, res->poly + j);
}
}
while (v->length >= 2 * i + 3);
if (v->length > 1)
fmpz_mod_poly_factor_insert(res, v, 1);
fmpz_mod_poly_clear(g);
fmpz_mod_poly_clear(h);
fmpz_mod_poly_clear(v);
fmpz_mod_poly_clear(x);
}

View File

@@ -0,0 +1,219 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_distinct_deg(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t poly, slong * const *degs)
{
fmpz_mod_poly_t f, g, v, vinv, reducedH0, tmp;
fmpz_mod_poly_t *h, *H, *I;
slong i, j, l, m, n, index, d;
fmpz_t p;
fmpz_mat_t HH, HHH;
double beta;
fmpz_init(p);
fmpz_set(p, &poly->p);
fmpz_mod_poly_init(v, p);
fmpz_mod_poly_make_monic(v, poly);
n = fmpz_mod_poly_degree(poly);
if (n == 1)
{
fmpz_mod_poly_factor_insert(res, v, 1);
(*degs)[0]= 1;
fmpz_mod_poly_clear(v);
return;
}
beta = 0.5 * (1. - (log(2) / log(n)));
l = ceil(pow(n, beta));
m = ceil(0.5 * n / l);
/* initialization */
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_init(g, p);
fmpz_mod_poly_init(vinv, p);
fmpz_mod_poly_init(reducedH0, p);
fmpz_mod_poly_init(tmp, p);
if (!(h = flint_malloc((2 * m + l + 1) * sizeof(fmpz_mod_poly_struct))))
{
flint_printf("Exception (fmpz_mod_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++)
fmpz_mod_poly_init(h[i], p);
for (i = 0; i < m; i++)
{
fmpz_mod_poly_init(H[i], p);
fmpz_mod_poly_init(I[i], p);
}
fmpz_mod_poly_reverse(vinv, v, v->length);
fmpz_mod_poly_inv_series_newton(vinv, vinv, v->length);
/* compute baby steps: h[i]=x^{p^i}mod v */
fmpz_mod_poly_set_coeff_ui(h[0], 1, 1);
fmpz_mod_poly_powmod_x_fmpz_preinv(h[1], p, v, vinv);
if (fmpz_sizeinbase(p, 2) > ((n_sqrt (v->length - 1) + 1) * 3) / 4)
{
fmpz_mat_init(HH, n_sqrt (v->length - 1) + 1, v->length - 1);
fmpz_mod_poly_precompute_matrix(HH, h[1], v, vinv);
for (i = 2; i < l + 1; i++)
fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(h[i], h[i - 1],
HH, v, vinv);
fmpz_mat_clear(HH);
}
else
{
for (i = 2; i < l + 1; i++)
fmpz_mod_poly_powmod_fmpz_binexp_preinv(h[i], h[i - 1], p,
v, vinv);
}
/* compute coarse distinct-degree factorisation */
index= 0;
fmpz_mod_poly_set(H[0], h[l]);
fmpz_mod_poly_set(reducedH0, H[0]);
fmpz_mat_init(HH, n_sqrt (v->length - 1) + 1, v->length - 1);
fmpz_mod_poly_precompute_matrix(HH, reducedH0, v, vinv);
d = 1;
for (j = 0; j < m; j++)
{
/* compute giant steps: H[i]=x^{p^(li)}mod v */
if (j > 0)
{
if (I[j - 1]->length > 1)
{
_fmpz_mod_poly_reduce_matrix_mod_poly(HHH, HH, v);
fmpz_mat_clear(HH);
fmpz_mat_init_set(HH, HHH);
fmpz_mat_clear(HHH);
fmpz_mod_poly_rem(reducedH0, reducedH0, v);
fmpz_mod_poly_rem(tmp, H[j - 1], v);
fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(H[j], tmp,
HH, v, vinv);
}
else
fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(H[j],
H[j - 1], HH, v, vinv);
}
/* compute interval polynomials */
fmpz_mod_poly_set_coeff_ui(I[j], 0, 1);
for (i = l - 1; (i >= 0) && (2 * d <= v->length - 1); i--, d++)
{
fmpz_mod_poly_rem(tmp, h[i], v);
fmpz_mod_poly_sub(tmp, H[j], tmp);
fmpz_mod_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 */
fmpz_mod_poly_gcd(I[j], v, I[j]);
if (I[j]->length > 1)
{
fmpz_mod_poly_remove(v, I[j]);
fmpz_mod_poly_reverse(vinv, v, v->length);
fmpz_mod_poly_inv_series_newton(vinv, vinv, v->length);
}
if (v->length-1 < 2 * d)
{
break;
}
}
if (v->length > 1)
{
fmpz_mod_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)
{
fmpz_mod_poly_set(g, I[j]);
for (i = l - 1; i >= 0 && (g->length > 1); i--)
{
/* compute f^{[l*(j+1)-i]} */
fmpz_mod_poly_sub(tmp, H[j], h[i]);
fmpz_mod_poly_gcd(f, g, tmp);
if (f->length > 1)
{
/* insert f^{[l*(j+1)-i]} into res */
fmpz_mod_poly_make_monic(f, f);
fmpz_mod_poly_factor_insert(res, f, 1);
(*degs)[index++] = l * (j + 1) - i;
fmpz_mod_poly_remove(g, f);
}
}
}
else if (I[j]->length > 1)
{
fmpz_mod_poly_make_monic(I[j], I[j]);
fmpz_mod_poly_factor_insert(res, I[j], 1);
(*degs)[index++] = I[j]->length - 1;
}
}
/* cleanup */
fmpz_clear(p);
fmpz_mod_poly_clear(f);
fmpz_mod_poly_clear(g);
fmpz_mod_poly_clear(reducedH0);
fmpz_mod_poly_clear(v);
fmpz_mod_poly_clear(vinv);
fmpz_mod_poly_clear(tmp);
fmpz_mat_clear(HH);
for (i = 0; i < l + 1; i++)
fmpz_mod_poly_clear(h[i]);
for (i = 0; i < m; i++)
{
fmpz_mod_poly_clear(H[i]);
fmpz_mod_poly_clear(I[i]);
}
flint_free(h);
}

View File

@@ -0,0 +1,66 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
#include "ulong_extras.h"
void
fmpz_mod_poly_factor_equal_deg(fmpz_mod_poly_factor_t factors,
const fmpz_mod_poly_t pol, slong d)
{
if (pol->length == d + 1)
{
fmpz_mod_poly_factor_insert(factors, pol, 1);
}
else
{
fmpz_mod_poly_t f, g, r;
flint_rand_t state;
fmpz_mod_poly_init(f, &pol->p);
flint_randinit(state);
while (!fmpz_mod_poly_factor_equal_deg_prob(f, state, pol, d))
{
};
flint_randclear(state);
fmpz_mod_poly_init(g, &pol->p);
fmpz_mod_poly_init(r, &pol->p);
fmpz_mod_poly_divrem(g, r, pol, f);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_factor_equal_deg(factors, f, d);
fmpz_mod_poly_clear(f);
fmpz_mod_poly_factor_equal_deg(factors, g, d);
fmpz_mod_poly_clear(g);
}
}

View File

@@ -0,0 +1,117 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
#include "ulong_extras.h"
int
fmpz_mod_poly_factor_equal_deg_prob(fmpz_mod_poly_t factor,
flint_rand_t state,
const fmpz_mod_poly_t pol, slong d)
{
fmpz_mod_poly_t a, b, c, polinv;
fmpz_t exp, t, p;
int res = 1;
slong i;
if (pol->length <= 1)
{
flint_printf("Exception (fmpz_mod_poly_factor_equal_deg_prob): \n");
flint_printf("Input polynomial is linear.\n");
abort();
}
fmpz_init_set(p, &pol->p);
fmpz_mod_poly_init(a, p);
do
{
fmpz_mod_poly_randtest(a, state, pol->length - 1);
} while (a->length <= 1);
fmpz_mod_poly_gcd(factor, a, pol);
if (factor->length != 1)
{
fmpz_mod_poly_clear(a);
return 1;
}
fmpz_mod_poly_init(b, p);
fmpz_mod_poly_init(polinv, p);
fmpz_mod_poly_reverse(polinv, pol, pol->length);
fmpz_mod_poly_inv_series_newton(polinv, polinv, polinv->length);
fmpz_init(exp);
if (fmpz_cmp_ui(p, 2) > 0)
{
/* compute a^{(p^d-1)/2} rem pol */
fmpz_pow_ui(exp, p, d);
fmpz_sub_ui(exp, exp, 1);
fmpz_fdiv_q_2exp(exp, exp, 1);
fmpz_mod_poly_powmod_fmpz_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 */
fmpz_mod_poly_rem(b, a, pol);
fmpz_mod_poly_init(c, p);
fmpz_mod_poly_set(c, b);
for (i = 1; i < d; i++)
{
/* c = a^{2^i} = (a^{2^{i-1}})^2 */
fmpz_mod_poly_powmod_ui_binexp_preinv(c, c, 2, pol, polinv);
fmpz_mod_poly_add(b, b, c);
}
fmpz_mod_poly_rem(b, b, pol);
fmpz_mod_poly_clear(c);
}
fmpz_clear(exp);
fmpz_init(t);
fmpz_sub_ui(t, &(b->coeffs[0]), 1);
fmpz_mod(t, t, p);
fmpz_mod_poly_set_coeff_fmpz(b, 0, t);
fmpz_clear(t);
fmpz_mod_poly_gcd(factor, b, pol);
if ((factor->length <= 1) || (factor->length == pol->length))
res = 0;
fmpz_mod_poly_clear(a);
fmpz_mod_poly_clear(b);
fmpz_mod_poly_clear(polinv);
fmpz_clear(p);
return res;
}

View File

@@ -0,0 +1,83 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_kaltofen_shoup(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t poly)
{
fmpz_mod_poly_t v;
fmpz_mod_poly_factor_t sq_free, dist_deg;
slong i, j, k, l, res_num, dist_deg_num;
slong *degs;
fmpz_mod_poly_init(v, &poly->p);
fmpz_mod_poly_make_monic(v, poly);
if (poly->length <= 2)
{
fmpz_mod_poly_factor_insert (res, v, 1);
fmpz_mod_poly_clear (v);
return;
}
if (!(degs = flint_malloc(fmpz_mod_poly_degree(poly) * sizeof(slong))))
{
flint_printf("Exception (fmpz_mod_poly_factor_kaltofen_shoup): \n");
flint_printf("Not enough memory.\n");
abort();
}
/* compute squarefree factorisation */
fmpz_mod_poly_factor_init(sq_free);
fmpz_mod_poly_factor_squarefree(sq_free, v);
/* compute distinct-degree factorisation */
fmpz_mod_poly_factor_init(dist_deg);
for (i = 0; i < sq_free->num; i++)
{
dist_deg_num = dist_deg->num;
fmpz_mod_poly_factor_distinct_deg(dist_deg, sq_free->poly + i, &degs);
/* compute equal-degree factorisation */
for (j = dist_deg_num, l = 0; j < dist_deg->num; j++, l++)
{
res_num = res->num;
fmpz_mod_poly_factor_equal_deg(res, dist_deg->poly + j, degs[l]);
for (k = res_num; k < res->num; k++)
res->exp[k] = fmpz_mod_poly_remove(v, res->poly + k);
}
}
flint_free(degs);
fmpz_mod_poly_clear(v);
fmpz_mod_poly_factor_clear(dist_deg);
fmpz_mod_poly_factor_clear(sq_free);
}

View File

@@ -0,0 +1,163 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
#include "ulong_extras.h"
void
fmpz_mod_poly_factor_squarefree(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_t f)
{
fmpz_mod_poly_t f_d, g, g_1, r;
fmpz_t p, x;
slong deg, i, p_ui;
if (f->length <= 1)
{
res->num = 0;
return;
}
if (f->length == 2)
{
fmpz_mod_poly_factor_insert(res, f, 1);
return;
}
fmpz_init(p);
fmpz_set(p, &f->p);
p_ui = fmpz_get_ui(p);
deg = fmpz_mod_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) */
fmpz_init(x);
fmpz_mod_poly_init(g_1, p);
fmpz_mod_poly_init(f_d, p);
fmpz_mod_poly_init(g, p);
fmpz_mod_poly_derivative(f_d, f);
/* Case 1 */
if (fmpz_mod_poly_is_zero(f_d))
{
fmpz_mod_poly_factor_t new_res;
fmpz_mod_poly_t h;
fmpz_mod_poly_init(h, p);
for (i = 0; i <= deg / p_ui; i++) /* this will be an integer since f'=0 */
{
fmpz_mod_poly_get_coeff_fmpz(x, f, i * p_ui);
fmpz_mod_poly_set_coeff_fmpz(h, i, x);
}
/* Now run squarefree on h, and return it to the pth power */
fmpz_mod_poly_factor_init(new_res);
fmpz_mod_poly_factor_squarefree(new_res, h);
fmpz_mod_poly_factor_pow(new_res, p_ui);
fmpz_mod_poly_factor_concat(res, new_res);
fmpz_mod_poly_clear(h);
fmpz_mod_poly_factor_clear(new_res);
}
else
{
fmpz_mod_poly_t h, z;
fmpz_mod_poly_init(r, p);
fmpz_mod_poly_gcd(g, f, f_d);
fmpz_mod_poly_divrem(g_1, r, f, g);
i = 1;
fmpz_mod_poly_init(h, p);
fmpz_mod_poly_init(z, p);
/* Case 2 */
while (g_1->length > 1)
{
fmpz_mod_poly_gcd(h, g_1, g);
fmpz_mod_poly_divrem(z, r, g_1, h);
/* out <- out.z */
if (z->length > 1)
{
fmpz_mod_poly_factor_insert(res, z, 1);
fmpz_mod_poly_make_monic(res->poly + (res->num - 1),
res->poly + (res->num - 1));
if (res->num)
res->exp[res->num - 1] *= i;
}
i++;
fmpz_mod_poly_set(g_1, h);
fmpz_mod_poly_divrem(g, r, g, h);
}
fmpz_mod_poly_clear(h);
fmpz_mod_poly_clear(z);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_make_monic(g, g);
if (g->length > 1)
{
/* so now we multiply res with squarefree(g^1/p) ^ p */
fmpz_mod_poly_t g_p; /* g^(1/p) */
fmpz_mod_poly_factor_t new_res_2;
fmpz_mod_poly_init(g_p, p);
for (i = 0; i <= fmpz_mod_poly_degree(g) / p_ui; i++)
{
fmpz_mod_poly_get_coeff_fmpz(x, g, i * p_ui);
fmpz_mod_poly_set_coeff_fmpz(g_p, i, x);
}
fmpz_mod_poly_factor_init(new_res_2);
/* squarefree(g^(1/p)) */
fmpz_mod_poly_factor_squarefree(new_res_2, g_p);
fmpz_mod_poly_factor_pow(new_res_2, p_ui);
fmpz_mod_poly_factor_concat(res, new_res_2);
fmpz_mod_poly_clear(g_p);
fmpz_mod_poly_factor_clear(new_res_2);
}
}
fmpz_clear(p);
fmpz_clear(x);
fmpz_mod_poly_clear(g_1);
fmpz_mod_poly_clear(f_d);
fmpz_mod_poly_clear(g);
}

View File

@@ -0,0 +1,41 @@
/*=============================================================================
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) 2011 Sebastian Pancratz
Copyright (C) 2008, 2009 William Hart
******************************************************************************/
#include <stdlib.h>
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_fit_length(fmpz_mod_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;
fmpz_mod_poly_factor_realloc(fac, len);
}
}

View File

@@ -0,0 +1,50 @@
/*=============================================================================
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 <gmp.h>
#include "flint.h"
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_init(fmpz_mod_poly_factor_t fac)
{
slong i;
fmpz_t p;
fac->alloc = 5;
fac->num = 0;
fac->poly = flint_malloc(sizeof(fmpz_mod_poly_struct) * 5);
fac->exp = flint_malloc(sizeof(slong) * 5);
fmpz_init_set_ui(p, 5);
for (i = 0; i < 5; i++)
fmpz_mod_poly_init(fac->poly + i, p);
fmpz_clear(p);
}

View File

@@ -0,0 +1,72 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_insert(fmpz_mod_poly_factor_t fac,
const fmpz_mod_poly_t poly, slong exp)
{
slong i;
fmpz_t p;
if (poly->length <= 1)
return;
for (i = 0; i < fac->num; i++)
{
if (fmpz_mod_poly_equal(poly, fac->poly + i))
{
fac->exp[i] += exp;
return;
}
}
if (fac->alloc == fac->num)
{
slong new_size = 2 * fac->alloc;
fac->poly =
flint_realloc(fac->poly, sizeof(fmpz_mod_poly_struct) * new_size);
fac->exp = flint_realloc(fac->exp, sizeof(slong) * new_size);
fmpz_init_set_ui(p, 5);
for (i = fac->alloc; i < new_size; i++)
fmpz_mod_poly_init(fac->poly + i, p);
fmpz_clear(p);
fac->alloc = new_size;
}
fmpz_mod_poly_set(fac->poly + fac->num, poly);
fmpz_set(&(fac->poly + fac->num)->p, &poly->p);
fac->exp[fac->num] = exp;
fac->num++;
}

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
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include "fmpz.h"
#include "fmpz_mod_poly.h"
#include "ulong_extras.h"
int
fmpz_mod_poly_is_irreducible(const fmpz_mod_poly_t f)
{
if (fmpz_mod_poly_length(f) > 2)
{
return fmpz_mod_poly_is_irreducible_ddf(f);
}
return 1;
}

View File

@@ -0,0 +1,146 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
int fmpz_mod_poly_is_irreducible_ddf(const fmpz_mod_poly_t poly)
{
fmpz_mod_poly_t f, v, vinv, reducedH0, tmp;
fmpz_mod_poly_t *h, *H, *I;
slong i, j, l, m, n, d;
fmpz_t p;
double beta;
int result = 1;
n = fmpz_mod_poly_degree(poly);
if (n < 2)
return 1;
if (!fmpz_mod_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 */
fmpz_init(p);
fmpz_set(p, &poly->p);
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_init(v, p);
fmpz_mod_poly_init(vinv, p);
fmpz_mod_poly_init(reducedH0, p);
fmpz_mod_poly_init(tmp, p);
if (!(h = flint_malloc((2 * m + l + 1) * sizeof(fmpz_mod_poly_struct))))
{
flint_printf("Exception (fmpz_mod_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++)
fmpz_mod_poly_init(h[i], p);
for (i = 0; i < m; i++)
{
fmpz_mod_poly_init(H[i], p);
fmpz_mod_poly_init(I[i], p);
}
fmpz_mod_poly_make_monic(v, poly);
fmpz_mod_poly_reverse (vinv, v, v->length);
fmpz_mod_poly_inv_series_newton (vinv, vinv, v->length);
/* compute baby steps: h[i]=x^{p^i}mod v */
fmpz_mod_poly_set_coeff_ui(h[0], 1, 1);
for (i = 1; i < l + 1; i++)
fmpz_mod_poly_powmod_fmpz_binexp_preinv(h[i], h[i - 1], p, v, vinv);
/* compute coarse distinct-degree factorisation */
fmpz_mod_poly_set(H[0], h[l]);
fmpz_mod_poly_set(reducedH0, H[0]);
d = 1;
for (j = 0; j < m; j++)
{
/* compute giant steps: H[i]=x^{p^(li)}mod v */
if (j > 0)
{
fmpz_mod_poly_rem (reducedH0, reducedH0, v);
fmpz_mod_poly_rem (tmp, H[j-1], v);
fmpz_mod_poly_compose_mod_brent_kung_preinv(H[j], tmp, reducedH0,
v, vinv);
}
/* compute interval polynomials */
fmpz_mod_poly_set_coeff_ui(I[j], 0, 1);
for (i = l - 1; (i >= 0) && (2*d <= v->length - 1); i--, d++)
{
fmpz_mod_poly_rem(tmp, h[i], v);
fmpz_mod_poly_sub(tmp, H[j], tmp);
fmpz_mod_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 */
fmpz_mod_poly_gcd(I[j], v, I[j]);
if (I[j]->length > 1)
{
result = 0;
break;
}
}
fmpz_clear(p);
fmpz_mod_poly_clear(f);
fmpz_mod_poly_clear(reducedH0);
fmpz_mod_poly_clear(v);
fmpz_mod_poly_clear(vinv);
fmpz_mod_poly_clear(tmp);
for (i = 0; i < l + 1; i++)
fmpz_mod_poly_clear(h[i]);
for (i = 0; i < m; i++)
{
fmpz_mod_poly_clear(H[i]);
fmpz_mod_poly_clear(I[i]);
}
flint_free(h);
return result;
}

View File

@@ -0,0 +1,112 @@
/*=============================================================================
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 "fmpz.h"
#include "fmpz_mod_poly.h"
#include "ulong_extras.h"
void
fmpz_mod_poly_powpowmod(fmpz_mod_poly_t res, const fmpz_mod_poly_t pol,
const fmpz_t exp, ulong exp2, const fmpz_mod_poly_t f)
{
fmpz_mod_poly_t pow;
ulong i;
fmpz_mod_poly_init(pow, &f->p);
fmpz_mod_poly_powmod_fmpz_binexp(pow, pol, exp, f);
fmpz_mod_poly_set(res, pow);
if (!fmpz_mod_poly_equal(pow, pol))
for (i = 1; i < exp2; i++)
fmpz_mod_poly_powmod_fmpz_binexp(res, res, exp, f);
fmpz_mod_poly_clear(pow);
}
int
fmpz_mod_poly_is_irreducible_rabin(const fmpz_mod_poly_t f)
{
if (fmpz_mod_poly_length(f) > 2)
{
const slong n = fmpz_mod_poly_degree(f);
fmpz_mod_poly_t a, x, x_p;
fmpz_mod_poly_init(a, &f->p);
fmpz_mod_poly_init(x, &f->p);
fmpz_mod_poly_init(x_p, &f->p);
fmpz_mod_poly_set_coeff_ui(x, 1, 1);
/* Compute x^q mod f */
fmpz_mod_poly_powpowmod(x_p, x, &f->p, n, f);
if (!fmpz_mod_poly_is_zero(x_p))
fmpz_mod_poly_make_monic(x_p, x_p);
/* Now do the irreducibility test */
if (!fmpz_mod_poly_equal(x_p, x))
{
fmpz_mod_poly_clear(a);
fmpz_mod_poly_clear(x);
fmpz_mod_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++)
{
fmpz_mod_poly_powpowmod(a, x, &f->p, n / factors.p[i], f);
fmpz_mod_poly_sub(a, a, x);
if (!fmpz_mod_poly_is_zero(a))
fmpz_mod_poly_make_monic(a, a);
fmpz_mod_poly_gcd(a, a, f);
if (a->length != 1)
{
fmpz_mod_poly_clear(a);
fmpz_mod_poly_clear(x);
fmpz_mod_poly_clear(x_p);
return 0;
}
}
}
fmpz_mod_poly_clear(a);
fmpz_mod_poly_clear(x);
fmpz_mod_poly_clear(x_p);
}
return 1;
}

View File

@@ -0,0 +1,68 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include "fmpz_mod_poly.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
#include <string.h>
int
_fmpz_mod_poly_is_squarefree(const fmpz * f, slong len, const fmpz_t p)
{
fmpz * fd, * g;
fmpz_t invd;
slong dlen;
int res;
if (len <= 2)
return len != 0;
fd = _fmpz_vec_init(2 * (len - 1));
g = fd + len - 1;
_fmpz_mod_poly_derivative(fd, f, len, p);
dlen = len - 1;
FMPZ_VEC_NORM(fd, dlen);
if (dlen)
{
fmpz_init(invd);
fmpz_invmod(invd, fd + dlen - 1, p);
res = (_fmpz_mod_poly_gcd(g, f, len, fd, dlen, invd, p) == 1);
fmpz_clear(invd);
}
else
res = 0; /* gcd(f, 0) = f, and len(f) > 2 */
_fmpz_vec_clear(fd, 2 * (len - 1));
return res;
}
int fmpz_mod_poly_is_squarefree(const fmpz_mod_poly_t f)
{
return _fmpz_mod_poly_is_squarefree(f->coeffs, f->length, &f->p);
}

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
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include <stdlib.h>
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_pow(fmpz_mod_poly_factor_t fac, slong exp)
{
slong i;
for (i = 0; i < fac->num; i++)
fac->exp[i] *= exp;
}

View File

@@ -0,0 +1,45 @@
/*=============================================================================
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 <stdio.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_print(const fmpz_mod_poly_factor_t fac)
{
slong i;
for (i = 0; i < fac->num; i++)
{
fmpz_mod_poly_print(fac->poly + i);
flint_printf(" ^ %wd\n", fac->exp[i]);
}
}

View File

@@ -0,0 +1,377 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
#define NP 20 /* number of moduli */
#define ND 8 /* number of degrees */
/*
Benchmarking code for factorisation in fmpz_mod_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);
fmpz_mod_poly_t f, g;
fmpz_mod_poly_factor_t res;
fmpz_t p;
mpz_t pz, curr;
int i, j, k, n, num;
double t, T1, T2, T3;
const slong degs[] = {8, 16, 32, 64, 128, 256, 512, 1024};
const int iter_count[] = {10000, 5000, 1000, 500, 300, 100, 50, 20};
mpz_init(pz);
mpz_init(curr);
fmpz_init(p);
flint_printf("Random polynomials\n");
flint_mpz_set_ui(pz, 2);
flint_mpz_set_ui(curr, 10);
for (i = 0; i < NP; i++)
{
fmpz_set_mpz(p, pz);
flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n");
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++)
{
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_randtest_not_zero(f, state, n);
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_cantor_zassenhaus(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_berlekamp(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_kaltofen_shoup(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
fmpz_mod_poly_clear(f);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
mpz_nextprime(pz, curr);
flint_mpz_mul_ui(curr, curr, 10);
}
/* This code checks whether fmpz_mod_poly_factor
made a correct choice between CZ and KS */
flint_printf("Check choice correctness\n");
flint_mpz_set_ui(pz, 2);
flint_mpz_set_ui(curr, 10);
for (i = 0; i < NP; i++)
{
fmpz_set_mpz(p, pz);
flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n");
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++)
{
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_randtest_not_zero(f, state, n);
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_cantor_zassenhaus(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_kaltofen_shoup(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
fmpz_mod_poly_clear(f);
}
flint_printf("CZ: %.2lf F: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
mpz_nextprime(pz, curr);
flint_mpz_mul_ui(curr, curr, 10);
}
flint_printf("Irreducible polynomials\n");
flint_mpz_set_ui(pz, 2);
flint_mpz_set_ui(curr, 10);
for (i = 0; i < NP; i++)
{
fmpz_set_mpz(p, pz);
flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n");
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++)
{
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_randtest_irreducible(f, state, n);
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_cantor_zassenhaus(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_berlekamp(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_kaltofen_shoup(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
fmpz_mod_poly_clear(f);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
mpz_nextprime(pz, curr);
flint_mpz_mul_ui(curr, curr, 10);
}
flint_printf("Product of two irreducible polynomials\n");
flint_mpz_set_ui(pz, 2);
flint_mpz_set_ui(curr, 10);
for (i = 0; i < NP; i++)
{
fmpz_set_mpz(p, pz);
flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n");
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++)
{
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_init(g, p);
fmpz_mod_poly_randtest_irreducible(f, state, n);
fmpz_mod_poly_randtest_irreducible(g, state, n);
fmpz_mod_poly_mul(f, f, g);
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_cantor_zassenhaus(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_berlekamp(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_kaltofen_shoup(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
fmpz_mod_poly_clear(f);
fmpz_mod_poly_clear(g);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
mpz_nextprime(pz, curr);
flint_mpz_mul_ui(curr, curr, 10);
}
flint_printf("Product of 8 small irreducible polynomials\n");
flint_mpz_set_ui(pz, 2);
flint_mpz_set_ui(curr, 10);
for (i = 0; i < NP; i++)
{
fmpz_set_mpz(p, pz);
flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n");
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++)
{
fmpz_mod_poly_init(f, p);
fmpz_mod_poly_init(g, p);
fmpz_mod_poly_randtest_irreducible(f, state, n);
for (num = 1; num < 8; num++)
{
fmpz_mod_poly_randtest_irreducible(g, state, n);
fmpz_mod_poly_mul(f, f, g);
}
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_cantor_zassenhaus(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T1 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_berlekamp(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T2 += t;
t = clock();
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_kaltofen_shoup(res, f);
fmpz_mod_poly_factor_clear(res);
t = (clock() - t) / CLOCKS_PER_SEC;
T3 += t;
fmpz_mod_poly_clear(f);
fmpz_mod_poly_clear(g);
}
flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3);
fflush(stdout);
if (T1 > T3 + 1)
break;
}
mpz_nextprime(pz, curr);
flint_mpz_mul_ui(curr, curr, 10);
}
mpz_clear(pz);
mpz_clear(curr);
fmpz_clear(p);
FLINT_TEST_CLEANUP(state);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,84 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <stdlib.h>
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_realloc(fmpz_mod_poly_factor_t fac, slong alloc)
{
fmpz_t p;
fmpz_init_set_ui(p, 5);
if (alloc == 0) /* Clear up, reinitialise */
{
fmpz_mod_poly_factor_clear(fac);
fmpz_mod_poly_factor_init(fac);
}
else if (fac->alloc) /* Realloc */
{
if (fac->alloc > alloc)
{
slong i;
for (i = alloc; i < fac->num; i++)
fmpz_mod_poly_clear(fac->poly + i);
fac->poly =
flint_realloc(fac->poly, alloc * sizeof(fmpz_mod_poly_struct));
fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong));
fac->alloc = alloc;
}
else if (fac->alloc < alloc)
{
slong i;
fac->poly =
flint_realloc(fac->poly, alloc * sizeof(fmpz_mod_poly_struct));
fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong));
for (i = fac->alloc; i < alloc; i++)
{
fmpz_mod_poly_init(fac->poly + i, p);
fac->exp[i] = WORD(0);
}
fac->alloc = alloc;
}
}
else /* Nothing allocated already so do it now */
{
slong i;
fac->poly = flint_malloc(alloc * sizeof(fmpz_mod_poly_struct));
fac->exp = flint_calloc(alloc, sizeof(slong));
for (i = 0; i < alloc; i++)
fmpz_mod_poly_init(fac->poly + i, p);
fac->num = 0;
fac->alloc = alloc;
}
fmpz_clear(p);
}

View File

@@ -0,0 +1,59 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include "flint.h"
#include "fmpz_mod_poly.h"
void
fmpz_mod_poly_factor_set(fmpz_mod_poly_factor_t res,
const fmpz_mod_poly_factor_t fac)
{
if (res != fac)
{
if (fac->num == 0)
{
fmpz_mod_poly_factor_clear(res);
fmpz_mod_poly_factor_init(res);
}
else
{
slong i;
fmpz_mod_poly_factor_fit_length(res, fac->num);
for (i = 0; i < fac->num; i++)
{
fmpz_mod_poly_set(res->poly + i, fac->poly + i);
res->exp[i] = fac->exp[i];
}
for (; i < res->num; i++)
{
fmpz_mod_poly_zero(res->poly + i);
res->exp[i] = 0;
}
res->num = fac->num;
}
}
}

View File

@@ -0,0 +1,142 @@
/*=============================================================================
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 "fmpz_mod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor....");
fflush(stdout);
for (iter = 0; iter < 200; iter++)
{
fmpz_mod_poly_t poly1, poly, q, r, product;
fmpz_mod_poly_factor_t res;
fmpz_t modulus;
slong i, j, length, num;
slong exp[5];
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(q, modulus);
fmpz_mod_poly_init(r, modulus);
fmpz_mod_poly_zero(poly1);
fmpz_mod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
fmpz_mod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)));
exp[0] = n_randint(state, 30) + 1;
for (i = 0; i < exp[0]; i++)
fmpz_mod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
{
fmpz_mod_poly_make_monic(poly, poly);
fmpz_mod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))
|| (r->length == 0));
exp[i] = n_randint(state, 30) + 1;
for (j = 0; j < exp[i]; j++)
fmpz_mod_poly_mul(poly1, poly1, poly);
}
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor(res, poly1);
if (res->num != num)
{
flint_printf("Error: number of factors incorrect: %wd != %wd\n",
res->num, num);
abort();
}
fmpz_mod_poly_init(product, &poly1->p);
fmpz_mod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
fmpz_mod_poly_mul(product, product, res->poly + i);
fmpz_mod_poly_scalar_mul_fmpz(product, product,
&(poly1->coeffs[poly1->length - 1]));
if (!fmpz_mod_poly_equal(poly1, product))
{
flint_printf
("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
flint_printf("product:\n");
fmpz_mod_poly_print(product);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(product);
fmpz_mod_poly_clear(q);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly);
fmpz_mod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,142 @@
/*=============================================================================
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 "fmpz_mod_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 < 200; iter++)
{
fmpz_mod_poly_t poly1, poly, q, r, product;
fmpz_mod_poly_factor_t res;
fmpz_t modulus;
slong i, j, length, num;
slong exp[5];
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(q, modulus);
fmpz_mod_poly_init(r, modulus);
fmpz_mod_poly_zero(poly1);
fmpz_mod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
fmpz_mod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)));
exp[0] = n_randint(state, 30) + 1;
for (i = 0; i < exp[0]; i++)
fmpz_mod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
{
fmpz_mod_poly_make_monic(poly, poly);
fmpz_mod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))
|| (r->length == 0));
exp[i] = n_randint(state, 30) + 1;
for (j = 0; j < exp[i]; j++)
fmpz_mod_poly_mul(poly1, poly1, poly);
}
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_berlekamp(res, poly1);
if (res->num != num)
{
flint_printf("Error: number of factors incorrect: %wd != %wd\n",
res->num, num);
abort();
}
fmpz_mod_poly_init(product, &poly1->p);
fmpz_mod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
fmpz_mod_poly_mul(product, product, res->poly + i);
fmpz_mod_poly_scalar_mul_fmpz(product, product,
&(poly1->coeffs[poly1->length - 1]));
if (!fmpz_mod_poly_equal(poly1, product))
{
flint_printf
("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
flint_printf("product:\n");
fmpz_mod_poly_print(product);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(product);
fmpz_mod_poly_clear(q);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly);
fmpz_mod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,142 @@
/*=============================================================================
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 "fmpz_mod_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 < 200; iter++)
{
fmpz_mod_poly_t poly1, poly, q, r, product;
fmpz_mod_poly_factor_t res;
fmpz_t modulus;
slong i, j, length, num;
slong exp[5];
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(q, modulus);
fmpz_mod_poly_init(r, modulus);
fmpz_mod_poly_zero(poly1);
fmpz_mod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
fmpz_mod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)));
exp[0] = n_randint(state, 30) + 1;
for (i = 0; i < exp[0]; i++)
fmpz_mod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
{
fmpz_mod_poly_make_monic(poly, poly);
fmpz_mod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))
|| (r->length == 0));
exp[i] = n_randint(state, 30) + 1;
for (j = 0; j < exp[i]; j++)
fmpz_mod_poly_mul(poly1, poly1, poly);
}
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_cantor_zassenhaus(res, poly1);
if (res->num != num)
{
flint_printf("Error: number of factors incorrect: %wd != %wd\n",
res->num, num);
abort();
}
fmpz_mod_poly_init(product, &poly1->p);
fmpz_mod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
fmpz_mod_poly_mul(product, product, res->poly + i);
fmpz_mod_poly_scalar_mul_fmpz(product, product,
&(poly1->coeffs[poly1->length - 1]));
if (!fmpz_mod_poly_equal(poly1, product))
{
flint_printf
("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
flint_printf("product:\n");
fmpz_mod_poly_print(product);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(product);
fmpz_mod_poly_clear(q);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly);
fmpz_mod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,137 @@
/*=============================================================================
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 "fmpz_mod_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++)
{
fmpz_mod_poly_t poly1, poly, q, r, product;
fmpz_mod_poly_factor_t res;
fmpz_t modulus;
slong i, length, num;
slong *degs;
fmpz_init(modulus);
fmpz_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(q, modulus);
fmpz_mod_poly_init(r, modulus);
fmpz_mod_poly_zero(poly1);
fmpz_mod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
fmpz_mod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)));
fmpz_mod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
{
fmpz_mod_poly_make_monic(poly, poly);
fmpz_mod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))
|| (r->length == 0));
fmpz_mod_poly_mul(poly1, poly1, poly);
}
if (!(degs = flint_malloc((poly1->length - 1) * sizeof(slong))))
{
flint_printf("Fatal error: not enough memory.");
abort();
}
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_distinct_deg(res, poly1, &degs);
fmpz_mod_poly_init(product, &poly1->p);
fmpz_mod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
fmpz_mod_poly_mul(product, product, res->poly + i);
fmpz_mod_poly_scalar_mul_fmpz(product, product,
&(poly1->coeffs[poly1->length - 1]));
if (!fmpz_mod_poly_equal(poly1, product))
{
flint_printf
("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
flint_printf("product:\n");
fmpz_mod_poly_print(product);
flint_printf("\n");
abort();
}
flint_free(degs);
fmpz_clear(modulus);
fmpz_mod_poly_clear(product);
fmpz_mod_poly_clear(q);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly);
fmpz_mod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,108 @@
/*=============================================================================
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 <stdlib.h>
#include "fmpz_mod_poly.h"
#include "ulong_extras.h"
int
main(void)
{
int iter;
FLINT_TEST_INIT(state);
flint_printf("factor_equal_deg_prob....");
fflush(stdout);
for (iter = 0; iter < 200; iter++)
{
fmpz_mod_poly_t poly1, poly2, q, r;
fmpz_t modulus;
slong length;
int i, num;
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(q, modulus);
fmpz_mod_poly_init(r, modulus);
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly2, modulus);
length = n_randint(state, 10) + 2;
do
{
fmpz_mod_poly_randtest(poly1, state, length);
if (poly1->length)
fmpz_mod_poly_make_monic(poly1, poly1);
}
while ((poly1->length < 2) || (!fmpz_mod_poly_is_irreducible(poly1)));
num = n_randint(state, 5) + 1;
for (i = 0; i < num; i++)
{
do
{
fmpz_mod_poly_randtest(poly2, state, length);
if (poly2->length)
fmpz_mod_poly_make_monic(poly2, poly2);
}
while ((poly2->length < 2)
|| (!fmpz_mod_poly_is_irreducible(poly2)));
fmpz_mod_poly_mul(poly1, poly1, poly2);
}
while (!fmpz_mod_poly_factor_equal_deg_prob
(poly2, state, poly1, length - 1))
{
};
fmpz_mod_poly_divrem(q, r, poly1, poly2);
if (!fmpz_mod_poly_is_zero(r))
{
flint_printf("FAIL:\n");
flint_printf("Error: factor does not divide original polynomial\n");
flint_printf("factor:\n");
fmpz_mod_poly_print(poly2);
flint_printf("\n\n");
flint_printf("polynomial:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(q);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,142 @@
/*=============================================================================
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 "fmpz_mod_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++)
{
fmpz_mod_poly_t poly1, poly, q, r, product;
fmpz_mod_poly_factor_t res;
fmpz_t modulus;
slong i, j, length, num;
slong exp[5];
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(q, modulus);
fmpz_mod_poly_init(r, modulus);
fmpz_mod_poly_zero(poly1);
fmpz_mod_poly_set_coeff_ui(poly1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
fmpz_mod_poly_make_monic(poly, poly);
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)));
exp[0] = n_randint(state, 30) + 1;
for (i = 0; i < exp[0]; i++)
fmpz_mod_poly_mul(poly1, poly1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
{
fmpz_mod_poly_make_monic(poly, poly);
fmpz_mod_poly_divrem(q, r, poly1, poly);
}
}
while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))
|| (r->length == 0));
exp[i] = n_randint(state, 30) + 1;
for (j = 0; j < exp[i]; j++)
fmpz_mod_poly_mul(poly1, poly1, poly);
}
fmpz_mod_poly_factor_init(res);
fmpz_mod_poly_factor_kaltofen_shoup(res, poly1);
if (res->num != num)
{
flint_printf("Error: number of factors incorrect: %wd != %wd\n",
res->num, num);
abort();
}
fmpz_mod_poly_init(product, &poly1->p);
fmpz_mod_poly_set_coeff_ui(product, 0, 1);
for (i = 0; i < res->num; i++)
for (j = 0; j < res->exp[i]; j++)
fmpz_mod_poly_mul(product, product, res->poly + i);
fmpz_mod_poly_scalar_mul_fmpz(product, product,
&(poly1->coeffs[poly1->length - 1]));
if (!fmpz_mod_poly_equal(poly1, product))
{
flint_printf
("Error: product of factors does not equal to the original polynomial\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
flint_printf("product:\n");
fmpz_mod_poly_print(product);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(product);
fmpz_mod_poly_clear(q);
fmpz_mod_poly_clear(r);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly);
fmpz_mod_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
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz_vec.h"
#include "fmpz_mod_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 < 300; iter++)
{
int result = 1;
fmpz_mod_poly_t pol1, poly, quot, rem;
fmpz_mod_poly_factor_t res;
fmpz_t modulus;
slong exp[5], prod1;
slong length, i, j, num;
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(pol1, modulus);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(quot, modulus);
fmpz_mod_poly_init(rem, modulus);
fmpz_mod_poly_zero(pol1);
fmpz_mod_poly_set_coeff_ui(pol1, 0, 1);
length = n_randint(state, 7) + 2;
do
{
fmpz_mod_poly_randtest(poly, state, length);
fmpz_mod_poly_make_monic(poly, poly);
}
while ((!fmpz_mod_poly_is_irreducible(poly)) || (poly->length < 2));
exp[0] = n_randprime(state, 5, 0);
prod1 = exp[0];
for (i = 0; i < exp[0]; i++)
fmpz_mod_poly_mul(pol1, pol1, poly);
num = n_randint(state, 5) + 1;
for (i = 1; i < num; i++)
{
do
{
length = n_randint(state, 7) + 2;
fmpz_mod_poly_randtest(poly, state, length);
if (poly->length)
{
fmpz_mod_poly_make_monic(poly, poly);
fmpz_mod_poly_divrem(quot, rem, pol1, poly);
}
}
while ((!fmpz_mod_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++)
fmpz_mod_poly_mul(pol1, pol1, poly);
}
fmpz_mod_poly_factor_init(res);
fmpz_mod_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 = ");
fmpz_print(modulus);
flint_printf("\n");
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();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(quot);
fmpz_mod_poly_clear(rem);
fmpz_mod_poly_clear(pol1);
fmpz_mod_poly_clear(poly);
fmpz_mod_poly_factor_clear(res);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,99 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz_vec.h"
#include "fmpz_mod_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 < 100; iter++)
{
fmpz_mod_poly_t poly1, poly2;
fmpz_t modulus;
slong length;
int i, num;
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly2, modulus);
length = n_randint(state, 10) + 2;
do
{
fmpz_mod_poly_randtest(poly1, state, length);
if (!fmpz_mod_poly_is_zero(poly1))
fmpz_mod_poly_make_monic(poly1, poly1);
}
while ((!fmpz_mod_poly_is_irreducible(poly1)) || (poly1->length < 2));
num = n_randint(state, 5) + 1;
for (i = 0; i < num; i++)
{
do
{
fmpz_mod_poly_randtest(poly2, state, length);
if (!fmpz_mod_poly_is_zero(poly1))
fmpz_mod_poly_make_monic(poly2, poly2);
}
while ((!fmpz_mod_poly_is_irreducible(poly2)) || (poly2->length < 2));
fmpz_mod_poly_mul(poly1, poly1, poly2);
}
if (fmpz_mod_poly_is_irreducible(poly1))
{
flint_printf("Error: reducible polynomial declared irreducible!\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,99 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz_vec.h"
#include "fmpz_mod_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 < 100; iter++)
{
fmpz_mod_poly_t poly1, poly2;
fmpz_t modulus;
slong length;
int i, num;
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly2, modulus);
length = n_randint(state, 10) + 2;
do
{
fmpz_mod_poly_randtest(poly1, state, length);
if (!fmpz_mod_poly_is_zero(poly1))
fmpz_mod_poly_make_monic(poly1, poly1);
}
while ((!fmpz_mod_poly_is_irreducible_ddf(poly1)) || (poly1->length < 2));
num = n_randint(state, 5) + 1;
for (i = 0; i < num; i++)
{
do
{
fmpz_mod_poly_randtest(poly2, state, length);
if (!fmpz_mod_poly_is_zero(poly1))
fmpz_mod_poly_make_monic(poly2, poly2);
}
while ((!fmpz_mod_poly_is_irreducible_ddf(poly2)) || (poly2->length < 2));
fmpz_mod_poly_mul(poly1, poly1, poly2);
}
if (fmpz_mod_poly_is_irreducible_ddf(poly1))
{
flint_printf("Error: reducible polynomial declared irreducible!\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,99 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz_vec.h"
#include "fmpz_mod_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 < 100; iter++)
{
fmpz_mod_poly_t poly1, poly2;
fmpz_t modulus;
slong length;
int i, num;
fmpz_init_set_ui(modulus, n_randtest_prime(state, 0));
fmpz_mod_poly_init(poly1, modulus);
fmpz_mod_poly_init(poly2, modulus);
length = n_randint(state, 10) + 2;
do
{
fmpz_mod_poly_randtest(poly1, state, length);
if (!fmpz_mod_poly_is_zero(poly1))
fmpz_mod_poly_make_monic(poly1, poly1);
}
while ((!fmpz_mod_poly_is_irreducible_rabin(poly1)) || (poly1->length < 2));
num = n_randint(state, 5) + 1;
for (i = 0; i < num; i++)
{
do
{
fmpz_mod_poly_randtest(poly2, state, length);
if (!fmpz_mod_poly_is_zero(poly1))
fmpz_mod_poly_make_monic(poly2, poly2);
}
while ((!fmpz_mod_poly_is_irreducible_rabin(poly2)) || (poly2->length < 2));
fmpz_mod_poly_mul(poly1, poly1, poly2);
}
if (fmpz_mod_poly_is_irreducible_rabin(poly1))
{
flint_printf("Error: reducible polynomial declared irreducible!\n");
flint_printf("poly:\n");
fmpz_mod_poly_print(poly1);
flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(poly1);
fmpz_mod_poly_clear(poly2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,112 @@
/*=============================================================================
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) 2012 Lina Kulakova
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz_vec.h"
#include "fmpz_mod_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++)
{
fmpz_mod_poly_t poly, Q, R, t;
fmpz_t modulus;
mp_limb_t mod;
slong i, num_factors, exp, max_exp;
int v, result;
mod = n_randtest_prime(state, 0);
fmpz_init_set_ui(modulus, mod);
fmpz_mod_poly_init(poly, modulus);
fmpz_mod_poly_init(t, modulus);
fmpz_mod_poly_init(Q, modulus);
fmpz_mod_poly_init(R, modulus);
fmpz_mod_poly_set_coeff_ui(poly, 0, n_randint(state, mod));
num_factors = n_randint(state, 5);
max_exp = 0;
for (i = 0; i < num_factors; i++)
{
do {
fmpz_mod_poly_randtest(t, state, n_randint(state, 10));
} while (!fmpz_mod_poly_is_irreducible(t) ||
(fmpz_mod_poly_length(t) < 2));
exp = n_randint(state, 4) + 1;
if (n_randint(state, 2) == 0)
exp = 1;
fmpz_mod_poly_divrem(Q, R, poly, t);
if (!fmpz_mod_poly_is_zero(R))
{
fmpz_mod_poly_pow(t, t, exp);
fmpz_mod_poly_mul(poly, poly, t);
max_exp = FLINT_MAX(exp, max_exp);
}
}
v = fmpz_mod_poly_is_squarefree(poly);
if (v == 1)
result = (max_exp <= 1 && !fmpz_mod_poly_is_zero(poly));
else
result = (max_exp > 1 || fmpz_mod_poly_is_zero(poly));
if (!result)
{
flint_printf("FAIL: ");
fmpz_print(modulus);
flint_printf(" %wd, %d\n", max_exp, v);
fmpz_mod_poly_print(poly); flint_printf("\n");
abort();
}
fmpz_clear(modulus);
fmpz_mod_poly_clear(poly);
fmpz_mod_poly_clear(t);
fmpz_mod_poly_clear(Q);
fmpz_mod_poly_clear(R);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}