int main() { long iter; flint_rand_t state; printf("exp...."); fflush(stdout); flint_randinit(state); /* check exp(a+b) = exp(a)*exp(b) */ for (iter = 0; iter < 10000; iter++) { acb_t a, b, c, d, e; long prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); acb_randtest(c, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_add(c, a, b, prec); acb_exp(c, c, prec); acb_exp(d, a, prec); acb_exp(e, b, prec); acb_mul(d, d, e, prec); if (!acb_overlaps(c, d)) { printf("FAIL: overlap\n\n"); printf("a = "); acb_print(a); printf("\n\n"); printf("b = "); acb_print(b); printf("\n\n"); printf("c = "); acb_print(c); printf("\n\n"); printf("d = "); acb_print(d); printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
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); } }
/* f(z) = erf(z/sqrt(0.0002)*0.5 +1.5)*exp(-z), example provided by Silviu-Ioan Filip */ int f_erf_bent(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_set_ui(t, 1250); acb_sqrt(t, t, prec); acb_mul(t, t, z, prec); acb_set_d(res, 1.5); acb_add(res, res, t, prec); acb_hypgeom_erf(res, res, prec); acb_neg(t, z); acb_exp(t, t, prec); acb_mul(res, res, t, prec); acb_clear(t); return 0; }
/* REAL: erf(x) = 2x/sqrt(pi) * exp(-x^2) 1F1(1, 3/2, x^2) */ void acb_hypgeom_erf_1f1b(acb_t res, const acb_t z, slong prec) { acb_t a, b, t, w; acb_init(a); acb_init(b); acb_init(t); acb_init(w); acb_set_ui(b, 3); acb_mul_2exp_si(b, b, -1); acb_mul(w, z, z, prec); acb_hypgeom_pfq_direct(t, a, 0, b, 1, w, -1, prec); acb_neg(w, w); acb_exp(w, w, prec); acb_mul(t, t, w, prec); acb_mul(t, t, z, prec); arb_const_sqrt_pi(acb_realref(w), prec); acb_div_arb(t, t, acb_realref(w), prec); acb_mul_2exp_si(res, t, 1); acb_clear(a); acb_clear(b); acb_clear(t); acb_clear(w); }
int f_monster(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_exp(t, z, prec); acb_real_floor(res, t, order != 0, prec); if (acb_is_finite(res)) { acb_sub(res, t, res, prec); acb_add(t, t, z, prec); acb_sin(t, t, prec); acb_mul(res, res, t, prec); } acb_clear(t); return 0; }
/* f(z) = |z^4 + 10z^3 + 19z^2 - 6z - 6| exp(z) (for real z) -- Helfgott's integral on MathOverflow */ int f_helfgott(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_add_si(res, z, 10, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, 19, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, -6, prec); acb_mul(res, res, z, prec); acb_add_si(res, res, -6, prec); acb_real_abs(res, res, order != 0, prec); if (acb_is_finite(res)) { acb_t t; acb_init(t); acb_exp(t, z, prec); acb_mul(res, res, t, prec); acb_clear(t); } return 0; }
/* todo: remove radii */ void acb_lambertw_halley_step(acb_t res, acb_t ew, const acb_t z, const acb_t w, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_exp(ew, w, prec); acb_add_ui(u, w, 2, prec); acb_add_ui(v, w, 1, prec); acb_mul_2exp_si(v, v, 1); acb_div(v, u, v, prec); acb_mul(t, ew, w, prec); acb_sub(u, t, z, prec); acb_mul(v, v, u, prec); acb_neg(v, v); acb_add(v, v, t, prec); acb_add(v, v, ew, prec); acb_div(t, u, v, prec); acb_sub(t, w, t, prec); acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(v); }
static void _acb_gamma(acb_t y, const acb_t x, long prec, int inverse) { int reflect; long r, n, wp; acb_t t, u, v; wp = prec + FLINT_BIT_COUNT(prec); acb_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 0, wp); acb_init(t); acb_init(u); acb_init(v); if (reflect) { /* gamma(x) = (rf(1-x, r) * pi) / (gamma(1-x+r) sin(pi x)) */ acb_sub_ui(t, x, 1, wp); acb_neg(t, t); acb_rising_ui_rec(u, t, r, wp); arb_const_pi(acb_realref(v), wp); acb_mul_arb(u, u, acb_realref(v), wp); acb_add_ui(t, t, r, wp); acb_gamma_stirling_eval(v, t, n, 0, wp); acb_exp(v, v, wp); acb_sin_pi(t, x, wp); acb_mul(v, v, t, wp); } else { /* gamma(x) = gamma(x+r) / rf(x,r) */ acb_add_ui(t, x, r, wp); acb_gamma_stirling_eval(u, t, n, 0, wp); acb_exp(u, u, prec); acb_rising_ui_rec(v, x, r, wp); } if (inverse) acb_div(y, v, u, prec); else acb_div(y, u, v, prec); acb_clear(t); acb_clear(u); acb_clear(v); }
void acb_hypgeom_m_asymp(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { acb_t t, u, v, c; acb_init(t); acb_init(u); acb_init(v); acb_init(c); acb_sub(c, b, a, prec); acb_neg(v, z); acb_hypgeom_u_asymp(t, a, b, z, -1, prec); acb_hypgeom_u_asymp(u, c, b, v, -1, prec); /* gamma(b-a) */ acb_rgamma(v, c, prec); acb_mul(t, t, v, prec); /* z^(a-b) */ acb_neg(c, c); acb_pow(v, z, c, prec); acb_mul(u, u, v, prec); /* gamma(a) */ acb_rgamma(v, a, prec); acb_mul(u, u, v, prec); /* exp(z) */ acb_exp(v, z, prec); acb_mul(u, u, v, prec); /* (-z)^(-a) */ acb_neg(c, a); acb_neg(v, z); acb_pow(v, v, c, prec); acb_mul(t, t, v, prec); acb_add(t, t, u, prec); if (!regularized) { acb_gamma(v, b, prec); acb_mul(t, t, v, prec); } if (acb_is_real(a) && acb_is_real(b) && acb_is_real(z)) { arb_zero(acb_imagref(t)); } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(c); }
/* f(z) = exp(z) */ int f_exp(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_exp(res, z, prec); return 0; }
void _acb_pow_arb_exp(acb_t z, const acb_t x, const arb_t y, long prec) { acb_t t; acb_init(t); acb_log(t, x, prec); acb_mul_arb(t, t, y, prec); acb_exp(z, t, prec); acb_clear(t); }
/* f(z) = exp(-z^2+iz) */ int f_gaussian_twist(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_mul_onei(res, z); acb_submul(res, z, z, prec); acb_exp(res, res, prec); return 0; }
void acb_hypgeom_erf_asymp(acb_t res, const acb_t z, slong prec, slong prec2) { acb_t a, t, u; acb_init(a); acb_init(t); acb_init(u); acb_one(a); acb_mul_2exp_si(a, a, -1); acb_mul(t, z, z, prec2); acb_hypgeom_u_asymp(u, a, a, t, -1, prec2); acb_neg(t, t); acb_exp(t, t, prec2); acb_mul(u, u, t, prec2); acb_const_pi(t, prec2); acb_sqrt(t, t, prec2); acb_mul(t, t, z, prec2); acb_div(u, u, t, prec2); /* branch cut term: -1 or 1 */ if (arb_contains_zero(acb_realref(z))) { arb_zero(acb_imagref(t)); arf_zero(arb_midref(acb_realref(t))); mag_one(arb_radref(acb_realref(t))); } else { acb_set_si(t, arf_sgn(arb_midref(acb_realref(z)))); } acb_sub(t, t, u, prec); if (arb_is_zero(acb_imagref(z))) arb_zero(acb_imagref(t)); else if (arb_is_zero(acb_realref(z))) arb_zero(acb_realref(t)); acb_set(res, t); acb_clear(a); acb_clear(t); acb_clear(u); }
/* f(z) = exp(-z) Ai(-z) */ int f_exp_airy(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_neg(t, z); acb_hypgeom_airy(res, NULL, NULL, NULL, t, prec); acb_exp(t, t, prec); acb_mul(res, res, t, prec); acb_clear(t); return 0; }
/* f(z) = exp(-z) z^1000 */ int f_factorial1000(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_pow_ui(t, z, 1000, prec); acb_neg(res, z); acb_exp(res, res, prec); acb_mul(res, res, t, prec); acb_clear(t); return 0; }
/* f(z) = sin(z) + exp(-200-z^2) */ int f_sin_plus_small(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_mul(t, z, z, prec); acb_add_ui(t, t, 200, prec); acb_neg(t, t); acb_exp(t, t, prec); acb_sin(res, z, prec); acb_add(res, res, t, prec); acb_clear(t); return 0; }
/* f(z) = z exp(-z) / (1 + exp(-z)) */ int f_log_div1p_transformed(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_neg(t, z); acb_exp(t, t, prec); acb_add_ui(res, t, 1, prec); acb_div(res, t, res, prec); acb_mul(res, res, z, prec); acb_clear(t); return 0; }
void acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, long prec) { acb_t t; if (regularized) { acb_init(t); acb_rgamma(t, b, prec); } if (arf_sgn(arb_midref(acb_realref(z))) >= 0 || (acb_is_int(a) && arb_is_nonpositive(acb_realref(a)))) { _acb_hypgeom_m_1f1(res, a, b, z, prec); } else { /* Kummer's transformation */ acb_t u, v; acb_init(u); acb_init(v); acb_sub(u, b, a, prec); acb_neg(v, z); _acb_hypgeom_m_1f1(u, u, b, v, prec); acb_exp(v, z, prec); acb_mul(res, u, v, prec); acb_clear(u); acb_clear(v); } if (regularized) { acb_mul(res, res, t, prec); acb_clear(t); } }
void acb_hypgeom_bessel_k_asymp(acb_t res, const acb_t nu, const acb_t z, slong prec) { acb_t t, a, b, w; acb_init(t); acb_init(a); acb_init(b); acb_init(w); acb_one(a); acb_mul_2exp_si(a, a, -1); acb_add(a, a, nu, prec); acb_mul_2exp_si(b, nu, 1); acb_add_ui(b, b, 1, prec); acb_mul_2exp_si(w, z, 1); acb_hypgeom_u_asymp(t, a, b, w, -1, prec); acb_neg(w, z); acb_exp(w, w, prec); acb_mul(t, t, w, prec); acb_mul_2exp_si(w, z, 1); acb_rsqrt(w, w, prec); acb_mul(res, t, w, prec); arb_const_sqrt_pi(acb_realref(w), prec); acb_mul_arb(res, res, acb_realref(w), prec); acb_clear(t); acb_clear(a); acb_clear(b); acb_clear(w); }
int main() { slong iter; flint_rand_t state; flint_printf("gamma_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a0, a1, b, z, w0, w1, t, u, enz; slong prec0, prec1; int regularized; acb_init(a0); acb_init(a1); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(t); acb_init(u); acb_init(enz); regularized = n_randint(state, 3); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_add_ui(a1, a0, 1, prec0); acb_hypgeom_gamma_lower(w0, a0, z, regularized, prec0); acb_hypgeom_gamma_lower(w1, a1, z, regularized, prec1); acb_neg(enz, z); acb_exp(enz, enz, prec0); /* recurrence relations */ if (regularized == 2) { /* gamma^{*}(a,z) - exp(-z)/Gamma(a+1) - z gamma^{*}(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E4 */ acb_set(t, w0); acb_rgamma(u, a1, prec0); acb_submul(t, enz, u, prec0); acb_submul(t, z, w1, prec0); } else if (regularized == 1) { /* P(a,z) - exp(-z) z^a / Gamma(a+1) - P(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E5 */ acb_pow(u, z, a0, prec0); acb_rgamma(b, a1, prec0); acb_mul(u, u, b, prec0); acb_sub(t, w0, w1, prec0); acb_submul(t, enz, u, prec0); } else { /* a gamma(a,z) - exp(-z) z^a - gamma(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E1 */ acb_pow(u, z, a0, prec0); acb_mul(t, a0, w0, prec0); acb_submul(t, enz, u, prec0); acb_sub(t, t, w1, prec0); } if (!acb_contains_zero(t)) { flint_printf("FAIL: recurrence relation\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); abort(); } /* identities relating lower and upper incomplete gamma functions */ if (regularized == 0 || regularized == 1) { acb_t u0; acb_init(u0); acb_hypgeom_gamma_upper(u0, a0, z, regularized, prec0); acb_zero(t); if (regularized == 1) { /* P(s,z) + Q(s,z) - 1 = 0 */ /* http://dlmf.nist.gov/8.2.E5 */ acb_add(t, w0, u0, prec0); acb_sub_ui(t, t, 1, prec0); } else { /* gamma(s,z) + Gamma(s,z) - Gamma(s) = 0 */ /* excludes non-positive integer values of s */ /* http://dlmf.nist.gov/8.2.E3 */ if (!acb_is_int(a0) || arb_is_positive(acb_realref(a0))) { acb_gamma(b, a0, prec0); acb_add(t, w0, u0, prec0); acb_sub(t, t, b, prec0); } } if (!acb_contains_zero(t)) { flint_printf("FAIL: lower plus upper\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); abort(); } acb_clear(u0); } acb_clear(a0); acb_clear(a1); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(t); acb_clear(u); acb_clear(enz); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_hypgeom_chi_asymp(acb_t res, const acb_t z, slong prec) { acb_t t, u, v, one; acb_init(t); acb_init(u); acb_init(v); acb_init(one); acb_one(one); /* u = U(1,1,z) */ acb_hypgeom_u_asymp(u, one, one, z, -1, prec); /* v = e^(-z) */ acb_neg(v, z); acb_exp(v, v, prec); acb_mul(t, u, v, prec); if (arb_is_zero(acb_realref(z))) { arb_div(acb_realref(t), acb_imagref(t), acb_imagref(z), prec); arb_zero(acb_imagref(t)); acb_neg(t, t); } else { /* u = U(1,1,-z) */ acb_neg(u, z); acb_hypgeom_u_asymp(u, one, one, u, -1, prec); acb_inv(v, v, prec); acb_submul(t, u, v, prec); acb_div(t, t, z, prec); acb_mul_2exp_si(t, t, -1); acb_neg(t, t); } if (acb_is_real(z)) { if (arb_is_positive(acb_realref(z))) { arb_zero(acb_imagref(t)); } else if (arb_is_negative(acb_realref(z))) { arb_const_pi(acb_imagref(t), prec); } else { /* add [-pi,pi]/2 i */ acb_const_pi(u, prec); arb_zero(acb_imagref(t)); arb_add_error(acb_imagref(t), acb_realref(u)); } } else { /* -pi/2 if positive real or in lower half plane pi/2 if negative real or in upper half plane */ if (arb_is_negative(acb_imagref(z))) { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_sub(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else if (arb_is_positive(acb_imagref(z))) { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_add(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else { /* add [-pi,pi]/2 i */ acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_add_error(acb_imagref(t), acb_realref(u)); } } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(one); }
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; }
int main() { slong iter; flint_rand_t state; flint_printf("exp_pi_i...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 200), 3); acb_randtest(b, state, 1 + n_randint(state, 200), 3); acb_randtest(c, state, 1 + n_randint(state, 200), 3); acb_randtest(d, state, 1 + n_randint(state, 200), 3); prec = 2 + n_randint(state, 200); acb_exp_pi_i(b, a, prec); acb_const_pi(c, prec); acb_mul(c, c, a, prec); acb_mul_onei(c, c); acb_exp(d, c, prec); if (!acb_overlaps(d, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("b = "); acb_printd(b, 30); flint_printf("\n\n"); flint_printf("c = "); acb_printd(c, 30); flint_printf("\n\n"); flint_printf("d = "); acb_printd(d, 30); flint_printf("\n\n"); abort(); } acb_set(c, a); acb_exp_pi_i(c, c, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void _acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec, slong gamma_prec, int kummer) { if (regularized) { /* Remove singularity */ if (acb_is_int(b) && arb_is_nonpositive(acb_realref(b)) && arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 30) < 0) { acb_t c, d, t, u; slong n; n = arf_get_si(arb_midref(acb_realref(b)), ARF_RND_DOWN); acb_init(c); acb_init(d); acb_init(t); acb_init(u); acb_sub(c, a, b, prec); acb_add_ui(c, c, 1, prec); acb_neg(d, b); acb_add_ui(d, d, 2, prec); _acb_hypgeom_m_1f1(t, c, d, z, 0, prec, gamma_prec, kummer); acb_pow_ui(u, z, 1 - n, prec); acb_mul(t, t, u, prec); acb_rising_ui(u, a, 1 - n, prec); acb_mul(t, t, u, prec); arb_fac_ui(acb_realref(u), 1 - n, prec); acb_div_arb(res, t, acb_realref(u), prec); acb_clear(c); acb_clear(d); acb_clear(t); acb_clear(u); } else { acb_t t; acb_init(t); acb_rgamma(t, b, gamma_prec); _acb_hypgeom_m_1f1(res, a, b, z, 0, prec, gamma_prec, kummer); acb_mul(res, res, t, prec); acb_clear(t); } return; } /* Kummer's transformation */ if (kummer) { acb_t u, v; acb_init(u); acb_init(v); acb_sub(u, b, a, prec); acb_neg(v, z); _acb_hypgeom_m_1f1(u, u, b, v, regularized, prec, gamma_prec, 0); acb_exp(v, z, prec); acb_mul(res, u, v, prec); acb_clear(u); acb_clear(v); return; } if (acb_is_one(a)) { acb_hypgeom_pfq_direct(res, NULL, 0, b, 1, z, -1, prec); } else { acb_struct c[3]; c[0] = *a; c[1] = *b; acb_init(c + 2); acb_one(c + 2); acb_hypgeom_pfq_direct(res, c, 1, c + 1, 2, z, -1, prec); acb_clear(c + 2); } }
void acb_hypgeom_erf_asymp(acb_t res, const acb_t z, int complementary, slong prec, slong prec2) { acb_t a, t, u; acb_init(a); acb_init(t); acb_init(u); if (!acb_is_exact(z) && (arf_cmpabs_ui(arb_midref(acb_realref(z)), prec) < 0) && (arf_cmpabs_ui(arb_midref(acb_imagref(z)), prec) < 0)) { acb_t zmid; mag_t re_err, im_err; acb_init(zmid); mag_init(re_err); mag_init(im_err); acb_hypgeom_erf_propagated_error(re_err, im_err, z); arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); acb_hypgeom_erf_asymp(res, zmid, complementary, prec, prec2); arb_add_error_mag(acb_realref(res), re_err); arb_add_error_mag(acb_imagref(res), im_err); acb_clear(zmid); mag_clear(re_err); mag_clear(im_err); return; } acb_one(a); acb_mul_2exp_si(a, a, -1); acb_mul(t, z, z, prec2); acb_hypgeom_u_asymp(u, a, a, t, -1, prec2); acb_neg(t, t); acb_exp(t, t, prec2); acb_mul(u, u, t, prec2); arb_const_sqrt_pi(acb_realref(t), prec2); arb_zero(acb_imagref(t)); acb_mul(t, t, z, prec2); acb_div(u, u, t, prec2); /* branch cut term: -1 or 1 */ acb_csgn(acb_realref(t), z); arb_zero(acb_imagref(t)); if (complementary) { /* erfc(z) = 1 - erf(z) = u - (sgn - 1) */ acb_sub_ui(t, t, 1, prec); acb_sub(t, u, t, prec); } else { /* erf(z) = sgn - u */ acb_sub(t, t, u, prec); } if (arb_is_zero(acb_imagref(z))) { arb_zero(acb_imagref(t)); } else if (arb_is_zero(acb_realref(z))) { if (complementary) arb_one(acb_realref(t)); else arb_zero(acb_realref(t)); } acb_set(res, t); acb_clear(a); acb_clear(t); acb_clear(u); }
/* note: z should be exact here */ void acb_lambertw_main(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { acb_t w, t, oldw, ew; mag_t err; slong i, wp, accuracy, ebits, kbits, mbits, wp_initial, extraprec; int have_ew; acb_init(t); acb_init(w); acb_init(oldw); acb_init(ew); mag_init(err); /* We need higher precision for large k, large exponents, or very close to the branch point at -1/e. todo: we should be recomputing ez1 to higher precision when close... */ acb_get_mag(err, z); if (fmpz_is_zero(k) && mag_cmp_2exp_si(err, 0) < 0) ebits = 0; else ebits = fmpz_bits(MAG_EXPREF(err)); if (fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z))) || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z)))) { acb_get_mag(err, ez1); mbits = -MAG_EXP(err); mbits = FLINT_MAX(mbits, 0); mbits = FLINT_MIN(mbits, prec); } else { mbits = 0; } kbits = fmpz_bits(k); extraprec = FLINT_MAX(ebits, kbits); extraprec = FLINT_MAX(extraprec, mbits); wp = wp_initial = 40 + extraprec; accuracy = acb_lambertw_initial(w, z, ez1, k, wp_initial); mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); /* We should be able to compute e^w for the final certification during the Halley iteration. */ have_ew = 0; for (i = 0; i < 5 + FLINT_BIT_COUNT(prec + extraprec); i++) { /* todo: should we restart? */ if (!acb_is_finite(w)) break; wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10); wp = FLINT_MAX(wp, 40); wp += extraprec; acb_set(oldw, w); acb_lambertw_halley_step(t, ew, z, w, wp); /* estimate the error (conservatively) */ acb_sub(w, w, t, wp); acb_get_mag(err, w); acb_set(w, t); acb_add_error_mag(t, err); accuracy = acb_rel_accuracy_bits(t); if (accuracy > 2 * extraprec) accuracy *= 2.9; /* less conservatively */ accuracy = FLINT_MIN(accuracy, wp); accuracy = FLINT_MAX(accuracy, 0); if (accuracy > prec + extraprec) { /* e^w = e^oldw * e^(w-oldw) */ acb_sub(t, w, oldw, wp); acb_exp(t, t, wp); acb_mul(ew, ew, t, wp); have_ew = 1; break; } mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); } wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10); wp = FLINT_MAX(wp, 40); wp += extraprec; if (acb_lambertw_check_branch(w, k, wp)) { acb_t u, r, eu1; mag_t err, rad; acb_init(u); acb_init(r); acb_init(eu1); mag_init(err); mag_init(rad); if (have_ew) acb_set(t, ew); else acb_exp(t, w, wp); /* t = w e^w */ acb_mul(t, t, w, wp); acb_sub(r, t, z, wp); /* Bound W' on the straight line path between t and z */ acb_union(u, t, z, wp); arb_const_e(acb_realref(eu1), wp); arb_zero(acb_imagref(eu1)); acb_mul(eu1, eu1, u, wp); acb_add_ui(eu1, eu1, 1, wp); if (acb_lambertw_branch_crossing(u, eu1, k)) { mag_inf(err); } else { acb_lambertw_bound_deriv(err, u, eu1, k); acb_get_mag(rad, r); mag_mul(err, err, rad); } acb_add_error_mag(w, err); acb_set(res, w); acb_clear(u); acb_clear(r); acb_clear(eu1); mag_clear(err); mag_clear(rad); } else { acb_indeterminate(res); } acb_clear(t); acb_clear(w); acb_clear(oldw); acb_clear(ew); mag_clear(err); }
int main() { long iter; flint_rand_t state; printf("log...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { acb_t x, a, b; long prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(a); acb_init(b); acb_randtest_special(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(a, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_randtest_special(b, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_log(a, x, prec1); acb_log(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { printf("FAIL: overlap\n\n"); printf("x = "); acb_printd(x, 15); printf("\n\n"); printf("a = "); acb_printd(a, 15); printf("\n\n"); printf("b = "); acb_printd(b, 15); printf("\n\n"); abort(); } /* check exp(log(x)) = x */ acb_exp(b, b, prec1); if (!acb_contains(b, x)) { printf("FAIL: functional equation\n\n"); printf("x = "); acb_printd(x, 15); printf("\n\n"); printf("b = "); acb_printd(b, 15); printf("\n\n"); abort(); } acb_log(x, x, prec1); if (!acb_overlaps(a, x)) { printf("FAIL: aliasing\n\n"); printf("a = "); acb_printd(a, 15); printf("\n\n"); printf("x = "); acb_printd(x, 15); printf("\n\n"); abort(); } acb_clear(x); acb_clear(a); acb_clear(b); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void acb_hypgeom_ci_asymp(acb_t res, const acb_t z, slong prec) { acb_t t, u, w, v, one; acb_init(t); acb_init(u); acb_init(w); acb_init(v); acb_init(one); acb_one(one); acb_mul_onei(w, z); /* u = U(1,1,iz) */ acb_hypgeom_u_asymp(u, one, one, w, -1, prec); /* v = e^(-iz) */ acb_neg(v, w); acb_exp(v, v, prec); acb_mul(t, u, v, prec); if (acb_is_real(z)) { arb_div(acb_realref(t), acb_imagref(t), acb_realref(z), prec); arb_zero(acb_imagref(t)); acb_neg(t, t); } else { /* u = U(1,1,-iz) */ acb_neg(w, w); acb_hypgeom_u_asymp(u, one, one, w, -1, prec); acb_inv(v, v, prec); acb_submul(t, u, v, prec); acb_div(t, t, w, prec); acb_mul_2exp_si(t, t, -1); } if (arb_is_zero(acb_realref(z))) { if (arb_is_positive(acb_imagref(z))) { arb_const_pi(acb_imagref(t), prec); arb_mul_2exp_si(acb_imagref(t), acb_imagref(t), -1); } else if (arb_is_negative(acb_imagref(z))) { arb_const_pi(acb_imagref(t), prec); arb_mul_2exp_si(acb_imagref(t), acb_imagref(t), -1); arb_neg(acb_imagref(t), acb_imagref(t)); } else { acb_const_pi(u, prec); acb_mul_2exp_si(u, u, -1); arb_zero(acb_imagref(t)); arb_add_error(acb_imagref(t), acb_realref(u)); } } else { /* 0 if positive or positive imaginary pi if upper left quadrant (including negative real axis) -pi if lower left quadrant (including negative imaginary axis) */ if (arb_is_positive(acb_realref(z))) { /* do nothing */ } else if (arb_is_negative(acb_realref(z)) && arb_is_nonnegative(acb_imagref(z))) { acb_const_pi(u, prec); arb_add(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else if (arb_is_nonpositive(acb_realref(z)) && arb_is_negative(acb_imagref(z))) { acb_const_pi(u, prec); arb_sub(acb_imagref(t), acb_imagref(t), acb_realref(u), prec); } else { /* add [-pi,pi] */ acb_const_pi(u, prec); arb_add_error(acb_imagref(t), acb_realref(u)); } } acb_swap(res, t); acb_clear(t); acb_clear(u); acb_clear(w); acb_clear(v); acb_clear(one); }
int main() { long iter; flint_rand_t state; printf("gamma_upper...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000; iter++) { acb_t a0, a1, b, z, w0, w1, t, u; long prec0, prec1; int modified; acb_init(a0); acb_init(a1); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(t); acb_init(u); modified = n_randint(state, 2); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest_maybe_half_int(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_add_ui(a1, a0, 1, prec0); switch (n_randint(state, 4)) { case 0: acb_hypgeom_gamma_upper_asymp(w0, a0, z, modified, prec0); break; case 1: acb_hypgeom_gamma_upper_1f1a(w0, a0, z, modified, prec0); break; case 2: acb_hypgeom_gamma_upper_1f1b(w0, a0, z, modified, prec0); break; default: acb_hypgeom_gamma_upper(w0, a0, z, modified, prec0); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_gamma_upper_asymp(w1, a0, z, modified, prec1); break; case 1: acb_hypgeom_gamma_upper_1f1a(w1, a0, z, modified, prec1); break; case 2: acb_hypgeom_gamma_upper_1f1b(w1, a0, z, modified, prec1); break; default: acb_hypgeom_gamma_upper(w1, a0, z, modified, prec1); } if (!acb_overlaps(w0, w1)) { printf("FAIL: consistency\n\n"); printf("nu = "); acb_printd(a0, 30); printf("\n\n"); printf("z = "); acb_printd(z, 30); printf("\n\n"); printf("w0 = "); acb_printd(w0, 30); printf("\n\n"); printf("w1 = "); acb_printd(w1, 30); printf("\n\n"); abort(); } switch (n_randint(state, 4)) { case 0: acb_hypgeom_gamma_upper_asymp(w1, a1, z, modified, prec1); break; case 1: acb_hypgeom_gamma_upper_1f1a(w1, a1, z, modified, prec1); break; case 2: acb_hypgeom_gamma_upper_1f1b(w1, a1, z, modified, prec1); break; default: acb_hypgeom_gamma_upper(w1, a1, z, modified, prec1); } /* a Gamma(a,z) + exp(-z) z^a = Gamma(a+1,z) */ if (modified) acb_one(t); else acb_pow(t, z, a0, prec0); acb_neg(u, z); acb_exp(u, u, prec0); acb_mul(t, t, u, prec0); if (modified) { acb_mul(b, w1, z, prec0); acb_addmul(t, a0, w0, prec0); acb_sub(t, t, b, prec0); } else { acb_addmul(t, a0, w0, prec0); acb_sub(t, t, w1, prec0); } if (!acb_contains_zero(t)) { printf("FAIL: contiguous relation\n\n"); printf("nu = "); acb_printd(a0, 30); printf("\n\n"); printf("z = "); acb_printd(z, 30); printf("\n\n"); printf("w0 = "); acb_printd(w0, 30); printf("\n\n"); printf("w1 = "); acb_printd(w1, 30); printf("\n\n"); printf("t = "); acb_printd(t, 30); printf("\n\n"); abort(); } acb_clear(a0); acb_clear(a1); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }