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); }
void acb_hypgeom_u(acb_t res, const acb_t a, const acb_t b, const acb_t z, long prec) { acb_t t; acb_init(t); acb_sub(t, a, b, prec); acb_add_ui(t, t, 1, prec); if ((acb_is_int(a) && arf_sgn(arb_midref(acb_realref(a))) <= 0) || (acb_is_int(t) && arf_sgn(arb_midref(acb_realref(t))) <= 0) || acb_hypgeom_u_use_asymp(z, prec)) { acb_neg(t, a); acb_pow(t, z, t, prec); acb_hypgeom_u_asymp(res, a, b, z, -1, prec); acb_mul(res, res, t, prec); } else { acb_hypgeom_u_1f1(res, a, b, z, prec); } acb_clear(t); }
void acb_hypgeom_u_asymp_proper(acb_t res, const acb_t a, const acb_t b, const acb_t z, long prec) { acb_t t; acb_init(t); acb_pow(t, z, a, prec); acb_hypgeom_u_asymp(res, a, b, z, -1, prec); acb_div(res, res, t, prec); acb_clear(t); }
/* (+/- iz)^(-1/2-v) * z^v * exp(+/- iz) */ void acb_hypgeom_bessel_j_asymp_prefactors_fallback(acb_t Ap, acb_t Am, acb_t C, const acb_t nu, const acb_t z, long prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); /* v = -1/2-nu */ acb_one(v); acb_mul_2exp_si(v, v, -1); acb_add(v, v, nu, prec); acb_neg(v, v); acb_mul_onei(t, z); /* t = iz */ acb_neg(u, t); /* u = -iz */ /* Ap, Am = (+/- iz)^(-1/2-nu) */ acb_pow(Ap, t, v, prec); acb_pow(Am, u, v, prec); /* Ap, Am *= exp(+/- iz) */ acb_exp_invexp(u, v, t, prec); acb_mul(Ap, Ap, u, prec); acb_mul(Am, Am, v, prec); /* z^nu */ acb_pow(t, z, nu, prec); acb_mul(Ap, Ap, t, prec); acb_mul(Am, Am, t, prec); /* (2 pi)^(-1/2) */ acb_const_pi(C, prec); acb_mul_2exp_si(C, C, 1); acb_rsqrt(C, C, prec); acb_clear(t); acb_clear(u); acb_clear(v); }
void acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec) { acb_t jnu, t, u, v; acb_init(jnu); acb_init(t); acb_init(u); acb_init(v); acb_hypgeom_bessel_j(jnu, nu, z, prec); if (acb_is_int(nu)) { int is_real = acb_is_real(nu) && acb_is_real(z) && arb_is_positive(acb_realref(z)); acb_mul_onei(t, z); acb_hypgeom_bessel_k(t, nu, t, prec); acb_onei(u); acb_pow(u, u, nu, prec); acb_mul(t, t, u, prec); acb_const_pi(u, prec); acb_div(t, t, u, prec); acb_mul_2exp_si(t, t, 1); acb_neg(t, t); phase(v, acb_realref(z), acb_imagref(z)); acb_mul(u, jnu, v, prec); acb_mul_onei(u, u); acb_sub(res2, t, u, prec); if (is_real) arb_zero(acb_imagref(res2)); } else { acb_sin_cos_pi(t, u, nu, prec); acb_mul(v, jnu, u, prec); acb_neg(u, nu); acb_hypgeom_bessel_j(u, u, z, prec); acb_sub(v, v, u, prec); acb_div(res2, v, t, prec); } if (res1 != NULL) acb_set(res1, jnu); acb_clear(jnu); acb_clear(t); acb_clear(u); acb_clear(v); }
void acb_hypgeom_bessel_j_0f1(acb_t res, const acb_t nu, const acb_t z, long prec) { acb_struct b[2]; acb_t w, c, t; if (acb_is_int(nu) && arb_is_negative(acb_realref(nu))) { acb_init(t); acb_neg(t, nu); acb_hypgeom_bessel_j_0f1(res, t, z, prec); acb_mul_2exp_si(t, t, -1); if (!acb_is_int(t)) acb_neg(res, res); acb_clear(t); return; } acb_init(b + 0); acb_init(b + 1); acb_init(w); acb_init(c); acb_init(t); acb_add_ui(b + 0, nu, 1, prec); acb_one(b + 1); /* (z/2)^nu / gamma(nu+1) */ acb_mul_2exp_si(c, z, -1); acb_pow(c, c, nu, prec); acb_rgamma(t, b + 0, prec); acb_mul(c, t, c, prec); /* -z^2/4 */ acb_mul(w, z, z, prec); acb_mul_2exp_si(w, w, -2); acb_neg(w, w); acb_hypgeom_pfq_direct(t, NULL, 0, b, 2, w, -1, prec); acb_mul(res, t, c, prec); acb_clear(b + 0); acb_clear(b + 1); acb_clear(w); acb_clear(c); acb_clear(t); }
void acb_hypgeom_beta_lower(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec) { acb_t t, u; if (acb_is_zero(z) && arb_is_positive(acb_realref(a))) { acb_zero(res); return; } if (acb_is_one(z) && arb_is_positive(acb_realref(b))) { if (regularized) acb_one(res); else acb_beta(res, a, b, prec); return; } acb_init(t); acb_init(u); acb_sub_ui(t, b, 1, prec); acb_neg(t, t); acb_add_ui(u, a, 1, prec); if (regularized) { acb_hypgeom_2f1(t, a, t, u, z, 1, prec); acb_add(u, a, b, prec); acb_gamma(u, u, prec); acb_mul(t, t, u, prec); acb_rgamma(u, b, prec); acb_mul(t, t, u, prec); } else { acb_hypgeom_2f1(t, a, t, u, z, 0, prec); acb_div(t, t, a, prec); } acb_pow(u, z, a, prec); acb_mul(t, t, u, prec); acb_set(res, t); acb_clear(t); acb_clear(u); }
static void _acb_hypgeom_2f1r_reduced(acb_t res, const acb_t b, const acb_t c, const acb_t z, slong prec) { acb_t t, u; acb_init(t); acb_init(u); acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_neg(u, b); acb_pow(t, t, u, prec); acb_rgamma(u, c, prec); acb_mul(t, t, u, prec); acb_set(res, t); acb_clear(t); acb_clear(u); return; }
void acb_dirichlet_l(acb_t res, const acb_t s, const acb_dirichlet_group_t G, ulong m, slong prec) { acb_t chi, t, u, a; ulong k; acb_init(chi); acb_init(t); acb_init(u); acb_init(a); acb_zero(t); for (k = 1; k <= G->q; k++) { acb_dirichlet_chi(chi, G, m, k, prec); if (!acb_is_zero(chi)) { acb_set_ui(a, k); acb_div_ui(a, a, G->q, prec); acb_hurwitz_zeta(u, s, a, prec); acb_addmul(t, chi, u, prec); } } acb_set_ui(u, G->q); acb_neg(a, s); acb_pow(u, u, a, prec); acb_mul(res, t, u, prec); acb_clear(chi); acb_clear(t); acb_clear(u); acb_clear(a); }
void acb_hypgeom_bessel_k_0f1(acb_t res, const acb_t nu, const acb_t z, slong prec) { if (acb_is_int(nu)) { acb_poly_t nux, zx, rx; acb_poly_init(nux); acb_poly_init(zx); acb_poly_init(rx); acb_poly_set_coeff_acb(nux, 0, nu); acb_poly_set_coeff_si(nux, 1, 1); acb_poly_set_acb(zx, z); acb_hypgeom_bessel_k_0f1_series(rx, nux, zx, 1, prec); acb_poly_get_coeff_acb(res, rx, 0); acb_poly_clear(nux); acb_poly_clear(zx); acb_poly_clear(rx); } else { acb_t t, u, v, w; acb_struct b[2]; acb_init(t); acb_init(u); acb_init(v); acb_init(w); acb_init(b + 0); acb_init(b + 1); /* u = 0F1(1+nu), v = 0F1(1-nu) */ acb_mul(t, z, z, prec); acb_mul_2exp_si(t, t, -2); acb_add_ui(b, nu, 1, prec); acb_one(b + 1); acb_hypgeom_pfq_direct(u, NULL, 0, b, 2, t, -1, prec); acb_sub_ui(b, nu, 1, prec); acb_neg(b, b); acb_hypgeom_pfq_direct(v, NULL, 0, b, 2, t, -1, prec); /* v = v * gamma(nu) / (z/2)^nu */ acb_mul_2exp_si(t, z, -1); acb_pow(t, t, nu, prec); acb_gamma(w, nu, prec); acb_mul(v, v, w, prec); acb_div(v, v, t, prec); /* u = u * t * pi / (gamma(nu) * nu * sin(pi nu)) */ acb_mul(u, u, t, prec); acb_const_pi(t, prec); acb_mul(u, u, t, prec); acb_sin_pi(t, nu, prec); acb_mul(t, t, w, prec); acb_mul(t, t, nu, prec); acb_div(u, u, t, prec); acb_sub(res, v, u, prec); acb_mul_2exp_si(res, res, -1); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(w); acb_clear(b + 0); acb_clear(b + 1); } }
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; }
void acb_dirichlet_zeta_rs_mid(acb_t res, const acb_t s, slong K, slong prec) { acb_t R1, R2, X, t; slong wp; if (arf_sgn(arb_midref(acb_imagref(s))) < 0) { acb_init(t); acb_conj(t, s); acb_dirichlet_zeta_rs(res, t, K, prec); acb_conj(res, res); acb_clear(t); return; } acb_init(R1); acb_init(R2); acb_init(X); acb_init(t); /* rs_r increases the precision internally */ wp = prec; acb_dirichlet_zeta_rs_r(R1, s, K, wp); if (arb_is_exact(acb_realref(s)) && (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0)) { acb_conj(R2, R1); } else { /* conj(R(conj(1-s))) */ arb_sub_ui(acb_realref(t), acb_realref(s), 1, 10 * wp); arb_neg(acb_realref(t), acb_realref(t)); arb_set(acb_imagref(t), acb_imagref(s)); acb_dirichlet_zeta_rs_r(R2, t, K, wp); acb_conj(R2, R2); } if (acb_is_finite(R1) && acb_is_finite(R2)) { wp += 10 + arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(s))); wp = FLINT_MAX(wp, 10); /* X = pi^(s-1/2) gamma((1-s)/2) rgamma(s/2) = (2 pi)^s rgamma(s) / (2 cos(pi s / 2)) */ acb_rgamma(X, s, wp); acb_const_pi(t, wp); acb_mul_2exp_si(t, t, 1); acb_pow(t, t, s, wp); acb_mul(X, X, t, wp); acb_mul_2exp_si(t, s, -1); acb_cos_pi(t, t, wp); acb_mul_2exp_si(t, t, 1); acb_div(X, X, t, wp); acb_mul(R2, R2, X, wp); } /* R1 + X * R2 */ acb_add(res, R1, R2, prec); acb_clear(R1); acb_clear(R2); acb_clear(X); acb_clear(t); }
int main() { slong iter; flint_rand_t state; flint_printf("u_asymp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t a, b, a2, b2, z, U1, U2, t, u, M1, M2, am; acb_struct bm[2]; ulong n1, n2; slong prec0, prec1, prec2; acb_init(a); acb_init(b); acb_init(a2); acb_init(b2); acb_init(z); acb_init(U1); acb_init(U2); acb_init(t); acb_init(u); acb_init(M1); acb_init(M2); acb_init(am); acb_init(bm); acb_init(bm + 1); if (n_randint(state, 4) == 0) { n1 = n_randint(state, 200); n2 = n_randint(state, 200); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); } else { n1 = n_randint(state, 40); n2 = n_randint(state, 40); prec0 = 2 + n_randint(state, 300); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); } acb_randtest_param(a, state, prec0, 1 + n_randint(state, 20)); if (n_randint(state, 4) == 0) acb_add_ui(b, a, n_randint(state, 10), prec0); else acb_randtest_param(b, state, prec0, 1 + n_randint(state, 20)); acb_randtest(z, state, prec0, 1 + n_randint(state, 20)); /* Test Kummer's transformation */ acb_sub(a2, a, b, prec0); acb_add_ui(a2, a2, 1, prec0); acb_sub_ui(b2, b, 2, prec0); acb_neg(b2, b2); acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1); acb_hypgeom_u_asymp(U2, a2, b2, z, n2, prec2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (Kummer transformation)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); abort(); } /* Check contiguous relation (b-a-1)U(a,b-1,z) + z U(a,b+1,z) + (1-b-z) U(a,b,z) = 0 */ acb_one(t); acb_sub(t, t, b, prec0); acb_sub(t, t, z, prec0); acb_mul(u, U1, t, prec1); acb_add_ui(b2, b, 1, prec0); acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2); acb_addmul(u, U2, z, prec1); acb_sub_ui(b2, b, 1, prec0); acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2); acb_sub(t, b, a, prec0); acb_sub_ui(t, t, 1, prec0); acb_mul(t, t, U2, prec0); acb_add(t, t, u, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL (contiguous relation)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("t = "); acb_printd(t, 100); flint_printf("\n"); abort(); } /* Test U(a,b,z) = gamma(1-b)/gamma(a-b+1) M(a,b,z) + gamma(b-1)/gamma(a) z^(1-b) M(a-b+1,2-b,z) */ acb_set(am, a); acb_set(bm, b); acb_one(bm + 1); acb_hypgeom_pfq_direct(M1, am, 1, bm, 2, z, n2, prec2); acb_sub(am, a, b, prec2); acb_add_ui(am, am, 1, prec2); acb_sub_ui(bm, b, 2, prec2); acb_neg(bm, bm); acb_one(bm + 1); acb_hypgeom_pfq_direct(M2, am, 1, bm, 2, z, n2, prec2); acb_sub(am, a, b, prec2); acb_add_ui(am, am, 1, prec2); acb_rgamma(am, am, prec2); acb_mul(M1, M1, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_neg(am, am); acb_gamma(am, am, prec2); acb_mul(M1, M1, am, prec2); acb_rgamma(am, a, prec2); acb_mul(M2, M2, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_gamma(am, am, prec2); acb_mul(M2, M2, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_neg(am, am); acb_pow(am, z, am, prec2); acb_mul(M2, M2, am, prec2); acb_add(U2, M1, M2, prec2); acb_pow(am, z, a, prec2); acb_mul(U2, U2, am, prec2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (U in terms of M)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); abort(); } /* Test special value: b = a+1 */ acb_add_ui(b, a, 1, prec0); acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1); acb_one(U2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (special value)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(a2); acb_clear(b2); acb_clear(z); acb_clear(U1); acb_clear(U2); acb_clear(t); acb_clear(u); acb_clear(M1); acb_clear(M2); acb_clear(am); acb_clear(bm); acb_clear(bm + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void _acb_hypgeom_legendre_q_single(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t a, b, c, z2, t, u; acb_init(a); acb_init(b); acb_init(c); acb_init(z2); acb_init(t); acb_init(u); /* invalid in (-1,0) */ if (!_acb_hypgeom_legendre_q_single_valid(z)) { acb_indeterminate(res); return; } acb_pow_si(z2, z, -2, prec); /* z2 = 1/z^2 */ /* t = 2F1r((m+n+1)/2, (m+n)/2+1, n+3/2, 1/z^2) */ acb_add(b, m, n, prec); acb_add_ui(a, b, 1, prec); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, b, -1); acb_add_ui(b, b, 1, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_add(c, c, n, prec); acb_hypgeom_2f1(t, a, b, c, z2, 1, prec); /* prefactor sqrt(pi) 2^-n (z+1)^(m/2) (z-1)^(m/2) exp(i pi m) */ /* (1/2) gamma(m+n+1) z^(-m-n-1) */ if (!acb_is_zero(m)) { acb_add_ui(z2, z, 1, prec); acb_mul_2exp_si(c, m, -1); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_sub_ui(z2, z, 1, prec); acb_mul_2exp_si(c, m, -1); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_exp_pi_i(z2, m, prec); acb_mul(t, t, z2, prec); } acb_set_ui(z2, 2); acb_neg(c, n); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_add(c, m, n, prec); acb_add_ui(c, c, 1, prec); acb_gamma(z2, c, prec); acb_mul(t, t, z2, prec); acb_neg(c, c); acb_pow(z2, z, c, prec); acb_mul(t, t, z2, prec); acb_mul_2exp_si(t, t, -1); arb_const_sqrt_pi(acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z2); acb_clear(t); acb_clear(u); }
void acb_hypgeom_u_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, long prec) { if (acb_is_int(b)) { acb_poly_t aa, bb, zz; acb_poly_init(aa); acb_poly_init(bb); acb_poly_init(zz); acb_poly_set_acb(aa, a); acb_poly_set_coeff_acb(bb, 0, b); acb_poly_set_coeff_si(bb, 1, 1); acb_poly_set_acb(zz, z); acb_hypgeom_u_1f1_series(zz, aa, bb, zz, 1, prec); acb_poly_get_coeff_acb(res, zz, 0); acb_poly_clear(aa); acb_poly_clear(bb); acb_poly_clear(zz); } else { acb_t t, u, v; acb_struct aa[3]; acb_init(t); acb_init(u); acb_init(v); acb_init(aa + 0); acb_init(aa + 1); acb_init(aa + 2); acb_set(aa, a); acb_set(aa + 1, b); acb_one(aa + 2); acb_hypgeom_pfq_direct(u, aa, 1, aa + 1, 2, z, -1, prec); acb_sub(aa, a, b, prec); acb_add_ui(aa, aa, 1, prec); acb_sub_ui(aa + 1, b, 2, prec); acb_neg(aa + 1, aa + 1); acb_hypgeom_pfq_direct(v, aa, 1, aa + 1, 2, z, -1, prec); acb_sub_ui(aa + 1, b, 1, prec); /* rgamma(a-b+1) * gamma(1-b) * u */ acb_rgamma(t, aa, prec); acb_mul(u, u, t, prec); acb_neg(t, aa + 1); acb_gamma(t, t, prec); acb_mul(u, u, t, prec); /* rgamma(a) * gamma(b-1) * z^(1-b) * v */ acb_rgamma(t, a, prec); acb_mul(v, v, t, prec); acb_gamma(t, aa + 1, prec); acb_mul(v, v, t, prec); acb_neg(t, aa + 1); acb_pow(t, z, t, prec); acb_mul(v, v, t, prec); acb_add(res, u, v, prec); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(aa + 0); acb_clear(aa + 1); acb_clear(aa + 2); } }
/* todo: use euler product for complex s, and check efficiency for large negative integers */ void acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec) { acb_t a; double cutoff; if (acb_is_int(s) && arf_cmpabs_2exp_si(arb_midref(acb_realref(s)), FLINT_BITS - 1) < 0) { acb_zeta_si(res, arf_get_si(arb_midref(acb_realref(s)), ARF_RND_DOWN), prec); return; } cutoff = 24.0 * prec * sqrt(prec); if (arf_cmpabs_d(arb_midref(acb_imagref(s)), cutoff) >= 0 && arf_cmpabs_d(arb_midref(acb_realref(s)), 10 + prec * 0.1) <= 0) { acb_dirichlet_zeta_rs(res, s, 0, prec); return; } acb_init(a); acb_one(a); if (arf_sgn(arb_midref(acb_realref(s))) < 0) { acb_t t, u, v; slong wp = prec + 6; acb_init(t); acb_init(u); acb_init(v); acb_sub_ui(t, s, 1, wp); /* 2 * (2pi)^(s-1) */ arb_const_pi(acb_realref(u), wp); acb_mul_2exp_si(u, u, 1); acb_pow(u, u, t, wp); acb_mul_2exp_si(u, u, 1); /* sin(pi*s/2) */ acb_mul_2exp_si(v, s, -1); acb_sin_pi(v, v, wp); acb_mul(u, u, v, wp); /* gamma(1-s) zeta(1-s) */ acb_neg(t, t); acb_gamma(v, t, wp); acb_mul(u, u, v, wp); acb_hurwitz_zeta(v, t, a, wp); acb_mul(res, u, v, prec); acb_clear(t); acb_clear(u); acb_clear(v); } else { acb_hurwitz_zeta(res, s, a, prec); } acb_clear(a); }
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_legendre_q_double(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); if (acb_is_int(m)) { acb_sub_ui(t, z, 1, prec); acb_mul_2exp_si(u, m, -1); acb_pow(v, t, u, prec); acb_neg(t, t); acb_neg(u, u); acb_pow(t, t, u, prec); acb_mul(t, t, v, prec); acb_hypgeom_legendre_q(u, n, m, z, 0, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(u, m, -1); if (!acb_is_int(u)) acb_neg(t, t); acb_sub_ui(u, z, 1, prec); acb_sqrt(u, u, prec); acb_sub_ui(v, z, 1, prec); acb_neg(v, v); acb_rsqrt(v, v, prec); acb_mul(u, u, v, prec); acb_hypgeom_legendre_p(v, n, m, z, 1, prec); acb_mul(u, u, v, prec); acb_const_pi(v, prec); acb_mul(u, u, v, prec); acb_mul_2exp_si(u, u, -1); acb_sub(res, t, u, prec); } else { acb_sub(t, n, m, prec); acb_add_ui(t, t, 1, prec); acb_mul_2exp_si(u, m, 1); acb_rising(t, t, u, prec); acb_neg(u, m); acb_hypgeom_legendre_p(u, n, u, z, 1, prec); acb_mul(t, t, u, prec); acb_hypgeom_legendre_p(u, n, m, z, 1, prec); acb_sub(t, u, t, prec); acb_exp_pi_i(u, m, prec); acb_mul(t, t, u, prec); acb_sin_pi(u, m, prec); acb_div(t, t, u, prec); acb_const_pi(u, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(t, t, -1); acb_set(res, t); } acb_clear(t); acb_clear(u); acb_clear(v); }
void acb_hypgeom_legendre_q(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec) { if (type == 0) { /* http://functions.wolfram.com/07.11.26.0033.01 */ /* todo: simplify the gamma quotients and the sqrt pi factor... */ acb_t a, b, c, z2, mn, nm, t, u; acb_init(a); acb_init(b); acb_init(c); acb_init(z2); acb_init(mn); acb_init(nm); acb_init(t); acb_init(u); acb_add(mn, m, n, prec); /* mn = m + n */ acb_sub(nm, n, m, prec); /* nm = n - m */ acb_mul(z2, z, z, prec); /* z2 = z^2 */ /* t = 2F1((1-m-n)/2, (n-m)/2+1, 3/2, z^2) */ acb_sub_ui(a, mn, 1, prec); acb_neg(a, a); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, nm, -1); acb_add_ui(b, b, 1, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_hypgeom_2f1(t, a, b, c, z2, 0, prec); /* u = 2F1(-(m+n)/2, (n-m+1)/2, 1/2, z^2) */ acb_neg(a, mn); acb_mul_2exp_si(a, a, -1); acb_add_ui(b, nm, 1, prec); acb_mul_2exp_si(b, b, -1); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_hypgeom_2f1(u, a, b, c, z2, 0, prec); /* a = cospi((m+n)/2) gamma((m+n)/2+1) rgamma((n-m+1)/2) z */ /* b = sinpi((m+n)/2) gamma((m+n+1)/2) rgamma((n-m)/2+1) / 2 */ acb_mul_2exp_si(a, mn, -1); acb_sin_cos_pi(b, a, a, prec); acb_mul_2exp_si(c, mn, -1); acb_add_ui(c, c, 1, prec); acb_gamma(c, c, prec); acb_mul(a, a, c, prec); acb_add_ui(c, nm, 1, prec); acb_mul_2exp_si(c, c, -1); acb_rgamma(c, c, prec); acb_mul(a, a, c, prec); acb_mul(a, a, z, prec); acb_add_ui(c, mn, 1, prec); acb_mul_2exp_si(c, c, -1); acb_gamma(c, c, prec); acb_mul(b, b, c, prec); acb_mul_2exp_si(c, nm, -1); acb_add_ui(c, c, 1, prec); acb_rgamma(c, c, prec); acb_mul(b, b, c, prec); acb_mul_2exp_si(b, b, -1); /* at - bu */ acb_mul(t, t, a, prec); acb_mul(u, u, b, prec); acb_sub(t, t, u, prec); /* prefactor sqrt(pi) 2^m (1-z^2)^(-m/2) */ if (!acb_is_zero(m)) { acb_sub_ui(u, z2, 1, prec); acb_neg(u, u); acb_neg(c, m); acb_mul_2exp_si(c, c, -1); acb_pow(u, u, c, prec); acb_set_ui(c, 2); acb_pow(c, c, m, prec); acb_mul(u, u, c, prec); acb_mul(t, t, u, prec); } arb_const_sqrt_pi(acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z2); acb_clear(mn); acb_clear(nm); acb_clear(t); acb_clear(u); } else if (type == 1) { if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -2) < 0) || !_acb_hypgeom_legendre_q_single_valid(z)) { _acb_hypgeom_legendre_q_double(res, n, m, z, prec); } else { _acb_hypgeom_legendre_q_single(res, n, m, z, prec); } } else { flint_printf("unsupported 'type' %d for legendre q\n", type); abort(); } }
int main() { slong iter; flint_rand_t state; flint_printf("bessel_i...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000; iter++) { acb_t nu, z, jv, iv, t; slong prec; acb_init(nu); acb_init(z); acb_init(jv); acb_init(iv); acb_init(t); prec = 2 + n_randint(state, 500); acb_randtest_param(nu, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(iv, nu, z, prec); break; case 1: acb_hypgeom_bessel_i_0f1(iv, nu, z, prec); break; default: acb_hypgeom_bessel_i(iv, nu, z, prec); } acb_mul_onei(t, z); acb_hypgeom_bessel_j(jv, nu, t, prec); acb_pow(t, z, nu, prec); acb_mul(jv, jv, t, prec); acb_mul_onei(t, z); acb_pow(t, t, nu, prec); acb_div(jv, jv, t, prec); if (!acb_overlaps(iv, jv)) { flint_printf("FAIL: consistency with bessel_j\n\n"); flint_printf("nu = "); acb_printd(nu, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("iv = "); acb_printd(iv, 30); flint_printf("\n\n"); flint_printf("jv = "); acb_printd(jv, 30); flint_printf("\n\n"); abort(); } acb_clear(nu); acb_clear(z); acb_clear(jv); acb_clear(iv); acb_clear(t); } for (iter = 0; iter < 2000; iter++) { acb_t nu0, nu1, nu2, z, w0, w1, w2, t, u; slong prec0, prec1, prec2; acb_init(nu0); acb_init(nu1); acb_init(nu2); acb_init(z); acb_init(w0); acb_init(w1); acb_init(w2); acb_init(t); acb_init(u); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest_param(nu0, 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_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_sub_ui(nu1, nu0, 1, prec0); acb_sub_ui(nu2, nu0, 2, prec0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w0, nu0, z, prec0); break; case 1: acb_hypgeom_bessel_i_0f1(w0, nu0, z, prec0); break; default: acb_hypgeom_bessel_i(w0, nu0, z, prec0); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w1, nu0, z, prec1); break; case 1: acb_hypgeom_bessel_i_0f1(w1, nu0, z, prec1); break; default: acb_hypgeom_bessel_i(w1, nu0, z, prec1); } if (!acb_overlaps(w0, w1)) { flint_printf("FAIL: consistency\n\n"); flint_printf("nu = "); acb_printd(nu0, 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"); abort(); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w1, nu1, z, prec1); break; case 1: acb_hypgeom_bessel_i_0f1(w1, nu1, z, prec1); break; default: acb_hypgeom_bessel_i(w1, nu1, z, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w2, nu2, z, prec2); break; case 1: acb_hypgeom_bessel_i_0f1(w2, nu2, z, prec2); break; default: acb_hypgeom_bessel_i(w2, nu2, z, prec2); } acb_mul(t, w1, nu1, prec0); acb_mul_2exp_si(t, t, 1); acb_submul(t, w2, z, prec0); acb_addmul(t, w0, z, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL: contiguous relation\n\n"); flint_printf("nu = "); acb_printd(nu0, 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("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); abort(); } acb_neg(t, nu0); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w2, t, z, prec2); break; case 1: acb_hypgeom_bessel_i_0f1(w2, t, z, prec2); break; default: acb_hypgeom_bessel_i(w2, t, z, prec2); } acb_mul(w1, w1, w2, prec2); acb_neg(t, nu1); switch (n_randint(state, 3)) { case 0: acb_hypgeom_bessel_i_asymp(w2, t, z, prec2); break; case 1: acb_hypgeom_bessel_i_0f1(w2, t, z, prec2); break; default: acb_hypgeom_bessel_i(w2, t, z, prec2); } acb_mul(w0, w0, w2, prec2); acb_sub(w0, w1, w0, prec2); acb_sin_pi(t, nu0, prec2); acb_const_pi(u, prec2); acb_mul(u, u, z, prec2); acb_div(t, t, u, prec2); acb_mul_2exp_si(t, t, 1); if (!acb_overlaps(w0, t)) { flint_printf("FAIL: wronskian\n\n"); flint_printf("nu = "); acb_printd(nu0, 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("t = "); acb_printd(t, 30); flint_printf("\n\n"); abort(); } acb_clear(nu0); acb_clear(nu1); acb_clear(nu2); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(w2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_hypgeom_2f1_transform_nolimit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) { acb_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s; if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z))) { acb_indeterminate(res); return; } if (!regularized) { acb_init(t); acb_gamma(t, c, prec); acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, 1, which, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } acb_init(ba); acb_init(ca); acb_init(cb); acb_init(cab); acb_init(ac1); acb_init(bc1); acb_init(ab1); acb_init(ba1); acb_init(w); acb_init(t); acb_init(u); acb_init(v); acb_init(s); acb_add_si(s, z, -1, prec); /* s = 1 - z */ acb_neg(s, s); acb_sub(ba, b, a, prec); /* ba = b - a */ acb_sub(ca, c, a, prec); /* ca = c - a */ acb_sub(cb, c, b, prec); /* cb = c - b */ acb_sub(cab, ca, b, prec); /* cab = c - a - b */ acb_add_si(ac1, ca, -1, prec); acb_neg(ac1, ac1); /* ac1 = a - c + 1 */ acb_add_si(bc1, cb, -1, prec); acb_neg(bc1, bc1); /* bc1 = b - c + 1 */ acb_add_si(ab1, ba, -1, prec); acb_neg(ab1, ab1); /* ab1 = a - b + 1 */ acb_add_si(ba1, ba, 1, prec); /* ba1 = b - a + 1 */ /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */ if (which == 2) { acb_inv(w, z, prec); /* w = 1/z */ acb_hypgeom_2f1_direct(t, a, ac1, ab1, w, 1, prec); acb_hypgeom_2f1_direct(u, b, bc1, ba1, w, 1, prec); } else if (which == 3) { acb_inv(w, s, prec); /* w = 1/(1-z) */ acb_hypgeom_2f1_direct(t, a, cb, ab1, w, 1, prec); acb_hypgeom_2f1_direct(u, b, ca, ba1, w, 1, prec); } else if (which == 4) { acb_set(w, s); /* w = 1-z */ acb_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_direct(t, a, b, v, w, 1, prec); acb_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_hypgeom_2f1_direct(u, ca, cb, v, w, 1, prec); } else if (which == 5) { acb_inv(w, z, prec); /* w = 1-1/z */ acb_neg(w, w); acb_add_si(w, w, 1, prec); acb_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_direct(t, a, ac1, v, w, 1, prec); acb_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_add_si(u, a, -1, prec); /* u = 1-a */ acb_neg(u, u); acb_hypgeom_2f1_direct(u, ca, u, v, w, 1, prec); } else { flint_printf("invalid transformation!\n"); flint_abort(); } /* gamma factors */ acb_rgamma(v, a, prec); acb_mul(u, u, v, prec); acb_rgamma(v, ca, prec); acb_mul(t, t, v, prec); acb_rgamma(v, b, prec); if (which == 2 || which == 3) acb_mul(t, t, v, prec); else acb_mul(u, u, v, prec); acb_rgamma(v, cb, prec); if (which == 2 || which == 3) acb_mul(u, u, v, prec); else acb_mul(t, t, v, prec); if (which == 2 || which == 3) { if (which == 2) acb_neg(s, z); /* -z, otherwise 1-z since before */ acb_neg(v, a); acb_pow(v, s, v, prec); acb_mul(t, t, v, prec); acb_neg(v, b); acb_pow(v, s, v, prec); acb_mul(u, u, v, prec); } else { acb_pow(v, s, cab, prec); acb_mul(u, u, v, prec); if (which == 5) { acb_neg(v, a); acb_pow(v, z, v, prec); acb_mul(t, t, v, prec); acb_neg(v, ca); acb_pow(v, z, v, prec); acb_mul(u, u, v, prec); } } acb_sub(t, t, u, prec); if (which == 2 || which == 3) acb_sin_pi(v, ba, prec); else acb_sin_pi(v, cab, prec); acb_div(t, t, v, prec); acb_const_pi(v, prec); acb_mul(t, t, v, prec); acb_set(res, t); acb_clear(ba); acb_clear(ca); acb_clear(cb); acb_clear(cab); acb_clear(ac1); acb_clear(bc1); acb_clear(ab1); acb_clear(ba1); acb_clear(w); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(s); }
void acb_dirichlet_l(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { if (!acb_is_finite(s)) { acb_indeterminate(res); } else if (G == NULL || G->q == 1) { acb_dirichlet_zeta(res, s, prec); } else if (dirichlet_char_is_primitive(G, chi) && (arf_cmp_d(arb_midref(acb_realref(s)), -0.5) < 0 || (G->q != 1 && dirichlet_parity_char(G, chi) == 0 && arf_cmpabs_d(arb_midref(acb_imagref(s)), 0.125) < 0 && arf_cmp_d(arb_midref(acb_realref(s)), 0.125) < 0))) { /* use functional equation */ acb_t t, u, v; int parity; ulong q; parity = dirichlet_parity_char(G, chi); q = G->q; acb_init(t); acb_init(u); acb_init(v); /* gamma((1-s+p)/2) / gamma((s+p)/2) */ acb_add_ui(t, s, parity, prec); acb_mul_2exp_si(t, t, -1); acb_rgamma(t, t, prec); if (!acb_is_zero(t)) /* assumes q != 1 when s = 0 */ { acb_neg(u, s); acb_add_ui(u, u, 1 + parity, prec); acb_mul_2exp_si(u, u, -1); acb_gamma(u, u, prec); acb_mul(t, t, u, prec); /* epsilon */ acb_dirichlet_root_number(u, G, chi, prec); acb_mul(t, t, u, prec); /* (pi/q)^(s-1/2) */ acb_const_pi(u, prec); acb_div_ui(u, u, q, prec); acb_set_d(v, -0.5); acb_add(v, v, s, prec); acb_pow(u, u, v, prec); acb_mul(t, t, u, prec); acb_sub_ui(u, s, 1, prec); acb_neg(u, u); acb_conj(u, u); acb_dirichlet_l_general(u, u, G, chi, prec); acb_conj(u, u); acb_mul(t, t, u, prec); if (dirichlet_char_is_real(G, chi) && acb_is_real(s)) arb_zero(acb_imagref(t)); } acb_set(res, t); acb_clear(t); acb_clear(u); acb_clear(v); } else { acb_dirichlet_l_general(res, s, G, chi, prec); } }
int main() { slong iter; flint_rand_t state; flint_printf("pow...."); fflush(stdout); flint_randinit(state); /* check large arguments */ for (iter = 0; iter < 20000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); acb_randtest(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); if (n_randint(state, 4) == 0) arb_zero(acb_imagref(a)); acb_randtest(b, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); if (n_randint(state, 4) == 0) arb_zero(acb_imagref(b)); acb_pow(c, a, b, prec1); acb_pow(d, a, b, prec2); if (!acb_overlaps(c, d)) { flint_printf("FAIL: overlap\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"); flint_abort(); } acb_randtest(c, state, 1 + n_randint(state, 1000), 200); /* check a^(b+c) = a^b*a^c */ acb_add(e, b, c, prec1); acb_pow(d, a, e, prec1); acb_pow(e, a, b, prec1); acb_pow(f, a, c, prec1); acb_mul(e, e, f, prec1); if (!acb_overlaps(d, e)) { flint_printf("FAIL: functional equation\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"); flint_printf("e = "); acb_print(e); flint_printf("\n\n"); flint_abort(); } acb_pow(c, a, b, prec1); acb_set(d, a); acb_pow(d, d, b, prec2); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing 1\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"); flint_abort(); } acb_set(d, b); acb_pow(d, a, d, prec2); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing 2\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"); flint_abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_hypgeom_2f1_transform(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, int which, slong prec) { int regularized; regularized = flags & ACB_HYPGEOM_2F1_REGULARIZED; if (which == 1) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_sub_ui(t, z, 1, prec); /* t = z-1 */ acb_div(u, z, t, prec); /* u = z/(z-1) */ acb_neg(t, t); acb_neg(v, a); acb_pow(t, t, v, prec); /* t = (1-z)^-a */ acb_sub(v, c, b, prec); /* v = c-b */ /* We cannot use regularized=1 directly, since if c is a nonnegative integer, the transformation formula reads (lhs) * 0 = (rhs) * 0. */ acb_hypgeom_2f1_direct(u, a, v, c, u, 1, prec); if (!regularized) { acb_gamma(v, c, prec); acb_mul(u, u, v, prec); } acb_mul(res, u, t, prec); acb_clear(t); acb_clear(u); acb_clear(v); } else { acb_t d; int limit; acb_init(d); if (which == 2 || which == 3) { if (flags & ACB_HYPGEOM_2F1_AB) { limit = 1; } else { acb_sub(d, b, a, prec); limit = acb_is_int(d); } } else { if (flags & ACB_HYPGEOM_2F1_ABC) { limit = 1; } else { acb_sub(d, c, a, prec); acb_sub(d, d, b, prec); limit = acb_is_int(d); } } if (limit) acb_hypgeom_2f1_transform_limit(res, a, b, c, z, regularized, which, prec); else acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, regularized, which, prec); acb_clear(d); } if (!acb_is_finite(res)) acb_indeterminate(res); }