/*
Copyright (C) 2011 Andy Novocin
Copyright (C) 2016 William Hart
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#include
#include
#include "flint.h"
#include "fmpz_poly.h"
#define LONG_FAC_TEST 0 /* run an extra long test */
#define TEST_HARD 0 /* test hard polynomials */
#if LONG_FAC_TEST
#define FAC_MULT 5
#else
#define FAC_MULT 1
#endif
#if TEST_HARD
#include
void factor_poly(const char * file_str, const char * name)
{
FILE * file;
fmpz_poly_t f;
fmpz_poly_factor_t fac;
struct timeval start, stop;
ulong ms;
fmpz_poly_init(f);
file = fopen(file_str, "rw");
fmpz_poly_fread(file, f);
fmpz_poly_factor_init(fac);
gettimeofday(&start, NULL);
fmpz_poly_factor(fac, f);
gettimeofday(&stop, NULL);
ms = (stop.tv_sec - start.tv_sec)*1000 + (stop.tv_usec - start.tv_usec) / 1000;
flint_printf("%s has %wd factors\n", name, fac->num);
flint_printf("Time to factor %s: %ld ms\n\n", name, ms);
fmpz_poly_factor_clear(fac);
fclose(file);
fmpz_poly_clear(f);
}
#endif
int
main(void)
{
int i, result;
int tmul = 100;
#ifdef _WIN32
tmul = 1;
#endif
FLINT_TEST_INIT(state);
flint_printf("factor....");
fflush(stdout);
#if TEST_HARD
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P1_flint", "P1");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P2_flint", "P2");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P3_flint", "P3");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P4_flint", "P4");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P5_flint", "P5");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P6_flint", "P6");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P7_flint", "P7");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/P8_flint", "P8");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/M12_5_flint", "M12_5");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/M12_6_flint", "M12_6");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/T1_flint", "T1");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/T2_flint", "T2");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/T3_flint", "T3");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/H1_flint", "H1");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/S7_flint", "S7");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/S8_flint", "S8");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/C1_flint", "C1");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/S9_flint", "S9");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/S10_flint", "S10");
factor_poly("/home/wbhart/.julia/v0.5/Nemo/deps/flint2/fmpz_poly_factor/test/H2_flint", "H2");
#endif
for (i = 0; i < tmul * flint_test_multiplier(); i++)
{
fmpz_t c;
fmpz_poly_t f, g, h, t;
fmpz_poly_factor_t fac;
slong j, k, n = n_randint(state, 10*FAC_MULT);
slong facs1 = 0, facs2 = 0;
fmpz_init(c);
fmpz_poly_init(f);
fmpz_poly_init(g);
fmpz_poly_init(h);
fmpz_poly_init(t);
fmpz_poly_factor_init(fac);
fmpz_randtest_not_zero(c, state, n_randint(state, 10) + 1);
fmpz_poly_set_fmpz(f, c);
for (j = 0; j < n; j++)
{
do {
fmpz_poly_randtest(g, state, n_randint(state, 10) + 2, n_randint(state, 100));
} while (g->length == 0);
k = 0;
while (k < g->length && fmpz_is_zero(g->coeffs + k))
k++;
facs1 += k; /* count powers of x separately */
if (k < g->length - 1)
facs1++; /* rough lower bound of factors of f */
fmpz_poly_mul(f, f, g);
}
fmpz_poly_factor(fac, f);
fmpz_poly_set_fmpz(h, &fac->c);
for (j = 0; j < fac->num; j++)
{
if (fac->exp[j] == 1)
fmpz_poly_mul(h, h, fac->p + j);
else
{
fmpz_poly_pow(t, fac->p + j, fac->exp[j]);
fmpz_poly_mul(h, h, t);
}
facs2 += fac->exp[j];
}
result = fmpz_poly_equal(f, h) && facs1 <= facs2;
if (!result)
{
flint_printf("FAIL:\n");
flint_printf("facs1 = %wd, facs2 = %wd\n", facs1, facs2);
flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n");
flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n");
flint_printf("fac = "), fmpz_poly_factor_print(fac), flint_printf("\n\n");
abort();
}
for (j = 0; j < fac->num; j++)
{
for (k = j + 1; k < fac->num; k++)
{
if (fmpz_poly_equal(fac->p + j, fac->p + k))
{
flint_printf("FAIL (repeated factor):\n");
flint_printf("facs1 = %wd, facs2 = %wd\n", facs1, facs2);
flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n");
flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n");
flint_printf("fac = "), fmpz_poly_factor_print(fac), flint_printf("\n\n");
abort();
}
}
fmpz_poly_content(c, fac->p + j);
if (!fmpz_is_one(c) || fmpz_sgn((fac->p + j)->coeffs + fmpz_poly_degree(fac->p + j)) < 0)
{
flint_printf("FAIL (factor not reduced):\n");
flint_printf("facs1 = %wd, facs2 = %wd\n", facs1, facs2);
flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n");
flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n");
flint_printf("fac = "), fmpz_poly_factor_print(fac), flint_printf("\n\n");
abort();
}
}
fmpz_clear(c);
fmpz_poly_clear(f);
fmpz_poly_clear(g);
fmpz_poly_clear(h);
fmpz_poly_clear(t);
fmpz_poly_factor_clear(fac);
}
/* Regression test: #783 */
{
fmpz_poly_t a;
fmpz_poly_factor_t f;
fmpz_poly_init(a);
fmpz_poly_set_str(a, "31 294114975 822759704 601207031 3459410600 6329635407 5561735376 2870497527 -364079376 -984488613 -2855108728 -5168185293 -2678402184 -3199593893 -2740409376 -1003657917 -549998688 -252445155 -80724312 -19101979 -28418280 -2087859 -9732528 -2615547 -159120 -148311 -4680 -1359 2504 73 0 1");
fmpz_poly_factor_init(f);
fmpz_poly_factor(f, a);
fmpz_poly_factor_clear(f);
fmpz_poly_clear(a);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}