void _acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, long d, long prec) { ulong M, N; long i; arf_t bound; arb_ptr vb; if (d < 1) return; if (!acb_is_finite(s) || !acb_is_finite(a)) { _acb_vec_indeterminate(z, d); return; } arf_init(bound); vb = _arb_vec_init(d); _acb_poly_zeta_em_choose_param(bound, &N, &M, s, a, FLINT_MIN(d, 2), prec, MAG_BITS); _acb_poly_zeta_em_bound(vb, s, a, N, M, d, MAG_BITS); _acb_poly_zeta_em_sum(z, s, a, deflate, N, M, d, prec); for (i = 0; i < d; i++) { arb_get_abs_ubound_arf(bound, vb + i, MAG_BITS); arb_add_error_arf(acb_realref(z + i), bound); arb_add_error_arf(acb_imagref(z + i), bound); } arf_clear(bound); _arb_vec_clear(vb, d); }
void partitions_fmpz_fmpz_hrr(fmpz_t p, const fmpz_t n, int use_doubles) { arb_t x; arf_t bound; slong N; arb_init(x); arf_init(bound); N = partitions_hrr_needed_terms(fmpz_get_d(n)); if (fmpz_cmp_ui(n, 4e8) >= 0 && flint_get_num_threads() > 1) { hrr_sum_threaded(x, n, N, use_doubles); } else { partitions_hrr_sum_arb(x, n, 1, N, use_doubles); } partitions_rademacher_bound(bound, n, N); arb_add_error_arf(x, bound); if (!arb_get_unique_fmpz(p, x)) { flint_printf("not unique!\n"); arb_printd(x, 50); flint_printf("\n"); abort(); } arb_clear(x); arf_clear(bound); }
int _arb_poly_newton_step(arb_t xnew, arb_srcptr poly, long len, const arb_t x, const arb_t convergence_interval, const arf_t convergence_factor, long prec) { arf_t err; arb_t t, u, v; int result; arf_init(err); arb_init(t); arb_init(u); arb_init(v); arf_set_mag(err, arb_radref(x)); arf_mul(err, err, err, MAG_BITS, ARF_RND_UP); arf_mul(err, err, convergence_factor, MAG_BITS, ARF_RND_UP); arf_set(arb_midref(t), arb_midref(x)); mag_zero(arb_radref(t)); _arb_poly_evaluate2(u, v, poly, len, t, prec); arb_div(u, u, v, prec); arb_sub(u, t, u, prec); arb_add_error_arf(u, err); if (arb_contains(convergence_interval, u) && (mag_cmp(arb_radref(u), arb_radref(x)) < 0)) { arb_swap(xnew, u); result = 1; } else { arb_set(xnew, x); result = 0; } arb_clear(t); arb_clear(u); arb_clear(v); arf_clear(err); return result; }
int main() { long iter; flint_rand_t state; printf("add_error...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; arf_t m, r; arb_init(a); arb_init(b); arb_init(c); arf_init(m); arf_init(r); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 10); arf_randtest_special(m, state, 1 + n_randint(state, 2000), 10); arf_randtest_special(r, state, 1 + n_randint(state, 2000), 10); /* c = a plus error bounds */ arb_set(c, a); arf_set(arb_midref(b), m); arf_get_mag(arb_radref(b), r); arb_add_error(c, b); /* b = a + random point */ arb_set(b, a); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), r, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), r, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { printf("FAIL (arb_add_error)\n\n"); printf("a = "); arb_printn(a, 50, 0); printf("\n\n"); printf("b = "); arb_printn(b, 50, 0); printf("\n\n"); printf("c = "); arb_printn(c, 50, 0); printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(m); arf_clear(r); } for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; arf_t m; arb_init(a); arb_init(b); arb_init(c); arf_init(m); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(c, state, 1 + n_randint(state, 2000), 10); arf_randtest_special(m, state, 1 + n_randint(state, 2000), 10); /* c = a plus error bounds */ arb_set(c, a); arb_add_error_arf(c, m); /* b = a + random point */ arb_set(b, a); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { printf("FAIL (arb_add_error_arf)\n\n"); printf("a = "); arb_printn(a, 50, 0); printf("\n\n"); printf("b = "); arb_printn(b, 50, 0); printf("\n\n"); printf("c = "); arb_printn(c, 50, 0); printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(m); } for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; arf_t t; mag_t r; arb_init(a); arb_init(b); arb_init(c); mag_init(r); arf_init(t); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); mag_randtest(r, state, 10); /* c = a plus error bounds */ arb_set(c, a); arb_add_error_mag(c, r); /* b = a + random point */ arb_set(b, a); arf_set_mag(t, r); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { printf("FAIL (arb_add_error_mag)\n\n"); printf("a = "); arb_printn(a, 50, 0); printf("\n\n"); printf("b = "); arb_printn(b, 50, 0); printf("\n\n"); printf("c = "); arb_printn(c, 50, 0); printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); mag_clear(r); arf_clear(t); } for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; arf_t t; long e; arb_init(a); arb_init(b); arb_init(c); arf_init(t); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); e = n_randint(state, 10) - 10; /* c = a plus error bounds */ arb_set(c, a); arb_add_error_2exp_si(c, e); /* b = a + random point */ arb_set(b, a); arf_one(t); arf_mul_2exp_si(t, t, e); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { printf("FAIL (arb_add_error_2exp_si)\n\n"); printf("a = "); arb_printn(a, 50, 0); printf("\n\n"); printf("b = "); arb_printn(b, 50, 0); printf("\n\n"); printf("c = "); arb_printn(c, 50, 0); printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(t); } for (iter = 0; iter < 10000; iter++) { arb_t a, b, c; arf_t t; fmpz_t e; arb_init(a); arb_init(b); arb_init(c); arf_init(t); fmpz_init(e); arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10); arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10); fmpz_randtest(e, state, 10); /* c = a plus error bounds */ arb_set(c, a); arb_add_error_2exp_fmpz(c, e); /* b = a + random point */ arb_set(b, a); arf_one(t); arf_mul_2exp_fmpz(t, t, e); if (n_randint(state, 2)) arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); else arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN); /* should this be done differently? */ if (arf_is_nan(arb_midref(b))) arf_zero(arb_midref(b)); if (!arb_contains(c, b)) { printf("FAIL (arb_add_error_2exp_fmpz)\n\n"); printf("a = "); arb_printn(a, 50, 0); printf("\n\n"); printf("b = "); arb_printn(b, 50, 0); printf("\n\n"); printf("c = "); arb_printn(c, 50, 0); printf("\n\n"); abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arf_clear(t); fmpz_clear(e); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
int acb_calc_integrate_taylor(acb_t res, acb_calc_func_t func, void * param, const acb_t a, const acb_t b, const arf_t inner_radius, const arf_t outer_radius, long accuracy_goal, long prec) { long num_steps, step, N, bp; int result; acb_t delta, m, x, y1, y2, sum; acb_ptr taylor_poly; arf_t err; acb_init(delta); acb_init(m); acb_init(x); acb_init(y1); acb_init(y2); acb_init(sum); arf_init(err); acb_sub(delta, b, a, prec); /* precision used for bounds calculations */ bp = MAG_BITS; /* compute the number of steps */ { arf_t t; arf_init(t); acb_get_abs_ubound_arf(t, delta, bp); arf_div(t, t, inner_radius, bp, ARF_RND_UP); arf_mul_2exp_si(t, t, -1); num_steps = (long) (arf_get_d(t, ARF_RND_UP) + 1.0); /* make sure it's not something absurd */ num_steps = FLINT_MIN(num_steps, 10 * prec); num_steps = FLINT_MAX(num_steps, 1); arf_clear(t); } result = ARB_CALC_SUCCESS; acb_zero(sum); for (step = 0; step < num_steps; step++) { /* midpoint of subinterval */ acb_mul_ui(m, delta, 2 * step + 1, prec); acb_div_ui(m, m, 2 * num_steps, prec); acb_add(m, m, a, prec); if (arb_calc_verbose) { printf("integration point %ld/%ld: ", 2 * step + 1, 2 * num_steps); acb_printd(m, 15); printf("\n"); } /* evaluate at +/- x */ /* TODO: exactify m, and include error in x? */ acb_div_ui(x, delta, 2 * num_steps, prec); /* compute bounds and number of terms to use */ { arb_t cbound, xbound, rbound; arf_t C, D, R, X, T; double DD, TT, NN; arb_init(cbound); arb_init(xbound); arb_init(rbound); arf_init(C); arf_init(D); arf_init(R); arf_init(X); arf_init(T); /* R is the outer radius */ arf_set(R, outer_radius); /* X = upper bound for |x| */ acb_get_abs_ubound_arf(X, x, bp); arb_set_arf(xbound, X); /* Compute C(m,R). Important subtlety: due to rounding when computing m, we will in general be farther than R away from the integration path. But since acb_calc_cauchy_bound actually integrates over the area traced by a complex interval, it will catch any extra singularities (giving an infinite bound). */ arb_set_arf(rbound, outer_radius); acb_calc_cauchy_bound(cbound, func, param, m, rbound, 8, bp); arf_set_mag(C, arb_radref(cbound)); arf_add(C, arb_midref(cbound), C, bp, ARF_RND_UP); /* Sanity check: we need C < inf and R > X */ if (arf_is_finite(C) && arf_cmp(R, X) > 0) { /* Compute upper bound for D = C * R * X / (R - X) */ arf_mul(D, C, R, bp, ARF_RND_UP); arf_mul(D, D, X, bp, ARF_RND_UP); arf_sub(T, R, X, bp, ARF_RND_DOWN); arf_div(D, D, T, bp, ARF_RND_UP); /* Compute upper bound for T = (X / R) */ arf_div(T, X, R, bp, ARF_RND_UP); /* Choose N */ /* TODO: use arf arithmetic to avoid overflow */ /* TODO: use relative accuracy (look at |f(m)|?) */ DD = arf_get_d(D, ARF_RND_UP); TT = arf_get_d(T, ARF_RND_UP); NN = -(accuracy_goal * 0.69314718055994530942 + log(DD)) / log(TT); N = NN + 0.5; N = FLINT_MIN(N, 100 * prec); N = FLINT_MAX(N, 1); /* Tail bound: D / (N + 1) * T^N */ { mag_t TT; mag_init(TT); arf_get_mag(TT, T); mag_pow_ui(TT, TT, N); arf_set_mag(T, TT); mag_clear(TT); } arf_mul(D, D, T, bp, ARF_RND_UP); arf_div_ui(err, D, N + 1, bp, ARF_RND_UP); } else { N = 1; arf_pos_inf(err); result = ARB_CALC_NO_CONVERGENCE; } if (arb_calc_verbose) { printf("N = %ld; bound: ", N); arf_printd(err, 15); printf("\n"); printf("R: "); arf_printd(R, 15); printf("\n"); printf("C: "); arf_printd(C, 15); printf("\n"); printf("X: "); arf_printd(X, 15); printf("\n"); } arb_clear(cbound); arb_clear(xbound); arb_clear(rbound); arf_clear(C); arf_clear(D); arf_clear(R); arf_clear(X); arf_clear(T); } /* evaluate Taylor polynomial */ taylor_poly = _acb_vec_init(N + 1); func(taylor_poly, m, param, N, prec); _acb_poly_integral(taylor_poly, taylor_poly, N + 1, prec); _acb_poly_evaluate(y2, taylor_poly, N + 1, x, prec); acb_neg(x, x); _acb_poly_evaluate(y1, taylor_poly, N + 1, x, prec); acb_neg(x, x); /* add truncation error */ arb_add_error_arf(acb_realref(y1), err); arb_add_error_arf(acb_imagref(y1), err); arb_add_error_arf(acb_realref(y2), err); arb_add_error_arf(acb_imagref(y2), err); acb_add(sum, sum, y2, prec); acb_sub(sum, sum, y1, prec); if (arb_calc_verbose) { printf("values: "); acb_printd(y1, 15); printf(" "); acb_printd(y2, 15); printf("\n"); } _acb_vec_clear(taylor_poly, N + 1); if (result == ARB_CALC_NO_CONVERGENCE) break; } acb_set(res, sum); acb_clear(delta); acb_clear(m); acb_clear(x); acb_clear(y1); acb_clear(y2); acb_clear(sum); arf_clear(err); return result; }