void acb_cot(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_cot(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_coth(acb_imagref(r), acb_imagref(z), prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_zero(acb_realref(r)); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos(r, t, z, prec + 4); acb_div(r, t, r, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_mul_onei(t, t); acb_exp(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } else { acb_div_onei(t, t); acb_exp(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } } acb_clear(t); } }
void acb_atanh(acb_t res, const acb_t z, slong prec) { acb_mul_onei(res, z); acb_atan(res, res, prec); acb_div_onei(res, res); }
void integrals_edge_factors_gc(acb_ptr res, const acb_t cab, const acb_t ba2, sec_t c, slong prec) { slong i; acb_t cj, ci; acb_init(cj); acb_init(ci); /* polynomial shift */ acb_vec_polynomial_shift(res, cab, c.g, prec); /* constants cj, j = 1 */ /* c_1 = (1-zeta^-1) ba2^(-d/2) (-I)^i * = 2 / ba2^(d/2) */ acb_pow_ui(cj, ba2, c.d / 2, prec); if (c.d % 2) { acb_t t; acb_init(t); acb_sqrt(t, ba2, prec); acb_mul(cj, cj, t, prec); acb_clear(t); } acb_inv(cj, cj, prec); acb_mul_2exp_si(cj, cj, 1); _acb_vec_scalar_mul(res, res, c.g, cj, prec); /* constant ci = -I * ba2*/ acb_one(ci); for (i = 1; i < c.g; i++) { acb_mul(ci, ci, ba2, prec); acb_div_onei(ci, ci); acb_mul(res + i, res + i, ci, prec); } acb_clear(ci); acb_clear(cj); }
int main(int argc, char *argv[]) { acb_t s, t, a, b; mag_t tol; slong prec, goal; slong N; ulong k; int integral, ifrom, ito; int i, twice, havegoal, havetol; acb_calc_integrate_opt_t options; ifrom = ito = -1; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-i")) { if (!strcmp(argv[i+1], "all")) { ifrom = 0; ito = NUM_INTEGRALS - 1; } else { ifrom = ito = atol(argv[i+1]); if (ito < 0 || ito >= NUM_INTEGRALS) flint_abort(); } } } if (ifrom == -1) { flint_printf("Compute integrals using acb_calc_integrate.\n"); flint_printf("Usage: integrals -i n [-prec p] [-tol eps] [-twice] [...]\n\n"); flint_printf("-i n - compute integral n (0 <= n <= %d), or \"-i all\"\n", NUM_INTEGRALS - 1); flint_printf("-prec p - precision in bits (default p = 64)\n"); flint_printf("-goal p - approximate relative accuracy goal (default p)\n"); flint_printf("-tol eps - approximate absolute error goal (default 2^-p)\n"); flint_printf("-twice - run twice (to see overhead of computing nodes)\n"); flint_printf("-heap - use heap for subinterval queue\n"); flint_printf("-verbose - show information\n"); flint_printf("-verbose2 - show more information\n"); flint_printf("-deg n - use quadrature degree up to n\n"); flint_printf("-eval n - limit number of function evaluations to n\n"); flint_printf("-depth n - limit subinterval queue size to n\n\n"); flint_printf("Implemented integrals:\n"); for (integral = 0; integral < NUM_INTEGRALS; integral++) flint_printf("I%d = %s\n", integral, descr[integral]); flint_printf("\n"); return 1; } acb_calc_integrate_opt_init(options); prec = 64; twice = 0; goal = 0; havetol = havegoal = 0; acb_init(a); acb_init(b); acb_init(s); acb_init(t); mag_init(tol); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-prec")) { prec = atol(argv[i+1]); } else if (!strcmp(argv[i], "-twice")) { twice = 1; } else if (!strcmp(argv[i], "-goal")) { goal = atol(argv[i+1]); if (goal < 0) { flint_printf("expected goal >= 0\n"); return 1; } havegoal = 1; } else if (!strcmp(argv[i], "-tol")) { arb_t x; arb_init(x); arb_set_str(x, argv[i+1], 10); arb_get_mag(tol, x); arb_clear(x); havetol = 1; } else if (!strcmp(argv[i], "-deg")) { options->deg_limit = atol(argv[i+1]); } else if (!strcmp(argv[i], "-eval")) { options->eval_limit = atol(argv[i+1]); } else if (!strcmp(argv[i], "-depth")) { options->depth_limit = atol(argv[i+1]); } else if (!strcmp(argv[i], "-verbose")) { options->verbose = 1; } else if (!strcmp(argv[i], "-verbose2")) { options->verbose = 2; } else if (!strcmp(argv[i], "-heap")) { options->use_heap = 1; } } if (!havegoal) goal = prec; if (!havetol) mag_set_ui_2exp_si(tol, 1, -prec); for (integral = ifrom; integral <= ito; integral++) { flint_printf("I%d = %s ...\n", integral, descr[integral]); for (i = 0; i < 1 + twice; i++) { TIMEIT_ONCE_START switch (integral) { case 0: acb_set_d(a, 0); acb_set_d(b, 100); acb_calc_integrate(s, f_sin, NULL, a, b, goal, tol, options, prec); break; case 1: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_atanderiv, NULL, a, b, goal, tol, options, prec); acb_mul_2exp_si(s, s, 2); break; case 2: acb_set_d(a, 0); acb_one(b); acb_mul_2exp_si(b, b, goal); acb_calc_integrate(s, f_atanderiv, NULL, a, b, goal, tol, options, prec); arb_add_error_2exp_si(acb_realref(s), -goal); acb_mul_2exp_si(s, s, 1); break; case 3: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_circle, NULL, a, b, goal, tol, options, prec); acb_mul_2exp_si(s, s, 2); break; case 4: acb_set_d(a, 0); acb_set_d(b, 8); acb_calc_integrate(s, f_rump, NULL, a, b, goal, tol, options, prec); break; case 5: acb_set_d(a, 1); acb_set_d(b, 101); acb_calc_integrate(s, f_floor, NULL, a, b, goal, tol, options, prec); break; case 6: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_helfgott, NULL, a, b, goal, tol, options, prec); break; case 7: acb_zero(s); acb_set_d_d(a, -1.0, -1.0); acb_set_d_d(b, 2.0, -1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 2.0, -1.0); acb_set_d_d(b, 2.0, 1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 2.0, 1.0); acb_set_d_d(b, -1.0, 1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, -1.0, 1.0); acb_set_d_d(b, -1.0, -1.0); acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_const_pi(t, prec); acb_div(s, s, t, prec); acb_mul_2exp_si(s, s, -1); acb_div_onei(s, s); break; case 8: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_essing, NULL, a, b, goal, tol, options, prec); break; case 9: acb_set_d(a, 0); acb_set_d(b, 1); acb_calc_integrate(s, f_essing2, NULL, a, b, goal, tol, options, prec); break; case 10: acb_set_d(a, 0); acb_set_d(b, 10000); acb_calc_integrate(s, f_factorial1000, NULL, a, b, goal, tol, options, prec); break; case 11: acb_set_d_d(a, 1.0, 0.0); acb_set_d_d(b, 1.0, 1000.0); acb_calc_integrate(s, f_gamma, NULL, a, b, goal, tol, options, prec); break; case 12: acb_set_d(a, -10.0); acb_set_d(b, 10.0); acb_calc_integrate(s, f_sin_plus_small, NULL, a, b, goal, tol, options, prec); break; case 13: acb_set_d(a, -1020.0); acb_set_d(b, -1010.0); acb_calc_integrate(s, f_exp, NULL, a, b, goal, tol, options, prec); break; case 14: acb_set_d(a, 0); acb_set_d(b, ceil(sqrt(goal * 0.693147181) + 1.0)); acb_calc_integrate(s, f_gaussian, NULL, a, b, goal, tol, options, prec); acb_mul(b, b, b, prec); acb_neg(b, b); acb_exp(b, b, prec); arb_add_error(acb_realref(s), acb_realref(b)); break; case 15: acb_set_d(a, 0.0); acb_set_d(b, 1.0); acb_calc_integrate(s, f_spike, NULL, a, b, goal, tol, options, prec); break; case 16: acb_set_d(a, 0.0); acb_set_d(b, 8.0); acb_calc_integrate(s, f_monster, NULL, a, b, goal, tol, options, prec); break; case 17: acb_set_d(a, 0); acb_set_d(b, ceil(goal * 0.693147181 + 1.0)); acb_calc_integrate(s, f_sech, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_exp(b, b, prec); acb_mul_2exp_si(b, b, 1); arb_add_error(acb_realref(s), acb_realref(b)); break; case 18: acb_set_d(a, 0); acb_set_d(b, ceil(goal * 0.693147181 / 3.0 + 2.0)); acb_calc_integrate(s, f_sech3, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_mul_ui(b, b, 3, prec); acb_exp(b, b, prec); acb_mul_2exp_si(b, b, 3); acb_div_ui(b, b, 3, prec); arb_add_error(acb_realref(s), acb_realref(b)); break; case 19: if (goal < 0) abort(); /* error bound 2^-N (1+N) when truncated at 2^-N */ N = goal + FLINT_BIT_COUNT(goal); acb_one(a); acb_mul_2exp_si(a, a, -N); acb_one(b); acb_calc_integrate(s, f_log_div1p, NULL, a, b, goal, tol, options, prec); acb_set_ui(b, N + 1); acb_mul_2exp_si(b, b, -N); arb_add_error(acb_realref(s), acb_realref(b)); break; case 20: if (goal < 0) abort(); /* error bound (N+1) exp(-N) when truncated at N */ N = goal + FLINT_BIT_COUNT(goal); acb_zero(a); acb_set_ui(b, N); acb_calc_integrate(s, f_log_div1p_transformed, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_exp(b, b, prec); acb_mul_ui(b, b, N + 1, prec); arb_add_error(acb_realref(s), acb_realref(b)); break; case 21: acb_zero(s); N = 10; acb_set_d_d(a, 0.5, -0.5); acb_set_d_d(b, 0.5, 0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 0.5, 0.5); acb_set_d_d(b, -0.5, 0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, -0.5, 0.5); acb_set_d_d(b, -0.5, -0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, -0.5, -0.5); acb_set_d_d(b, 0.5, -0.5); acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_const_pi(t, prec); acb_div(s, s, t, prec); acb_mul_2exp_si(s, s, -1); acb_div_onei(s, s); break; case 22: acb_zero(s); N = 1000; acb_set_d_d(a, 100.0, 0.0); acb_set_d_d(b, 100.0, N); acb_calc_integrate(t, f_zeta_frac, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_set_d_d(a, 100, N); acb_set_d_d(b, 0.5, N); acb_calc_integrate(t, f_zeta_frac, NULL, a, b, goal, tol, options, prec); acb_add(s, s, t, prec); acb_div_onei(s, s); arb_zero(acb_imagref(s)); acb_set_ui(t, N); acb_dirichlet_hardy_theta(t, t, NULL, NULL, 1, prec); acb_add(s, s, t, prec); acb_const_pi(t, prec); acb_div(s, s, t, prec); acb_add_ui(s, s, 1, prec); break; case 23: acb_set_d(a, 0.0); acb_set_d(b, 1000.0); acb_calc_integrate(s, f_lambertw, NULL, a, b, goal, tol, options, prec); break; case 24: acb_set_d(a, 0.0); acb_const_pi(b, prec); acb_calc_integrate(s, f_max_sin_cos, NULL, a, b, goal, tol, options, prec); break; case 25: acb_set_si(a, -1); acb_set_si(b, 1); acb_calc_integrate(s, f_erf_bent, NULL, a, b, goal, tol, options, prec); break; case 26: acb_set_si(a, -10); acb_set_si(b, 10); acb_calc_integrate(s, f_airy_ai, NULL, a, b, goal, tol, options, prec); break; case 27: acb_set_si(a, 0); acb_set_si(b, 10); acb_calc_integrate(s, f_horror, NULL, a, b, goal, tol, options, prec); break; case 28: acb_set_d_d(a, -1, -1); acb_set_d_d(b, -1, 1); acb_calc_integrate(s, f_sqrt, NULL, a, b, goal, tol, options, prec); break; case 29: acb_set_d(a, 0); acb_set_d(b, ceil(sqrt(goal * 0.693147181) + 1.0)); acb_calc_integrate(s, f_gaussian_twist, NULL, a, b, goal, tol, options, prec); acb_mul(b, b, b, prec); acb_neg(b, b); acb_exp(b, b, prec); arb_add_error(acb_realref(s), acb_realref(b)); arb_add_error(acb_imagref(s), acb_realref(b)); break; case 30: acb_set_d(a, 0); acb_set_d(b, ceil(goal * 0.693147181 + 1.0)); acb_calc_integrate(s, f_exp_airy, NULL, a, b, goal, tol, options, prec); acb_neg(b, b); acb_exp(b, b, prec); acb_mul_2exp_si(b, b, 1); arb_add_error(acb_realref(s), acb_realref(b)); break; case 31: acb_zero(a); acb_const_pi(b, prec); acb_calc_integrate(s, f_sin_cos_frac, NULL, a, b, goal, tol, options, prec); break; case 32: acb_zero(a); acb_set_ui(b, 3); acb_calc_integrate(s, f_sin_near_essing, NULL, a, b, goal, tol, options, prec); break; case 33: acb_zero(a); acb_zero(b); k = 3; scaled_bessel_select_N(acb_realref(b), k, prec); acb_calc_integrate(s, f_scaled_bessel, &k, a, b, goal, tol, options, prec); scaled_bessel_tail_bound(acb_realref(a), k, acb_realref(b), prec); arb_add_error(acb_realref(s), acb_realref(a)); break; case 34: acb_zero(a); acb_zero(b); k = 15; scaled_bessel_select_N(acb_realref(b), k, prec); acb_calc_integrate(s, f_scaled_bessel, &k, a, b, goal, tol, options, prec); scaled_bessel_tail_bound(acb_realref(a), k, acb_realref(b), prec); arb_add_error(acb_realref(s), acb_realref(a)); break; case 35: acb_set_d_d(a, -1, -1); acb_set_d_d(b, -1, 1); acb_calc_integrate(s, f_rsqrt, NULL, a, b, goal, tol, options, prec); break; default: abort(); } TIMEIT_ONCE_STOP } flint_printf("I%d = ", integral); acb_printn(s, 3.333 * prec, 0); flint_printf("\n\n"); } acb_clear(a); acb_clear(b); acb_clear(s); acb_clear(t); mag_clear(tol); flint_cleanup(); return 0; }
void acb_hypgeom_fresnel_erf(acb_t res1, acb_t res2, const acb_t z, slong prec) { acb_t t, u, v, w1, w2; acb_init(t); acb_init(v); acb_init(w1); if (arb_is_zero(acb_imagref(z))) { acb_mul_onei(t, z); acb_add(w1, z, t, 2 * prec); acb_hypgeom_erf(t, w1, prec + 4); acb_mul_2exp_si(t, t, 1); acb_mul_onei(v, t); acb_add(t, t, v, prec); if (res1 != NULL) acb_set_arb(res1, acb_realref(t)); if (res2 != NULL) acb_set_arb(res2, acb_imagref(t)); } else if (arb_is_zero(acb_realref(z))) { acb_mul_onei(t, z); acb_sub(w1, t, z, 2 * prec); acb_hypgeom_erf(t, w1, prec + 4); acb_mul_2exp_si(t, t, 1); acb_mul_onei(v, t); acb_add(t, t, v, prec); if (res1 != NULL) acb_set_arb(res1, acb_realref(t)); if (res1 != NULL) acb_mul_onei(res1, res1); if (res2 != NULL) acb_set_arb(res2, acb_imagref(t)); if (res2 != NULL) acb_div_onei(res2, res2); } else { acb_init(u); acb_init(w2); /* w1 = (1+i)z, w2 = (1-i)z */ acb_mul_onei(t, z); acb_add(w1, z, t, 2 * prec); acb_sub(w2, z, t, 2 * prec); acb_hypgeom_erf(t, w1, prec + 4); acb_hypgeom_erf(u, w2, prec + 4); /* S = (1+i) (t - ui) = (1+i) t + (1-i) u */ /* C = (1-i) (t + ui) = (1-i) t + (1+i) u */ acb_mul_onei(v, t); if (res1 != NULL) acb_add(res1, t, v, prec); if (res2 != NULL) acb_sub(res2, t, v, prec); acb_mul_onei(v, u); if (res1 != NULL) acb_add(res1, res1, u, prec); if (res1 != NULL) acb_sub(res1, res1, v, prec); if (res2 != NULL) acb_add(res2, res2, u, prec); if (res2 != NULL) acb_add(res2, res2, v, prec); acb_clear(u); acb_clear(w2); } acb_clear(t); acb_clear(v); acb_clear(w1); }