147 lines
4.3 KiB
C
147 lines
4.3 KiB
C
|
/*=============================================================================
|
||
|
|
||
|
This file is part of FLINT.
|
||
|
|
||
|
FLINT is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
FLINT is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with FLINT; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
|
||
|
=============================================================================*/
|
||
|
/******************************************************************************
|
||
|
|
||
|
Copyright (C) 2011 Andy Novocin
|
||
|
Copyright (C) 2011 William Hart
|
||
|
Copyright (C) 2011 Sebastian Pancratz
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include "fmpz_poly.h"
|
||
|
|
||
|
#define TRACE 0
|
||
|
|
||
|
void fmpz_poly_factor_zassenhaus_recombination(fmpz_poly_factor_t final_fac,
|
||
|
const fmpz_poly_factor_t lifted_fac,
|
||
|
const fmpz_poly_t F, const fmpz_t P, slong exp)
|
||
|
{
|
||
|
const slong r = lifted_fac->num;
|
||
|
|
||
|
slong k, *used_arr, *sub_arr;
|
||
|
fmpz_poly_t f, Q, R, tryme;
|
||
|
fmpz *leadF;
|
||
|
|
||
|
used_arr = flint_calloc(2 * r, sizeof(slong));
|
||
|
sub_arr = used_arr + r;
|
||
|
|
||
|
fmpz_poly_init(f);
|
||
|
fmpz_poly_init(Q);
|
||
|
fmpz_poly_init(R);
|
||
|
fmpz_poly_init(tryme);
|
||
|
fmpz_poly_set(f, F);
|
||
|
|
||
|
#if TRACE == 1
|
||
|
fmpz_poly_factor_print(lifted_fac); flint_printf(" lifted_fac\n");
|
||
|
#endif
|
||
|
|
||
|
leadF = fmpz_poly_lead(F);
|
||
|
|
||
|
for (k = 1; k < r; k++)
|
||
|
{
|
||
|
slong count = 0, indx = k - 1, l;
|
||
|
|
||
|
for(l = 0; l < k; l++)
|
||
|
sub_arr[l] = l;
|
||
|
|
||
|
sub_arr[indx]--;
|
||
|
while ((indx >= 0))
|
||
|
{
|
||
|
sub_arr[indx] = sub_arr[indx] + 1;
|
||
|
|
||
|
for (l = indx + 1; l < k; l++)
|
||
|
sub_arr[l] = sub_arr[l - 1] + 1;
|
||
|
|
||
|
if (sub_arr[k - 1] > r - 1)
|
||
|
indx--;
|
||
|
else
|
||
|
{
|
||
|
for(l = 0; l < k; l++)
|
||
|
{
|
||
|
if (used_arr[sub_arr[l]] == 1)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Need to involve leadF, perhaps set coeff 0 to leadF and do
|
||
|
leadF * rest and check if under M_bits... here I'm using a
|
||
|
trial division... */
|
||
|
fmpz_poly_set_fmpz(tryme, leadF);
|
||
|
|
||
|
for(l = 0; l < k; l++)
|
||
|
fmpz_poly_mul(tryme, tryme, lifted_fac->p + (sub_arr[l]));
|
||
|
|
||
|
fmpz_poly_scalar_smod_fmpz(tryme, tryme, P);
|
||
|
fmpz_poly_primitive_part(tryme, tryme);
|
||
|
fmpz_poly_divrem(Q, R, f, tryme);
|
||
|
|
||
|
#if TRACE == 1
|
||
|
fmpz_poly_print(tryme); flint_printf(" is tryme\n");
|
||
|
fmpz_poly_print(R); flint_printf(" is R\n");
|
||
|
#endif
|
||
|
|
||
|
if (fmpz_poly_is_zero(R))
|
||
|
{
|
||
|
fmpz_poly_factor_insert(final_fac, tryme, exp);
|
||
|
|
||
|
for(l = 0; l < k; l++)
|
||
|
{
|
||
|
used_arr[sub_arr[l]] = 1;
|
||
|
count++;
|
||
|
}
|
||
|
|
||
|
fmpz_poly_set(f, Q);
|
||
|
leadF = fmpz_poly_lead(f);
|
||
|
/* If r - count = k then the rest are irreducible.
|
||
|
TODO: Add a test for that case */
|
||
|
}
|
||
|
|
||
|
indx = k - 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* This is where we switch to the next loop for k. So we will have
|
||
|
found all factors using <= k local factors. We should/could update
|
||
|
f to be the rest divided away (or multiply the remaining), could
|
||
|
also adjust r. It is the number of remaining factors so if you
|
||
|
update then test if r = k or k+1 in which case the remaining f is
|
||
|
irreducible. */
|
||
|
}
|
||
|
|
||
|
{
|
||
|
slong test = 0;
|
||
|
|
||
|
for (k = 0; k < r; k++)
|
||
|
test = test + used_arr[k];
|
||
|
|
||
|
if (test == 0)
|
||
|
fmpz_poly_factor_insert(final_fac, f, exp);
|
||
|
}
|
||
|
|
||
|
fmpz_poly_clear(f);
|
||
|
fmpz_poly_clear(tryme);
|
||
|
fmpz_poly_clear(Q);
|
||
|
fmpz_poly_clear(R);
|
||
|
flint_free(used_arr);
|
||
|
}
|
||
|
|
||
|
#undef TRACE
|
||
|
|