void arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { if (n == 0) { arb_poly_zero(Qinv); return; } if (Q->length == 0) { arb_poly_fit_length(Qinv, n); _arb_vec_indeterminate(Qinv->coeffs, n); _arb_poly_set_length(Qinv, n); return; } if (Qinv == Q) { arb_poly_t t; arb_poly_init(t); arb_poly_inv_series(t, Q, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); return; } arb_poly_fit_length(Qinv, n); _arb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec); _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); }
/* F = 1 + U + U^2 + ... = 1/(1-U) assuming that U[0] is positive; indeterminate if not convergent */ static void arb_poly_geometric_sum(arb_poly_t F, const arb_poly_t U, long len, long prec) { if (U->length == 0) { arb_poly_one(F); return; } arb_poly_add_si(F, U, -1, prec); arb_poly_neg(F, F); if (F->length > 0 && arb_is_positive(F->coeffs)) { arb_poly_inv_series(F, F, len, prec); } else { arb_poly_fit_length(F, len); _arb_vec_indeterminate(F->coeffs, len); _arb_poly_set_length(F, len); } }
int main() { slong iter; flint_rand_t state; flint_printf("digamma_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; arb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 300); rbits2 = 2 + n_randint(state, 300); rbits3 = 2 + n_randint(state, 300); m = n_randint(state, 25); n1 = n_randint(state, 25); n2 = n_randint(state, 25); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); arb_poly_randtest(a, state, m, rbits1, 10); arb_poly_digamma_series(b, a, n1, rbits2); arb_poly_digamma_series(c, a, n2, rbits3); arb_poly_set(d, b); arb_poly_truncate(d, FLINT_MIN(n1, n2)); arb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); arb_poly_printd(a, 50); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 50); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 50); flint_printf("\n\n"); abort(); } /* check psi(a) + 1/a = psi(a+1) */ arb_poly_inv_series(c, a, n1, rbits2); arb_poly_add(c, b, c, rbits2); arb_poly_add_si(d, a, 1, rbits2); arb_poly_digamma_series(d, d, n1, rbits2); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); arb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); arb_poly_printd(d, 15); flint_printf("\n\n"); abort(); } arb_poly_digamma_series(a, a, n1, rbits2); if (!arb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); abort(); } arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(c); arb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("inv_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A, B; arb_poly_t a, b; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); arb_poly_init(a); arb_poly_init(b); do { fmpq_poly_randtest_not_zero(A, state, m, qbits); } while (A->coeffs[0] == 0); arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); fmpq_poly_inv_series(B, A, n); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_inv_series(b, a, n, rbits2); if (!arb_poly_contains_fmpq_poly(b, B)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); flint_printf("\n\n"); flint_printf("B = "); fmpq_poly_print(B); flint_printf("\n\n"); flint_printf("a = "); arb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); arb_poly_printd(b, 15); flint_printf("\n\n"); abort(); } arb_poly_inv_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); arb_poly_clear(a); arb_poly_clear(b); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }