void acb_tan_pi(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_tan_pi(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_t t; arb_init(t); arb_const_pi(t, prec + 4); arb_mul(t, acb_imagref(z), t, prec + 4); arb_tanh(acb_imagref(r), t, prec); arb_zero(acb_realref(r)); arb_clear(t); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos_pi(r, t, z, prec + 4); acb_div(r, r, t, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_exp_pi_i(t, t, prec + 4); acb_add_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); } else { acb_neg(t, t); acb_exp_pi_i(t, t, prec + 4); acb_add_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); } } acb_clear(t); } }
void acb_hypgeom_bessel_i_asymp_prefactors(acb_t A, acb_t B, acb_t C, const acb_t nu, const acb_t z, long prec) { acb_t t, u; acb_init(t); acb_init(u); /* C = (2 pi z)^(-1/2) */ acb_const_pi(C, prec); acb_mul_2exp_si(C, C, 1); acb_mul(C, C, z, prec); acb_rsqrt(C, C, prec); if (arb_is_positive(acb_imagref(z)) || (arb_is_zero(acb_imagref(z)) && arb_is_negative(acb_realref(z)))) { acb_exp_pi_i(t, nu, prec); acb_mul_onei(t, t); } else if (arb_is_negative(acb_imagref(z)) || (arb_is_zero(acb_imagref(z)) && arb_is_positive(acb_realref(z)))) { acb_neg(t, nu); acb_exp_pi_i(t, t, prec); acb_mul_onei(t, t); acb_neg(t, t); } else { acb_exp_pi_i(t, nu, prec); acb_mul_onei(t, t); acb_neg(u, nu); acb_exp_pi_i(u, u, prec); acb_mul_onei(u, u); acb_neg(u, u); arb_union(acb_realref(t), acb_realref(t), acb_realref(u), prec); arb_union(acb_imagref(t), acb_imagref(t), acb_imagref(u), prec); } acb_exp_invexp(B, A, z, prec); acb_mul(A, A, t, prec); acb_clear(t); acb_clear(u); }
void acb_modular_lambda(acb_t r, const acb_t tau, long prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, q; acb_struct thetas[4]; int R[4], S[4], C; int Rsum, qpower; psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(q); acb_init(thetas + 0); acb_init(thetas + 1); acb_init(thetas + 2); acb_init(thetas + 3); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_modular_theta_transform(R, S, &C, g); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(thetas + 1, thetas + 2, thetas + 3, q, prec); acb_zero(thetas + 0); /* divide the transformation factors */ Rsum = 4 * (R[1] - R[2]); /* possible factor [q^(+/- 1/4)]^4 needed for theta_1^4 or theta_2^4 */ qpower = (S[1] == 0 || S[1] == 1) - (S[2] == 0 || S[2] == 1); acb_div(r, thetas + S[1], thetas + S[2], prec); acb_mul(r, r, r, prec); acb_mul(r, r, r, prec); if ((Rsum & 7) == 4) acb_neg(r, r); if (qpower == 1) acb_mul(r, r, q, prec); else if (qpower == -1) acb_div(r, r, q, prec); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(q); acb_clear(thetas + 0); acb_clear(thetas + 1); acb_clear(thetas + 2); acb_clear(thetas + 3); }
void acb_modular_delta(acb_t z, const acb_t tau, long prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, t1, t2, t3, t4, q; psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(t1); acb_init(t2); acb_init(t3); acb_init(t4); acb_init(q); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(t2, t3, t4, q, prec); /* (t2 t3 t4) ^ 8 * q^2 */ acb_mul(t1, t2, t3, prec); acb_mul(t1, t1, t4, prec); acb_mul(t1, t1, t1, prec); acb_mul(t1, t1, t1, prec); acb_mul(t1, t1, q, prec); acb_mul(t1, t1, t1, prec); acb_mul_2exp_si(t1, t1, -8); if (!fmpz_is_zero(&g->c)) { acb_mul_fmpz(t2, tau, &g->c, prec); acb_add_fmpz(t2, t2, &g->d, prec); acb_pow_ui(t2, t2, 12, prec); acb_div(t1, t1, t2, prec); } acb_set(z, t1); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(t1); acb_clear(t2); acb_clear(t3); acb_clear(t4); acb_clear(q); }
acb_t *fft_init(long n,long prec) { long i,halfn,*base; acb_t *x,*w; base = (long *)malloc(2*sizeof(long)+3*n/2*sizeof(acb_t)); if (!base) return (acb_t *)0; base[0] = n; base[1] = prec; x = (acb_t *)&base[2]; w = x+n; halfn = n>>1; for (i=0;i<n;i++) acb_init(x[i]); for (i=0;i<halfn;i++) { acb_init(w[i]); acb_set_ui(w[i],i); acb_div_ui(w[i],w[i],halfn,prec); acb_exp_pi_i(w[i],w[i],prec); } return x; }
void acb_modular_eisenstein(acb_ptr r, const acb_t tau, slong len, slong prec) { psl2z_t g; arf_t one_minus_eps; acb_t tau_prime, t1, t2, t3, t4, q; slong m, n; if (len < 1) return; psl2z_init(g); arf_init(one_minus_eps); acb_init(tau_prime); acb_init(t1); acb_init(t2); acb_init(t3); acb_init(t4); acb_init(q); arf_set_ui_2exp_si(one_minus_eps, 63, -6); acb_modular_fundamental_domain_approx(tau_prime, g, tau, one_minus_eps, prec); acb_exp_pi_i(q, tau_prime, prec); acb_modular_theta_const_sum(t2, t3, t4, q, prec); /* fourth powers of the theta functions (a, b, c) */ acb_mul(t2, t2, t2, prec); acb_mul(t2, t2, t2, prec); acb_mul(t2, t2, q, prec); acb_mul(t3, t3, t3, prec); acb_mul(t3, t3, t3, prec); acb_mul(t4, t4, t4, prec); acb_mul(t4, t4, t4, prec); /* c2 = pi^4 * (a^8 + b^8 + c^8) / 30 */ /* c3 = pi^6 * (b^12 + c^12 - 3a^8 * (b^4+c^4)) / 180 */ /* r = a^8 */ acb_mul(r, t2, t2, prec); if (len > 1) { /* r[1] = -3 a^8 * (b^4 + c^4) */ acb_add(r + 1, t3, t4, prec); acb_mul(r + 1, r + 1, r, prec); acb_mul_si(r + 1, r + 1, -3, prec); } /* b^8 */ acb_mul(t1, t3, t3, prec); acb_add(r, r, t1, prec); /* b^12 */ if (len > 1) acb_addmul(r + 1, t1, t3, prec); /* c^8 */ acb_mul(t1, t4, t4, prec); acb_add(r, r, t1, prec); /* c^12 */ if (len > 1) acb_addmul(r + 1, t1, t4, prec); acb_const_pi(t1, prec); acb_mul(t1, t1, t1, prec); acb_mul(t2, t1, t1, prec); acb_mul(r, r, t2, prec); acb_div_ui(r, r, 30, prec); if (len > 1) { acb_mul(t2, t2, t1, prec); acb_mul(r + 1, r + 1, t2, prec); acb_div_ui(r + 1, r + 1, 189, prec); } /* apply modular transformation */ if (!fmpz_is_zero(&g->c)) { acb_mul_fmpz(t1, tau, &g->c, prec); acb_add_fmpz(t1, t1, &g->d, prec); acb_inv(t1, t1, prec); acb_mul(t1, t1, t1, prec); acb_mul(t2, t1, t1, prec); acb_mul(r, r, t2, prec); if (len > 1) { acb_mul(t2, t1, t2, prec); acb_mul(r + 1, r + 1, t2, prec); } } /* compute more coefficients using recurrence */ for (n = 4; n < len + 2; n++) { acb_zero(r + n - 2); m = 2; for (m = 2; m * 2 < n; m++) acb_addmul(r + n - 2, r + m - 2, r + n - m - 2, prec); acb_mul_2exp_si(r + n - 2, r + n - 2, 1); if (n % 2 == 0) acb_addmul(r + n - 2, r + n / 2 - 2, r + n / 2 - 2, prec); acb_mul_ui(r + n - 2, r + n - 2, 3, prec); acb_div_ui(r + n - 2, r + n - 2, (2 * n + 1) * (n - 3), prec); } /* convert c's to G's */ for (n = 0; n < len; n++) acb_div_ui(r + n, r + n, 2 * n + 3, prec); psl2z_clear(g); arf_clear(one_minus_eps); acb_clear(tau_prime); acb_clear(t1); acb_clear(t2); acb_clear(t3); acb_clear(t4); acb_clear(q); }
int main() { slong iter; flint_rand_t state; flint_printf("theta_sum...."); fflush(stdout); flint_randinit(state); /* Very weak test, just testing the error bounds and not that we compute the right functions */ for (iter = 0; iter < 10000; iter++) { acb_ptr t1a, t1b, t2a, t2b, t3a, t3b, t4a, t4b; acb_t w, q; int w_is_unit; slong prec0, e0, prec1, prec2, len1, len2, i; acb_init(w); acb_init(q); e0 = 1 + n_randint(state, 100); prec0 = 2 + n_randint(state, 3000); prec1 = 2 + n_randint(state, 3000); prec2 = 2 + n_randint(state, 3000); len1 = 1 + n_randint(state, 30); len2 = 1 + n_randint(state, 30); t1a = _acb_vec_init(len1); t2a = _acb_vec_init(len1); t3a = _acb_vec_init(len1); t4a = _acb_vec_init(len1); t1b = _acb_vec_init(len2); t2b = _acb_vec_init(len2); t3b = _acb_vec_init(len2); t4b = _acb_vec_init(len2); if (n_randint(state, 2)) { arb_randtest(acb_realref(q), state, prec0, e0); arb_zero(acb_imagref(q)); acb_exp_pi_i(w, q, prec0); w_is_unit = n_randint(state, 2); } else { acb_randtest(w, state, prec0, e0); w_is_unit = 0; } acb_randtest(q, state, prec0, e0); for (i = 0; i < len1; i++) { acb_randtest(t1a + i, state, prec0, e0); acb_randtest(t2a + i, state, prec0, e0); acb_randtest(t3a + i, state, prec0, e0); acb_randtest(t4a + i, state, prec0, e0); } for (i = 0; i < len2; i++) { acb_randtest(t1b + i, state, prec0, e0); acb_randtest(t2b + i, state, prec0, e0); acb_randtest(t3b + i, state, prec0, e0); acb_randtest(t4b + i, state, prec0, e0); } acb_modular_theta_sum(t1a, t2a, t3a, t4a, w, w_is_unit, q, len1, prec1); acb_modular_theta_sum(t1b, t2b, t3b, t4b, w, w_is_unit & n_randint(state, 2), q, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(t1a + i, t1b + i) || !acb_overlaps(t2a + i, t2b + i) || !acb_overlaps(t3a + i, t3b + i) || !acb_overlaps(t4a + i, t4b + i)) { flint_printf("FAIL (overlap) iter = %wd\n", iter); flint_printf("len1 = %wd, len2 = %wd, prec1 = %wd, prec2 = %wd\n\n", len1, len2, prec1, prec2); flint_printf("i = %wd\n\n", i); flint_printf("q = "); acb_printd(q, 50); flint_printf("\n\n"); flint_printf("w = "); acb_printd(w, 50); flint_printf("\n\n"); flint_printf("t1a = "); acb_printd(t1a + i, 50); flint_printf("\n\n"); flint_printf("t1b = "); acb_printd(t1b + i, 50); flint_printf("\n\n"); flint_printf("t2a = "); acb_printd(t2a + i, 50); flint_printf("\n\n"); flint_printf("t2b = "); acb_printd(t2b + i, 50); flint_printf("\n\n"); flint_printf("t3a = "); acb_printd(t3a + i, 50); flint_printf("\n\n"); flint_printf("t3b = "); acb_printd(t3b + i, 50); flint_printf("\n\n"); flint_printf("t4a = "); acb_printd(t4a + i, 50); flint_printf("\n\n"); flint_printf("t4b = "); acb_printd(t4b + i, 50); flint_printf("\n\n"); abort(); } } _acb_vec_clear(t1a, len1); _acb_vec_clear(t2a, len1); _acb_vec_clear(t3a, len1); _acb_vec_clear(t4a, len1); _acb_vec_clear(t1b, len2); _acb_vec_clear(t2b, len2); _acb_vec_clear(t3b, len2); _acb_vec_clear(t4b, len2); acb_clear(w); acb_clear(q); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { long iter; flint_rand_t state; printf("legendre_q...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { acb_t n, m, z, res1, res2; long prec1, prec2, ebits; acb_init(n); acb_init(m); acb_init(z); acb_init(res1); acb_init(res2); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 10); if (n_randint(state, 2)) { acb_set_si(m, n_randint(state, 20) - 10); acb_set_si(n, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), ebits); acb_randtest_param(m, state, 1 + n_randint(state, 400), ebits); } acb_randtest_param(z, state, 1 + n_randint(state, 400), ebits); _acb_hypgeom_legendre_q_single(res1, n, m, z, prec1); _acb_hypgeom_legendre_q_double(res2, n, m, z, prec2); if (!acb_overlaps(res1, res2)) { printf("FAIL: consistency 1\n\n"); printf("iter = %ld, prec1 = %ld, prec2 = %ld\n\n", iter, prec1, prec2); printf("m = "); acb_printd(m, 30); printf("\n\n"); printf("n = "); acb_printd(n, 30); printf("\n\n"); printf("z = "); acb_printd(z, 30); printf("\n\n"); printf("res1 = "); acb_printd(res1, 30); printf("\n\n"); printf("res2 = "); acb_printd(res2, 30); printf("\n\n"); abort(); } acb_clear(n); acb_clear(m); acb_clear(z); acb_clear(res1); acb_clear(res2); } for (iter = 0; iter < 2000; iter++) { acb_t n, m, z, res1, res2, t, u; long prec1, prec2, ebits; int type; acb_init(n); acb_init(m); acb_init(z); acb_init(res1); acb_init(res2); acb_init(t); acb_init(u); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); ebits = 1 + n_randint(state, 10); if (n_randint(state, 2)) { acb_set_si(m, n_randint(state, 20) - 10); acb_set_si(n, n_randint(state, 20) - 10); } else { acb_randtest_param(n, state, 1 + n_randint(state, 400), ebits); acb_randtest_param(m, state, 1 + n_randint(state, 400), ebits); } acb_randtest_param(z, state, 1 + n_randint(state, 400), ebits); type = n_randint(state, 2); acb_hypgeom_legendre_q(res1, n, m, z, type, prec1); acb_neg(t, m); acb_hypgeom_legendre_p(res2, n, t, z, type, prec2); acb_add(u, m, n, prec2); acb_add_ui(u, u, 1, prec2); acb_gamma(u, u, prec2); acb_mul(res2, res2, u, prec2); acb_sub(u, n, m, prec2); acb_add_ui(u, u, 1, prec2); acb_rgamma(u, u, prec2); acb_mul(res2, res2, u, prec2); acb_hypgeom_legendre_p(t, n, m, z, type, prec2); if (type == 0) { acb_cos_pi(u, m, prec2); acb_mul(t, t, u, prec2); } acb_sub(res2, t, res2, prec2); if (type == 1) { acb_exp_pi_i(t, m, prec2); acb_mul(res2, res2, t, prec2); } acb_sin_pi(t, m, prec2); if (acb_contains_zero(t)) acb_indeterminate(res2); else acb_div(res2, res2, t, prec2); acb_const_pi(t, prec2); acb_mul(res2, res2, t, prec2); acb_mul_2exp_si(res2, res2, -1); if (!acb_overlaps(res1, res2)) { printf("FAIL: consistency 2\n\n"); printf("iter = %ld, prec1 = %ld, prec2 = %ld\n\n", iter, prec1, prec2); printf("type = %d\n\n", type); printf("m = "); acb_printd(m, 30); printf("\n\n"); printf("n = "); acb_printd(n, 30); printf("\n\n"); printf("z = "); acb_printd(z, 30); printf("\n\n"); printf("res1 = "); acb_printd(res1, 30); printf("\n\n"); printf("res2 = "); acb_printd(res2, 30); printf("\n\n"); abort(); } acb_clear(n); acb_clear(m); acb_clear(z); acb_clear(res1); acb_clear(res2); acb_clear(t); acb_clear(u); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
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_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_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); }
static void acb_log_sin_pi_half(acb_t res, const acb_t z, slong prec, int upper) { acb_t t, u, zmid; arf_t n; arb_t pi; acb_init(t); acb_init(u); acb_init(zmid); arf_init(n); arb_init(pi); arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z))); arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z))); arf_floor(n, arb_midref(acb_realref(zmid))); arb_sub_arf(acb_realref(zmid), acb_realref(zmid), n, prec); arb_const_pi(pi, prec); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(zmid)), 2) < 1) { acb_sin_pi(t, zmid, prec); acb_log(t, t, prec); } else /* i*pi*(z-0.5) + log((1-exp(-2i*pi*z))/2) */ { acb_mul_2exp_si(t, zmid, 1); acb_neg(t, t); if (upper) acb_conj(t, t); acb_exp_pi_i(t, t, prec); acb_sub_ui(t, t, 1, prec); acb_neg(t, t); acb_mul_2exp_si(t, t, -1); acb_log(t, t, prec); acb_one(u); acb_mul_2exp_si(u, u, -1); acb_sub(u, zmid, u, prec); if (upper) acb_conj(u, u); acb_mul_onei(u, u); acb_addmul_arb(t, u, pi, prec); if (upper) acb_conj(t, t); } if (upper) arb_submul_arf(acb_imagref(t), pi, n, prec); else arb_addmul_arf(acb_imagref(t), pi, n, prec); /* propagated error bound from the derivative pi cot(pi z) */ if (!acb_is_exact(z)) { mag_t zm, um; mag_init(zm); mag_init(um); acb_cot_pi(u, z, prec); acb_mul_arb(u, u, pi, prec); mag_hypot(zm, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z))); acb_get_mag(um, u); mag_mul(um, um, zm); acb_add_error_mag(t, um); mag_clear(zm); mag_clear(um); } acb_set(res, t); acb_clear(t); acb_clear(u); acb_clear(zmid); arf_clear(n); arb_clear(pi); }
int main() { slong iter; flint_rand_t state; flint_printf("j...."); fflush(stdout); flint_randinit(state); /* Test SL2Z invariance */ for (iter = 0; iter < 10000; iter++) { acb_t tau1, tau2, z1, z2; slong e0, prec0, prec1, prec2; psl2z_t g; psl2z_init(g); acb_init(tau1); acb_init(tau2); acb_init(z1); acb_init(z2); e0 = 1 + n_randint(state, 100); prec0 = 2 + n_randint(state, 2000); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); acb_randtest(tau1, state, prec0, e0); acb_randtest(tau2, state, prec0, e0); acb_randtest(z1, state, prec0, e0); acb_randtest(z2, state, prec0, e0); psl2z_randtest(g, state, 1 + n_randint(state, 200)); acb_modular_transform(tau2, g, tau1, prec0); acb_modular_j(z1, tau1, prec1); acb_modular_j(z2, tau2, prec2); if (!acb_overlaps(z1, z2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau1 = "); acb_print(tau1); flint_printf("\n\n"); flint_printf("tau2 = "); acb_print(tau2); flint_printf("\n\n"); flint_printf("z1 = "); acb_print(z1); flint_printf("\n\n"); flint_printf("z2 = "); acb_print(z2); flint_printf("\n\n"); abort(); } acb_modular_j(tau1, tau1, prec2); if (!acb_overlaps(z1, tau1)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau1 = "); acb_print(tau1); flint_printf("\n\n"); flint_printf("tau2 = "); acb_print(tau2); flint_printf("\n\n"); flint_printf("z1 = "); acb_print(z1); flint_printf("\n\n"); flint_printf("z2 = "); acb_print(z2); flint_printf("\n\n"); abort(); } acb_clear(tau1); acb_clear(tau2); acb_clear(z1); acb_clear(z2); psl2z_clear(g); } /* Test special values */ for (iter = 0; iter < 100; iter++) { acb_t tau, z; slong prec; acb_init(tau); acb_init(z); prec = 2 + n_randint(state, 2000); acb_randtest(z, state, prec, 10); acb_onei(tau); acb_modular_j(z, tau, prec); acb_sub_ui(z, z, 1728, prec); if (!acb_contains_zero(z)) { flint_printf("FAIL (value 1)\n"); flint_printf("tau = "); acb_print(tau); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); abort(); } acb_set_ui(tau, 2); acb_div_ui(tau, tau, 3, prec); acb_exp_pi_i(tau, tau, prec); acb_modular_j(z, tau, prec); if (!acb_contains_zero(z)) { flint_printf("FAIL (value 2)\n"); flint_printf("tau = "); acb_print(tau); flint_printf("\n\n"); flint_printf("z = "); acb_print(z); flint_printf("\n\n"); abort(); } acb_clear(tau); acb_clear(z); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }