int elliptic(acb_ptr out, const acb_t inp, void * params, long order, long prec) { acb_ptr t; t = _acb_vec_init(order); acb_set(t, inp); if (order > 1) acb_one(t + 1); _acb_poly_sin_series(t, t, FLINT_MIN(2, order), order, prec); _acb_poly_mullow(out, t, order, t, order, order, prec); _acb_vec_scalar_mul_2exp_si(t, out, order, -1); acb_sub_ui(t, t, 1, prec); _acb_vec_neg(t, t, order); _acb_poly_rsqrt_series(out, t, order, order, prec); _acb_vec_clear(t, order); return 0; }
void _acb_poly_sqrt_series(acb_ptr g, acb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && acb_is_zero(h + hlen - 1)) hlen--; if (hlen <= 1) { acb_sqrt(g, h, prec); _acb_vec_zero(g + 1, len - 1); } else if (len == 2) { acb_sqrt(g, h, prec); acb_div(g + 1, h + 1, h, prec); acb_mul(g + 1, g + 1, g, prec); acb_mul_2exp_si(g + 1, g + 1, -1); } else if (_acb_vec_is_zero(h + 1, hlen - 2)) { acb_t t; acb_init(t); arf_set_si_2exp_si(arb_midref(acb_realref(t)), 1, -1); _acb_poly_binomial_pow_acb_series(g, h, hlen, t, len, prec); acb_clear(t); } else { acb_ptr t; t = _acb_vec_init(len); _acb_poly_rsqrt_series(t, h, hlen, len, prec); _acb_poly_mullow(g, t, len, h, hlen, len, prec); _acb_vec_clear(t, len); } }