#include "test_helpers.h"
#include "ulong_extras.h"
#include "nmod_poly.h"
TEST_FUNCTION_START(nmod_poly_berlekamp_massey, state)
{
slong i, j, k, l;
{
int changed;
nmod_berlekamp_massey_t B;
nmod_berlekamp_massey_init(B, 101);
nmod_berlekamp_massey_add_point(B, 1);
nmod_berlekamp_massey_add_point(B, 1);
nmod_berlekamp_massey_add_point(B, 2);
nmod_berlekamp_massey_add_point(B, 3);
changed = nmod_berlekamp_massey_reduce(B);
if ( changed != 1
|| 2 != nmod_poly_degree(nmod_berlekamp_massey_V_poly(B))
|| nmod_poly_degree(nmod_berlekamp_massey_R_poly(B)) > 1)
{
printf("FAIL\n");
flint_printf("check fibonacci 1\n");
fflush(stdout);
flint_abort();
}
nmod_berlekamp_massey_add_point(B, 5);
nmod_berlekamp_massey_add_point(B, 8);
changed = nmod_berlekamp_massey_reduce(B);
if ( changed != 0
|| 2 != nmod_poly_degree(nmod_berlekamp_massey_V_poly(B))
|| nmod_poly_degree(nmod_berlekamp_massey_R_poly(B)) > 1)
{
printf("FAIL\n");
flint_printf("check fibonacci 2\n");
fflush(stdout);
flint_abort();
}
nmod_berlekamp_massey_clear(B);
}
for (i = 0; i < 20 * flint_test_multiplier(); i++)
{
nmod_berlekamp_massey_t B1, B2;
nmod_berlekamp_massey_init(B1, 2);
nmod_berlekamp_massey_init(B2, 2);
for (j = 0; j < 10; j++)
{
ulong p;
p = n_randtest_prime(state, 1);
nmod_berlekamp_massey_set_prime(B1, p);
nmod_berlekamp_massey_set_prime(B2, p);
for (k = 0; k < 10; k++)
{
nmod_berlekamp_massey_add_point(B1, n_randint(state, p));
nmod_berlekamp_massey_add_zeros(B1, n_randint(state, 5));
nmod_berlekamp_massey_add_point(B1, n_randint(state, p));
if (n_randlimb(state) & 1)
{
nmod_berlekamp_massey_reduce(B1);
}
}
nmod_berlekamp_massey_add_points(B2, nmod_berlekamp_massey_points(B1),
nmod_berlekamp_massey_point_count(B1));
nmod_berlekamp_massey_reduce(B2);
nmod_berlekamp_massey_reduce(B1);
if (!nmod_poly_equal(nmod_berlekamp_massey_V_poly(B1),
nmod_berlekamp_massey_V_poly(B2)))
{
printf("FAIL\n");
flint_printf("check intermediate reductions match\n"
"i = %wd, j = %wd\n", i, j);
fflush(stdout);
flint_abort();
}
for (k = 0; k < 15; k++)
{
nmod_poly_t u, v, s, q, r;
nmod_poly_init(u, p);
nmod_poly_init(v, p);
nmod_poly_init(s, p);
nmod_poly_init(q, p);
nmod_poly_init(r, p);
nmod_poly_randtest(u, state, k);
nmod_poly_randtest_monic(v, state, k + 1);
nmod_poly_shift_left(s, u, 2*k);
nmod_poly_divrem(q, r, s, v);
nmod_berlekamp_massey_start_over(B1);
for (l = 2*k - 1; l >= 0 ; l--)
{
nmod_berlekamp_massey_add_point(B1, nmod_poly_get_coeff_ui(q, l));
}
nmod_berlekamp_massey_reduce(B1);
nmod_poly_divrem(q, r, v, nmod_berlekamp_massey_V_poly(B1));
if (!nmod_poly_is_zero(r))
{
flint_printf("check berlekamp_massey does its job\n"
"i = %wd, j = %wd, k = %wd\n", i, j, k);
printf("v: "); nmod_poly_print_pretty(v, "#"); printf("\n");
printf("B: "); nmod_berlekamp_massey_print(B1); printf("\n");
fflush(stdout);
flint_abort();
}
if ( nmod_poly_degree(nmod_berlekamp_massey_R_poly(B1))
>= nmod_poly_degree(nmod_berlekamp_massey_V_poly(B1)))
{
flint_printf("check discrepancy\n"
"i = %wd, j = %wd, k = %wd\n", i, j, k);
printf("v: "); nmod_poly_print_pretty(v, "#"); printf("\n");
printf("B: "); nmod_berlekamp_massey_print(B1); printf("\n");
fflush(stdout);
flint_abort();
}
nmod_poly_clear(u);
nmod_poly_clear(v);
nmod_poly_clear(s);
nmod_poly_clear(q);
nmod_poly_clear(r);
}
}
nmod_berlekamp_massey_clear(B1);
nmod_berlekamp_massey_clear(B2);
}
TEST_FUNCTION_END(state);
}