void arb_poly_exp_series(arb_poly_t f, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(f); return; } if (hlen == 0) { arb_poly_one(f); return; } if (hlen == 1) n = 1; arb_poly_fit_length(f, n); _arb_poly_exp_series(f->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(f, n); _arb_poly_normalise(f); }
void arb_poly_sinh_cosh_series_exponential(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sinh_cosh_series_exponential(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); }
void arb_poly_rising_ui_series(arb_poly_t res, const arb_poly_t f, ulong r, slong trunc, slong prec) { slong len; if ((f->length == 0 && r != 0) || trunc == 0) { arb_poly_zero(res); return; } if (r == 0) { arb_poly_one(res); return; } len = poly_pow_length(f->length, r, trunc); if (f == res) { arb_poly_t tmp; arb_poly_init(tmp); arb_poly_rising_ui_series(tmp, f, r, len, prec); arb_poly_swap(tmp, res); arb_poly_clear(tmp); } else { arb_poly_fit_length(res, len); _arb_poly_rising_ui_series(res->coeffs, f->coeffs, f->length, r, len, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } }
void arb_poly_sin_cos_series_tangent(arb_poly_t s, arb_poly_t c, const arb_poly_t h, slong n, slong prec, int times_pi) { slong hlen = h->length; if (n == 0) { arb_poly_zero(s); arb_poly_zero(c); return; } if (hlen == 0) { arb_poly_zero(s); arb_poly_one(c); return; } arb_poly_fit_length(s, n); arb_poly_fit_length(c, n); _arb_poly_sin_cos_series_tangent(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec, times_pi); _arb_poly_set_length(s, n); _arb_poly_normalise(s); _arb_poly_set_length(c, n); _arb_poly_normalise(c); }
void arb_poly_cosh_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { slong hlen = h->length; if (n == 0) { arb_poly_zero(g); return; } if (hlen == 0) { arb_poly_one(g); return; } if (hlen == 1) n = 1; arb_poly_fit_length(g, n); _arb_poly_cosh_series(g->coeffs, h->coeffs, hlen, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); }
static void bsplit(arb_poly_t pol, const arb_t sqrtD, const slong * qbf, slong a, slong b, slong prec) { if (b - a == 0) { arb_poly_one(pol); } else if (b - a == 1) { acb_t z; acb_init(z); /* j((-b+sqrt(-D))/(2a)) */ arb_set_si(acb_realref(z), -FLINT_ABS(qbf[3 * a + 1])); arb_set(acb_imagref(z), sqrtD); acb_div_si(z, z, 2 * qbf[3 * a], prec); acb_modular_j(z, z, prec); if (qbf[3 * a + 1] < 0) { /* (x^2 - 2re(j) x + |j|^2) */ arb_poly_fit_length(pol, 3); arb_mul(pol->coeffs, acb_realref(z), acb_realref(z), prec); arb_addmul(pol->coeffs, acb_imagref(z), acb_imagref(z), prec); arb_mul_2exp_si(pol->coeffs + 1, acb_realref(z), 1); arb_neg(pol->coeffs + 1, pol->coeffs + 1); arb_one(pol->coeffs + 2); _arb_poly_set_length(pol, 3); } else { /* (x-j) */ arb_poly_fit_length(pol, 2); arb_neg(pol->coeffs, acb_realref(z)); arb_one(pol->coeffs + 1); _arb_poly_set_length(pol, 2); } acb_clear(z); } else { arb_poly_t tmp; arb_poly_init(tmp); bsplit(pol, sqrtD, qbf, a, a + (b - a) / 2, prec); bsplit(tmp, sqrtD, qbf, a + (b - a) / 2, b, prec); arb_poly_mul(pol, pol, tmp, prec); arb_poly_clear(tmp); } }
void arb_poly_pow_ui_trunc_binexp(arb_poly_t res, const arb_poly_t poly, ulong exp, slong len, slong prec) { slong flen, rlen; flen = poly->length; if (exp == 0 && len != 0) { arb_poly_one(res); } else if (flen == 0 || len == 0) { arb_poly_zero(res); } else { rlen = poly_pow_length(flen, exp, len); if (res != poly) { arb_poly_fit_length(res, rlen); _arb_poly_pow_ui_trunc_binexp(res->coeffs, poly->coeffs, flen, exp, rlen, prec); _arb_poly_set_length(res, rlen); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, rlen); _arb_poly_pow_ui_trunc_binexp(t->coeffs, poly->coeffs, flen, exp, rlen, prec); _arb_poly_set_length(t, rlen); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } }
/* 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("atan_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { slong m, n, qbits, rbits1, rbits2; fmpq_poly_t A; arb_poly_t a, b, c, d; qbits = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n = 1 + n_randint(state, 30); fmpq_poly_init(A); arb_poly_init(a); arb_poly_init(b); arb_poly_init(c); arb_poly_init(d); fmpq_poly_randtest(A, state, m, qbits); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); arb_poly_atan_series(b, a, n, rbits2); /* Check 2 atan(x) = atan(2x/(1-x^2)) + C */ arb_poly_mullow(c, a, a, n, rbits2); arb_poly_one(d); arb_poly_sub(c, d, c, rbits2); arb_poly_add(d, a, a, rbits2); if (arb_poly_length(c) != 0) { arb_poly_div_series(c, d, c, n, rbits2); arb_poly_atan_series(c, c, n, rbits2); arb_poly_add(d, b, b, rbits2); /* TODO: also check the first coefficient */ arb_poly_set_coeff_si(c, 0, 0); arb_poly_set_coeff_si(d, 0, 0); if (!arb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("bits2 = %wd\n", rbits2); flint_printf("A = "); fmpq_poly_print(A); 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"); 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_atan_series(a, a, n, rbits2); if (!arb_poly_equal(a, b)) { flint_printf("FAIL (aliasing)\n\n"); abort(); } fmpq_poly_clear(A); 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; }