#include "test_helpers.h"
#include "nmod_mpoly.h"
TEST_FUNCTION_START(nmod_poly_multi_crt, state)
{
slong i, j, k;
{
nmod_poly_multi_crt_t P;
nmod_poly_struct ** moduli, ** inputs, * outputs;
ulong modulus = 1009;
slong moduli_count = 1000;
moduli = (nmod_poly_struct **) flint_malloc(moduli_count*sizeof(nmod_poly_struct *));
inputs = (nmod_poly_struct **) flint_malloc(moduli_count*sizeof(nmod_poly_struct *));
outputs = (nmod_poly_struct *) flint_malloc(moduli_count*sizeof(nmod_poly_struct));
for (k = 0; k < moduli_count; k++)
{
moduli[k] = (nmod_poly_struct *) flint_malloc(sizeof(nmod_poly_struct));
inputs[k] = (nmod_poly_struct *) flint_malloc(sizeof(nmod_poly_struct));
nmod_poly_init(moduli[k], modulus);
nmod_poly_init(inputs[k], modulus);
nmod_poly_init(outputs + k, modulus);
nmod_poly_set_coeff_ui(moduli[k], 1, 1);
nmod_poly_set_coeff_ui(moduli[k], 0, modulus - k);
nmod_poly_set_coeff_ui(inputs[k], 0, (k*k)^k);
}
nmod_poly_multi_crt_init(P);
if (!nmod_poly_multi_crt_precompute_p(P,
(const nmod_poly_struct * const *) moduli, moduli_count))
{
printf("FAIL\n");
flint_printf("Check simple example\n");
fflush(stdout);
flint_abort();
}
FLINT_ASSERT(_nmod_poly_multi_crt_local_size(P) <= moduli_count);
for (k = 0; k < 1; k++)
{
_nmod_poly_multi_crt_run_p(outputs, P,
(const nmod_poly_struct * const *) inputs);
}
for (k = 0; k < moduli_count; k++)
{
nmod_poly_clear(moduli[k]);
nmod_poly_clear(inputs[k]);
nmod_poly_clear(outputs + k);
flint_free(moduli[k]);
flint_free(inputs[k]);
}
flint_free(moduli);
flint_free(inputs);
flint_free(outputs);
nmod_poly_multi_crt_clear(P);
}
for (i = 0; i < 20 * flint_test_multiplier(); i++)
{
nmod_poly_multi_crt_t P;
nmod_poly_t t, p;
slong total_degree, moduli_length, moduli_count;
nmod_poly_struct ** moduli, ** inputs;
nmod_poly_t output;
ulong modulus;
modulus = n_randint(state, FLINT_BITS - 1) + 1;
modulus = n_randbits(state, modulus);
modulus = n_nextprime(modulus, 1);
nmod_poly_init(t, modulus);
nmod_poly_init(p, modulus);
nmod_poly_init(output, modulus);
nmod_poly_multi_crt_init(P);
for (j = 0; j < 4; j++)
{
moduli_length = n_randint(state, 20) + 1;
moduli_count = n_randint(state, 50) + 1;
moduli = (nmod_poly_struct **) flint_malloc(moduli_count
*sizeof(nmod_poly_struct *));
inputs = (nmod_poly_struct **) flint_malloc(moduli_count
*sizeof(nmod_poly_struct *));
for (k = 0; k < moduli_count; k++)
{
moduli[k] = (nmod_poly_struct *) flint_malloc(
sizeof(nmod_poly_struct));
inputs[k] = (nmod_poly_struct *) flint_malloc(
sizeof(nmod_poly_struct));
nmod_poly_init(moduli[k], modulus);
nmod_poly_init(inputs[k], modulus);
nmod_poly_randtest(moduli[k], state, moduli_length);
nmod_poly_randtest(inputs[k], state, moduli_length);
}
if (nmod_poly_multi_crt_precompute_p(P,
(const nmod_poly_struct * const *) moduli, moduli_count))
{
nmod_poly_multi_crt_precomp_p(output, P,
(const nmod_poly_struct * const *) inputs);
total_degree = 0;
for (k = 0; k < moduli_count; k++)
{
total_degree += nmod_poly_degree(moduli[k]);
nmod_poly_sub(t, output, inputs[k]);
nmod_poly_rem(t, t, moduli[k]);
if (!nmod_poly_is_zero(t))
{
printf("FAIL\n");
flint_printf("Check remainder "
"i = %wd, j = %wd, k = %wd\n", i, j, k);
fflush(stdout);
flint_abort();
}
}
if (nmod_poly_degree(output) >= total_degree)
{
printf("FAIL\n");
flint_printf("Check output degree "
"i = %wd, j = %wd, k = %wd\n", i, j, k);
fflush(stdout);
flint_abort();
}
}
else
{
int ok = 0;
nmod_poly_one(p);
for (k = 0; !ok && k < moduli_count; k++)
{
nmod_poly_mul(p, p, moduli[k]);
if (nmod_poly_degree(moduli[k]) < 1)
{
ok = 1;
}
}
for (k = 0; !ok && k < moduli_count; k++)
{
nmod_poly_div(t, p, moduli[k]);
nmod_poly_gcd(t, t, moduli[k]);
if (nmod_poly_degree(t) > 0)
{
ok = 1;
}
}
if (!ok)
{
printf("FAIL\n");
flint_printf("Check crt failure i = %wd, j = %wd\n", i, j);
fflush(stdout);
flint_abort();
}
}
for (k = 0; k < moduli_count; k++)
{
nmod_poly_clear(moduli[k]);
nmod_poly_clear(inputs[k]);
flint_free(moduli[k]);
flint_free(inputs[k]);
}
flint_free(moduli);
flint_free(inputs);
}
nmod_poly_clear(t);
nmod_poly_clear(p);
nmod_poly_clear(output);
nmod_poly_multi_crt_clear(P);
}
for (i = 0; i < 20 * flint_test_multiplier(); i++)
{
nmod_poly_multi_crt_t P;
nmod_poly_t t, p;
slong total_degree, moduli_length, moduli_count;
nmod_poly_struct * moduli, * inputs;
nmod_poly_t output;
ulong modulus;
modulus = n_randint(state, FLINT_BITS - 1) + 1;
modulus = n_randbits(state, modulus);
modulus = n_nextprime(modulus, 1);
nmod_poly_init(t, modulus);
nmod_poly_init(p, modulus);
nmod_poly_init(output, modulus);
nmod_poly_multi_crt_init(P);
for (j = 0; j < 4; j++)
{
moduli_length = n_randint(state, 20) + 1;
moduli_count = n_randint(state, 50) + 1;
moduli = (nmod_poly_struct *) flint_malloc(moduli_count
*sizeof(nmod_poly_struct));
inputs = (nmod_poly_struct *) flint_malloc(moduli_count
*sizeof(nmod_poly_struct));
for (k = 0; k < moduli_count; k++)
{
nmod_poly_init(moduli + k, modulus);
nmod_poly_init(inputs + k, modulus);
nmod_poly_randtest(moduli + k, state, moduli_length);
nmod_poly_randtest(inputs + k, state, moduli_length);
}
if (nmod_poly_multi_crt_precompute(P, moduli, moduli_count))
{
nmod_poly_multi_crt_precomp(output, P, inputs);
total_degree = 0;
for (k = 0; k < moduli_count; k++)
{
total_degree += nmod_poly_degree(moduli + k);
nmod_poly_sub(t, output, inputs + k);
nmod_poly_rem(t, t, moduli + k);
if (!nmod_poly_is_zero(t))
{
printf("FAIL\n");
flint_printf("Check remainder flat "
"i = %wd, j = %wd, k = %wd\n", i, j, k);
fflush(stdout);
flint_abort();
}
}
if (nmod_poly_degree(output) >= total_degree)
{
printf("FAIL\n");
flint_printf("Check output degree flat "
"i = %wd, j = %wd, k = %wd\n", i, j, k);
fflush(stdout);
flint_abort();
}
}
else
{
int ok = 0;
nmod_poly_one(p);
for (k = 0; !ok && k < moduli_count; k++)
{
nmod_poly_mul(p, p, moduli + k);
if (nmod_poly_degree(moduli + k) < 1)
{
ok = 1;
}
}
for (k = 0; !ok && k < moduli_count; k++)
{
nmod_poly_div(t, p, moduli + k);
nmod_poly_gcd(t, t, moduli + k);
if (nmod_poly_degree(t) > 0)
{
ok = 1;
}
}
if (!ok)
{
printf("FAIL\n");
flint_printf("Check flat crt failure i = %wd, j = %wd\n", i, j);
fflush(stdout);
flint_abort();
}
}
for (k = 0; k < moduli_count; k++)
{
nmod_poly_clear(moduli + k);
nmod_poly_clear(inputs + k);
}
flint_free(moduli);
flint_free(inputs);
}
nmod_poly_clear(t);
nmod_poly_clear(p);
nmod_poly_clear(output);
nmod_poly_multi_crt_clear(P);
}
for (i = 0; i < 20 * flint_test_multiplier(); i++)
{
nmod_poly_t t, p;
slong total_degree, moduli_length, moduli_count;
nmod_poly_struct * moduli, * inputs;
nmod_poly_t output;
ulong modulus;
modulus = n_randint(state, FLINT_BITS - 1) + 1;
modulus = n_randbits(state, modulus);
modulus = n_nextprime(modulus, 1);
nmod_poly_init(t, modulus);
nmod_poly_init(p, modulus);
nmod_poly_init(output, modulus);
for (j = 0; j < 4; j++)
{
moduli_length = n_randint(state, 20) + 1;
moduli_count = n_randint(state, 50) + 1;
moduli = (nmod_poly_struct *) flint_malloc(moduli_count
*sizeof(nmod_poly_struct));
inputs = (nmod_poly_struct *) flint_malloc(moduli_count
*sizeof(nmod_poly_struct));
for (k = 0; k < moduli_count; k++)
{
nmod_poly_init(moduli + k, modulus);
nmod_poly_init(inputs + k, modulus);
nmod_poly_randtest(moduli + k, state, moduli_length);
nmod_poly_randtest(inputs + k, state, moduli_length);
}
if (nmod_poly_multi_crt(output, moduli, inputs, moduli_count))
{
total_degree = 0;
for (k = 0; k < moduli_count; k++)
{
total_degree += nmod_poly_degree(moduli + k);
nmod_poly_sub(t, output, inputs + k);
nmod_poly_rem(t, t, moduli + k);
if (!nmod_poly_is_zero(t))
{
printf("FAIL\n");
flint_printf("Check remainder lazy "
"i = %wd, j = %wd, k = %wd\n", i, j, k);
fflush(stdout);
flint_abort();
}
}
if (nmod_poly_degree(output) >= total_degree)
{
printf("FAIL\n");
flint_printf("Check output degree lazy "
"i = %wd, j = %wd, k = %wd\n", i, j, k);
fflush(stdout);
flint_abort();
}
}
else
{
int ok = 0;
nmod_poly_one(p);
for (k = 0; !ok && k < moduli_count; k++)
{
nmod_poly_mul(p, p, moduli + k);
if (nmod_poly_degree(moduli + k) < 1)
{
ok = 1;
}
}
for (k = 0; !ok && k < moduli_count; k++)
{
nmod_poly_div(t, p, moduli + k);
nmod_poly_gcd(t, t, moduli + k);
if (nmod_poly_degree(t) > 0)
{
ok = 1;
}
}
if (!ok)
{
printf("FAIL\n");
flint_printf("Check lazy crt failure i = %wd, j = %wd\n", i, j);
fflush(stdout);
flint_abort();
}
}
for (k = 0; k < moduli_count; k++)
{
nmod_poly_clear(moduli + k);
nmod_poly_clear(inputs + k);
}
flint_free(moduli);
flint_free(inputs);
}
nmod_poly_clear(t);
nmod_poly_clear(p);
nmod_poly_clear(output);
}
TEST_FUNCTION_END(state);
}