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_poly_shift_left(fmprb_ptr res, fmprb_srcptr poly, long len, long n) { long i; /* Copy in reverse to avoid writing over unshifted coefficients */ if (res != poly) { for (i = len; i--; ) fmprb_set(res + n + i, poly + i); } else { for (i = len; i--; ) fmprb_swap(res + n + i, res + i); } for (i = 0; i < n; i++) fmprb_zero(res + i); }
void fmprb_hypgeom_sum(fmprb_t P, fmprb_t Q, const hypgeom_t hyp, long n, long prec) { if (n < 1) { fmprb_zero(P); fmprb_one(Q); } else { fmprb_t B, T; fmprb_init(B); fmprb_init(T); bsplit_recursive_fmprb(P, Q, B, T, hyp, 0, n, 0, prec); if (!fmprb_is_one(B)) fmprb_mul(Q, Q, B, prec); fmprb_swap(P, T); fmprb_clear(B); fmprb_clear(T); } }
void _fmprb_poly_evaluate_horner(fmprb_t y, fmprb_srcptr f, long len, const fmprb_t x, long prec) { if (len == 0) { fmprb_zero(y); } else if (len == 1 || fmprb_is_zero(x)) { fmprb_set_round(y, f, prec); } else if (len == 2) { fmprb_mul(y, x, f + 1, prec); fmprb_add(y, y, f + 0, prec); } else { long i = len - 1; fmprb_t t, u; fmprb_init(t); fmprb_init(u); fmprb_set(u, f + i); for (i = len - 2; i >= 0; i--) { fmprb_mul(t, u, x, prec); fmprb_add(u, f + i, t, prec); } fmprb_swap(y, u); fmprb_clear(t); fmprb_clear(u); } }
void fmpcb_calc_cauchy_bound(fmprb_t bound, fmpcb_calc_func_t func, void * param, const fmpcb_t x, const fmprb_t radius, long maxdepth, long prec) { long i, n, depth, wp; fmprb_t pi, theta, v, s1, c1, s2, c2, st, ct; fmpcb_t t, u; fmprb_t b; fmprb_init(pi); fmprb_init(theta); fmprb_init(v); fmprb_init(s1); fmprb_init(c1); fmprb_init(s2); fmprb_init(c2); fmprb_init(st); fmprb_init(ct); fmpcb_init(t); fmpcb_init(u); fmprb_init(b); wp = prec + 20; fmprb_const_pi(pi, wp); fmprb_zero_pm_inf(b); for (depth = 0, n = 16; depth < maxdepth; n *= 2, depth++) { fmprb_zero(b); /* theta = 2 pi / n */ fmprb_div_ui(theta, pi, n, wp); fmprb_mul_2exp_si(theta, theta, 1); /* sine and cosine of i*theta and (i+1)*theta */ fmprb_zero(s1); fmprb_one(c1); fmprb_sin_cos(st, ct, theta, wp); fmprb_set(s2, st); fmprb_set(c2, ct); for (i = 0; i < n; i++) { /* sine and cosine of 2 pi ([i,i+1]/n) */ /* since we use power of two subdivision points, the sine and cosine are monotone on each subinterval */ fmprb_union(fmpcb_realref(t), c1, c2, wp); fmprb_union(fmpcb_imagref(t), s1, s2, wp); fmpcb_mul_fmprb(t, t, radius, wp); fmpcb_add(t, t, x, prec); /* next angle */ fmprb_mul(v, c2, ct, wp); fmprb_mul(c1, s2, st, wp); fmprb_sub(c1, v, c1, wp); fmprb_mul(v, c2, st, wp); fmprb_mul(s1, s2, ct, wp); fmprb_add(s1, v, s1, wp); fmprb_swap(c1, c2); fmprb_swap(s1, s2); func(u, t, param, 1, prec); fmpcb_abs(v, u, prec); fmprb_add(b, b, v, prec); } fmprb_div_ui(b, b, n, prec); if (fmprb_is_exact(b) || fmpr_cmp(fmprb_radref(b), fmprb_midref(b)) < 0) break; } fmprb_set(bound, b); fmprb_clear(pi); fmprb_clear(theta); fmprb_clear(v); fmpcb_clear(t); fmpcb_clear(u); fmprb_clear(b); fmprb_clear(s1); fmprb_clear(c1); fmprb_clear(s2); fmprb_clear(c2); fmprb_clear(st); fmprb_clear(ct); }