int main() { flint_rand_t state; slong nmax, n, bound, count; mp_limb_t p, pinv, m1, m2; nmod_poly_t A; flint_printf("rev...."); fflush(stdout); flint_randinit(state); bound = 100000; p = n_nextprime(UWORD(1) << (FLINT_BITS - 1), 0); pinv = n_preinvert_limb(p); nmod_poly_init(A, p); nmod_poly_set_coeff_ui(A, 1, 1); nmod_poly_exp_series(A, A, bound); nmod_poly_shift_right(A, A, 1); nmod_poly_inv_series(A, A, bound); m1 = 1; for (n = 0; n < A->length; n++) { A->coeffs[n] = n_mulmod2_preinv(A->coeffs[n], m1, p, pinv); m1 = n_mulmod2_preinv(m1, n + 1, p, pinv); } for (nmax = 0; nmax < bound; nmax = 1.5 * nmax + 2) { fmpz_t numer, denom; bernoulli_rev_t iter; fmpz_init(numer); fmpz_init(denom); nmax += (nmax % 2); bernoulli_rev_init(iter, nmax); if (nmax < 8000) count = 4000; else count = 100; /* flint_printf("nmax = %wd, count = %wd\n", nmax, count); */ for (n = nmax; n >= 0 && count > 0; n -= 2, count--) { bernoulli_rev_next(numer, denom, iter); m1 = fmpz_fdiv_ui(numer, p); m2 = fmpz_fdiv_ui(denom, p); m2 = n_invmod(m2, p); m1 = n_mulmod2_preinv(m1, m2, p, pinv); m2 = nmod_poly_get_coeff_ui(A, n); if (m1 != m2) { flint_printf("FAIL:\n"); flint_printf("nmax = %wd, n = %wd\n", nmax, n); flint_printf("m1 = %wu mod %wu\n", m1, p); flint_printf("m2 = %wu mod %wu\n", m2, p); abort(); } } bernoulli_rev_clear(iter); fmpz_clear(numer); fmpz_clear(denom); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main(void) { int i, result; flint_rand_t state; flint_randinit(state); printf("invsqrt_series...."); fflush(stdout); /* Check 1/g^2 = h mod x^m */ for (i = 0; i < 1000; i++) { nmod_poly_t h, g, r; long m; mp_limb_t n; do n = n_randtest_prime(state, 0); while (n == 2UL); nmod_poly_init(h, n); nmod_poly_init(g, n); nmod_poly_init(r, n); do nmod_poly_randtest(h, state, n_randint(state, 1000)); while (h->length == 0); nmod_poly_set_coeff_ui(h, 0, 1UL); m = n_randint(state, h->length) + 1; nmod_poly_invsqrt_series(g, h, m); nmod_poly_mullow(r, g, g, m); nmod_poly_inv_series(r, r, m); nmod_poly_truncate(h, m); result = (nmod_poly_equal(r, h)); if (!result) { printf("FAIL:\n"); nmod_poly_print(h), printf("\n\n"); nmod_poly_print(g), printf("\n\n"); nmod_poly_print(r), printf("\n\n"); printf("n = %ld\n", n); abort(); } nmod_poly_clear(h); nmod_poly_clear(g); nmod_poly_clear(r); } /* Check aliasing of h and g */ for (i = 0; i < 1000; i++) { nmod_poly_t g, h; long m; mp_limb_t n; do n = n_randtest_prime(state, 0); while (n == 2UL); nmod_poly_init(h, n); nmod_poly_init(g, n); do nmod_poly_randtest(h, state, n_randint(state, 500)); while (h->length == 0); nmod_poly_set_coeff_ui(h, 0, 1UL); m = n_randint(state, h->length) + 1; nmod_poly_invsqrt_series(g, h, m); nmod_poly_invsqrt_series(h, h, m); result = (nmod_poly_equal(g, h)); if (!result) { printf("FAIL:\n"); nmod_poly_print(h), printf("\n\n"); nmod_poly_print(g), printf("\n\n"); printf("n = %ld, m = %ld\n", n, m); abort(); } nmod_poly_clear(g); nmod_poly_clear(h); } flint_randclear(state); printf("PASS\n"); return 0; }