void _arb_poly_sin_cos_pi_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_cos_pi(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_mul(t, t, h + 1, prec); arb_sin_cos_pi(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_neg(t, t); arb_mul(c + 1, s, t, prec); arb_clear(t); } else if (hlen < TANGENT_CUTOFF) _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 1); else _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 1); }
void _arb_poly_tan_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_tan(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_t t; arb_init(t); arb_tan(g, h, prec); arb_mul(t, g, g, prec); arb_add_ui(t, t, 1, prec); arb_mul(g + 1, t, h + 1, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t, u; t = _arb_vec_init(2 * len); u = t + len; NEWTON_INIT(TAN_NEWTON_CUTOFF, len) NEWTON_BASECASE(n) _arb_poly_sin_cos_series_basecase(t, u, h, hlen, n, prec, 0); _arb_poly_div_series(g, t, n, u, n, n, prec); NEWTON_END_BASECASE NEWTON_LOOP(m, n) _arb_poly_mullow(u, g, m, g, m, n, prec); arb_add_ui(u, u, 1, prec); _arb_poly_atan_series(t, g, m, n, prec); _arb_poly_sub(t + m, h + m, FLINT_MAX(0, hlen - m), t + m, n - m, prec); _arb_poly_mullow(g + m, u, n, t + m, n - m, n - m, prec); NEWTON_END_LOOP NEWTON_END _arb_vec_clear(t, 2 * len); } }
void _arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_cos(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_set(t, h + 1); arb_sin_cos(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_neg(t, t); arb_mul(c + 1, s, t, prec); arb_clear(t); } else { slong cutoff; if (prec <= 128) { cutoff = 1400; } else { cutoff = 100000 / pow(log(prec), 3); cutoff = FLINT_MIN(cutoff, 700); } if (hlen < cutoff) _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 0); else _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 0); } }