/* Copyright (C) 2019 Daniel Schultz 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 "nmod_poly.h" int main(void) { slong i, j, k, l; FLINT_TEST_INIT(state); flint_printf("berlekamp_massey...."); fflush(stdout); { 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"); 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"); 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++) { mp_limb_t p; p = n_randtest_prime(state, 1); nmod_berlekamp_massey_set_prime(B1, p); nmod_berlekamp_massey_set_prime(B2, p); /* check intermediate reductions match */ 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); flint_abort(); } /* Check berlekamp-massey does its job - 2k coeffcients of u a1 a2 a(2k) --- = --- + --- + ... + ------ + ... v x x^2 x^(2k) should be sufficient to reconstruct a divisor of v */ 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); /* deg(u) < deg(v), deg(v) = k */ nmod_poly_randtest(u, state, k); nmod_poly_randtest_monic(v, state, k + 1); /* q has enough coefficients of expansion of u/v at infty */ 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"); 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"); 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); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }