void fmprb_agm(fmprb_t z, const fmprb_t x, const fmprb_t y, long prec) { fmprb_t t, u, v, w; if (fmprb_contains_negative(x) || fmprb_contains_negative(y)) { fmprb_indeterminate(z); return; } if (fmprb_is_zero(x) || fmprb_is_zero(y)) { fmprb_zero(z); return; } fmprb_init(t); fmprb_init(u); fmprb_init(v); fmprb_init(w); fmprb_set(t, x); fmprb_set(u, y); while (!fmprb_overlaps(t, u) && !fmprb_contains_nonpositive(t) && !fmprb_contains_nonpositive(u)) { fmprb_add(v, t, u, prec); fmprb_mul_2exp_si(v, v, -1); fmprb_mul(w, t, u, prec); fmprb_sqrt(w, w, prec); fmprb_swap(v, t); fmprb_swap(w, u); } if (!fmprb_is_finite(t) || !fmprb_is_finite(u)) { fmprb_indeterminate(z); } else { fmprb_union(z, t, u, prec); } fmprb_clear(t); fmprb_clear(u); fmprb_clear(v); fmprb_clear(w); }
void fmprb_sqrtpos(fmprb_t z, const fmprb_t x, slong prec) { if (!fmprb_is_finite(x)) { if (fmpr_is_zero(fmprb_radref(x)) && fmpr_is_pos_inf(fmprb_midref(x))) fmprb_pos_inf(z); else fmprb_zero_pm_inf(z); } else if (fmprb_contains_nonpositive(x)) { fmpr_t t; fmpr_init(t); fmpr_add(t, fmprb_midref(x), fmprb_radref(x), FMPRB_RAD_PREC, FMPR_RND_CEIL); if (fmpr_sgn(t) <= 0) { fmprb_zero(z); } else { fmpr_sqrt(t, t, FMPRB_RAD_PREC, FMPR_RND_CEIL); fmpr_mul_2exp_si(t, t, -1); fmpr_set(fmprb_midref(z), t); fmpr_set(fmprb_radref(z), t); } fmpr_clear(t); } else { fmprb_sqrt(z, x, prec); } fmprb_nonnegative_part(z, z, prec); }
void _fmprb_poly_zeta_series(fmprb_ptr res, fmprb_srcptr h, long hlen, const fmprb_t a, int deflate, long len, long prec) { long i; fmpcb_t cs, ca; fmpcb_ptr z; fmprb_ptr t, u; if (fmprb_contains_nonpositive(a)) { _fmprb_vec_indeterminate(res, len); return; } hlen = FLINT_MIN(hlen, len); z = _fmpcb_vec_init(len); t = _fmprb_vec_init(len); u = _fmprb_vec_init(len); fmpcb_init(cs); fmpcb_init(ca); /* use reflection formula */ if (fmpr_sgn(fmprb_midref(h)) < 0 && fmprb_is_one(a)) { /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */ fmprb_t pi; fmprb_ptr f, s1, s2, s3, s4; fmprb_init(pi); f = _fmprb_vec_init(2); s1 = _fmprb_vec_init(len); s2 = _fmprb_vec_init(len); s3 = _fmprb_vec_init(len); s4 = _fmprb_vec_init(len); fmprb_const_pi(pi, prec); /* s1 = (2*pi)**s */ fmprb_mul_2exp_si(pi, pi, 1); _fmprb_poly_pow_cpx(s1, pi, h, len, prec); fmprb_mul_2exp_si(pi, pi, -1); /* s2 = sin(pi*s/2) / pi */ fmprb_mul_2exp_si(pi, pi, -1); fmprb_mul(f, pi, h, prec); fmprb_set(f + 1, pi); fmprb_mul_2exp_si(pi, pi, 1); _fmprb_poly_sin_series(s2, f, 2, len, prec); _fmprb_vec_scalar_div(s2, s2, len, pi, prec); /* s3 = gamma(1-s) */ fmprb_sub_ui(f, h, 1, prec); fmprb_neg(f, f); fmprb_set_si(f + 1, -1); _fmprb_poly_gamma_series(s3, f, 2, len, prec); /* s4 = zeta(1-s) */ fmprb_sub_ui(f, h, 1, prec); fmprb_neg(f, f); fmpcb_set_fmprb(cs, f); fmpcb_one(ca); zeta_series(z, cs, ca, 0, len, prec); for (i = 0; i < len; i++) fmprb_set(s4 + i, fmpcb_realref(z + i)); for (i = 1; i < len; i += 2) fmprb_neg(s4 + i, s4 + i); _fmprb_poly_mullow(u, s1, len, s2, len, len, prec); _fmprb_poly_mullow(s1, s3, len, s4, len, len, prec); _fmprb_poly_mullow(t, u, len, s1, len, len, prec); /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */ if (deflate) { fmprb_sub_ui(u, h, 1, prec); fmprb_neg(u, u); fmprb_ui_div(u, 1, u, prec); for (i = 1; i < len; i++) fmprb_mul(u + i, u + i - 1, u, prec); _fmprb_vec_add(t, t, u, len, prec); } fmprb_clear(pi); _fmprb_vec_clear(f, 2); _fmprb_vec_clear(s1, len); _fmprb_vec_clear(s2, len); _fmprb_vec_clear(s3, len); _fmprb_vec_clear(s4, len); } else { fmpcb_set_fmprb(cs, h); fmpcb_set_fmprb(ca, a); zeta_series(z, cs, ca, deflate, len, prec); for (i = 0; i < len; i++) fmprb_set(t + i, fmpcb_realref(z + i)); } /* compose with nonconstant part */ fmprb_zero(u); _fmprb_vec_set(u + 1, h + 1, hlen - 1); _fmprb_poly_compose_series(res, t, len, u, hlen, len, prec); _fmpcb_vec_clear(z, len); _fmprb_vec_clear(t, len); _fmprb_vec_clear(u, len); fmpcb_init(cs); fmpcb_init(ca); }