void acb_lambertw_initial_asymp(acb_t w, const acb_t z, const fmpz_t k, slong prec) { acb_t L1, L2, t; acb_init(L1); acb_init(L2); acb_init(t); acb_const_pi(L2, prec); acb_mul_2exp_si(L2, L2, 1); acb_mul_fmpz(L2, L2, k, prec); acb_mul_onei(L2, L2); acb_log(L1, z, prec); acb_add(L1, L1, L2, prec); acb_log(L2, L1, prec); /* L1 - L2 + L2/L1 + L2(L2-2)/(2 L1^2) */ acb_inv(t, L1, prec); acb_mul_2exp_si(w, L2, 1); acb_submul(w, L2, L2, prec); acb_neg(w, w); acb_mul(w, w, t, prec); acb_mul_2exp_si(w, w, -1); acb_add(w, w, L2, prec); acb_mul(w, w, t, prec); acb_sub(w, w, L2, prec); acb_add(w, w, L1, prec); acb_clear(L1); acb_clear(L2); acb_clear(t); }
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); }
int main() { slong iter; flint_rand_t state; flint_printf("eisenstein...."); fflush(stdout); flint_randinit(state); /* Test functional equation */ for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t tau1, tau2, t; acb_ptr r1, r2; slong e0, prec0, prec1, prec2, len1, len2, i; psl2z_t g; psl2z_init(g); acb_init(tau1); acb_init(tau2); acb_init(t); e0 = 1 + n_randint(state, 200); prec0 = 2 + n_randint(state, 2000); prec1 = 2 + n_randint(state, 2000); prec2 = 2 + n_randint(state, 2000); len1 = n_randint(state, 20); len2 = n_randint(state, 20); r1 = _acb_vec_init(len1); r2 = _acb_vec_init(len2); acb_randtest(tau1, state, prec0, e0); acb_randtest(tau2, state, prec0, e0); psl2z_randtest(g, state, 1 + n_randint(state, 200)); acb_modular_transform(tau2, g, tau1, prec0); acb_modular_eisenstein(r1, tau1, len1, prec1); acb_modular_eisenstein(r2, tau2, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { acb_mul_fmpz(t, tau1, &g->c, prec1); acb_add_fmpz(t, t, &g->d, prec1); acb_pow_ui(t, t, 2 * i + 4, prec1); acb_mul(t, t, r1 + i, prec1); if (!acb_overlaps(t, r2 + i)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau1 = "); acb_printd(tau1, 15); flint_printf("\n\n"); flint_printf("tau2 = "); acb_printd(tau2, 15); flint_printf("\n\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1 + i, 15); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2 + i, 15); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 15); flint_printf("\n\n"); flint_abort(); } } acb_clear(tau1); acb_clear(tau2); acb_clear(t); _acb_vec_clear(r1, len1); _acb_vec_clear(r2, len2); psl2z_clear(g); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
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); }
/* todo: use log(1-z) when this is better? would also need to adjust strategy in the main function */ void acb_hypgeom_dilog_bernoulli(acb_t res, const acb_t z, slong prec) { acb_t s, w, w2; slong n, k; fmpz_t c, d; mag_t m, err; double lm; int real; acb_init(s); acb_init(w); acb_init(w2); fmpz_init(c); fmpz_init(d); mag_init(m); mag_init(err); real = 0; if (acb_is_real(z)) { arb_sub_ui(acb_realref(w), acb_realref(z), 1, 30); real = arb_is_nonpositive(acb_realref(w)); } acb_log(w, z, prec); acb_get_mag(m, w); /* for k >= 4, the terms are bounded by (|w| / (2 pi))^k */ mag_set_ui_2exp_si(err, 2670177, -24); /* upper bound for 1/(2pi) */ mag_mul(err, err, m); lm = mag_get_d_log2_approx(err); if (lm < -0.25) { n = prec / (-lm) + 1; n = FLINT_MAX(n, 4); mag_geom_series(err, err, n); BERNOULLI_ENSURE_CACHED(n) acb_mul(w2, w, w, prec); for (k = n - (n % 2 == 0); k >= 3; k -= 2) { fmpz_mul_ui(c, fmpq_denref(bernoulli_cache + k - 1), k - 1); fmpz_mul_ui(d, c, (k + 1) * (k + 2)); acb_mul(s, s, w2, prec); acb_mul_fmpz(s, s, c, prec); fmpz_mul_ui(c, fmpq_numref(bernoulli_cache + k - 1), (k + 1) * (k + 2)); acb_sub_fmpz(s, s, c, prec); acb_div_fmpz(s, s, d, prec); } acb_mul(s, s, w, prec); acb_mul_2exp_si(s, s, 1); acb_sub_ui(s, s, 3, prec); acb_mul(s, s, w2, prec); acb_mul_2exp_si(s, s, -1); acb_const_pi(w2, prec); acb_addmul(s, w2, w2, prec); acb_div_ui(s, s, 6, prec); acb_neg(w2, w); acb_log(w2, w2, prec); acb_submul(s, w2, w, prec); acb_add(res, s, w, prec); acb_add_error_mag(res, err); if (real) arb_zero(acb_imagref(res)); } else { acb_indeterminate(res); } acb_clear(s); acb_clear(w); acb_clear(w2); fmpz_clear(c); fmpz_clear(d); mag_clear(m); mag_clear(err); }
int main() { long iter; flint_rand_t state; printf("eta...."); fflush(stdout); flint_randinit(state); /* Test functional equation */ for (iter = 0; iter < 10000; iter++) { acb_t tau1, tau2, z1, z2, z3, t; fmpq_t arg; long e0, prec0, prec1, prec2; psl2z_t g; psl2z_init(g); fmpq_init(arg); acb_init(tau1); acb_init(tau2); acb_init(z1); acb_init(z2); acb_init(z3); acb_init(t); e0 = 1 + n_randint(state, 200); 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_eta(z1, tau1, prec1); acb_modular_eta(z2, tau2, prec2); /* apply transformation */ fmpq_set_si(arg, acb_modular_epsilon_arg(g), 12); arb_sin_cos_pi_fmpq(acb_imagref(t), acb_realref(t), arg, prec1); acb_mul(z3, z1, t, prec1); acb_mul_fmpz(t, tau1, &g->c, prec1); acb_add_fmpz(t, t, &g->d, prec1); acb_sqrt(t, t, prec1); acb_mul(z3, z3, t, prec1); if (!acb_overlaps(z3, z2)) { printf("FAIL (overlap)\n"); printf("tau1 = "); acb_printd(tau1, 15); printf("\n\n"); printf("tau2 = "); acb_printd(tau2, 15); printf("\n\n"); printf("g = "); psl2z_print(g); printf("\n\n"); printf("z1 = "); acb_printd(z1, 15); printf("\n\n"); printf("z2 = "); acb_printd(z2, 15); printf("\n\n"); printf("z3 = "); acb_printd(z3, 15); printf("\n\n"); abort(); } acb_modular_eta(tau1, tau1, prec2); if (!acb_overlaps(z1, tau1)) { printf("FAIL (aliasing)\n"); printf("tau1 = "); acb_print(tau1); printf("\n\n"); printf("tau2 = "); acb_print(tau2); printf("\n\n"); printf("z1 = "); acb_print(z1); printf("\n\n"); printf("z2 = "); acb_print(z2); printf("\n\n"); abort(); } acb_clear(tau1); acb_clear(tau2); acb_clear(z1); acb_clear(z2); acb_clear(z3); acb_clear(t); psl2z_clear(g); fmpq_clear(arg); } /* Test special values */ for (iter = 0; iter < 100; iter++) { acb_t tau, z; arb_t t, u; long prec; acb_init(tau); acb_init(z); arb_init(t); arb_init(u); prec = 2 + n_randint(state, 2000); acb_randtest(z, state, prec, 10); acb_onei(tau); acb_modular_eta(z, tau, prec); arb_one(t); arb_mul_2exp_si(t, t, -2); arb_gamma(t, t, prec); arb_const_pi(u, prec); arb_root(u, u, 4, prec); arb_pow_ui(u, u, 3, prec); arb_div(t, t, u, prec); arb_mul_2exp_si(t, t, -1); if (!arb_overlaps(acb_realref(z), t) || !arb_contains_zero(acb_imagref(z))) { printf("FAIL (value 1)\n"); printf("tau = "); acb_print(tau); printf("\n\n"); printf("z = "); acb_print(z); printf("\n\n"); abort(); } acb_clear(tau); acb_clear(z); arb_clear(t); arb_clear(u); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("transform...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { psl2z_t g; acb_t z, w1, w2, t; slong prec; psl2z_init(g); acb_init(z); acb_init(w1); acb_init(w2); acb_init(t); psl2z_randtest(g, state, n_randint(state, 20)); acb_randtest(z, state, 1 + n_randint(state, 200), 1 + n_randint(state, 20)); acb_randtest(w1, state, 1 + n_randint(state, 200), 1 + n_randint(state, 20)); acb_randtest(w2, state, 1 + n_randint(state, 200), 1 + n_randint(state, 20)); acb_modular_transform(w1, g, z, 2 + n_randint(state, 200)); prec = 2 + n_randint(state, 200); acb_mul_fmpz(t, z, &g->a, prec); acb_add_fmpz(t, t, &g->b, prec); acb_mul_fmpz(w2, z, &g->c, prec); acb_add_fmpz(w2, w2, &g->d, prec); acb_div(w2, t, w2, prec); if (!acb_overlaps(w1, w2)) { flint_printf("FAIL\n"); flint_printf("g = "); psl2z_print(g); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 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"); abort(); } psl2z_clear(g); acb_clear(z); acb_clear(w1); acb_clear(w2); acb_clear(t); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("quadratic_roots_fmpz...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t r1, r2, x, y; fmpz_t a, b, c; slong prec; fmpz_init(a); fmpz_init(b); fmpz_init(c); acb_init(r1); acb_init(r2); acb_init(x); acb_init(y); prec = 2 + n_randint(state, 1000); fmpz_randtest_not_zero(a, state, 1 + n_randint(state, 1000)); fmpz_randtest(b, state, 1 + n_randint(state, 1000)); fmpz_randtest(c, state, 1 + n_randint(state, 1000)); acb_randtest(r1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(r2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_quadratic_roots_fmpz(r1, r2, a, b, c, prec); acb_mul(x, r1, r1, prec); acb_mul_fmpz(x, x, a, prec); acb_addmul_fmpz(x, r1, b, prec); acb_add_fmpz(x, x, c, prec); acb_mul(y, r2, r2, prec); acb_mul_fmpz(y, y, a, prec); acb_addmul_fmpz(y, r2, b, prec); acb_add_fmpz(y, y, c, prec); if (!acb_contains_zero(x) || !acb_contains_zero(y) || acb_rel_accuracy_bits(r1) < prec - 4 || acb_rel_accuracy_bits(r2) < prec - 4) { flint_printf("FAIL: containment / accuracy\n\n"); flint_printf("prec = %wd\n", prec); flint_printf("a = "); fmpz_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpz_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpz_print(c); flint_printf("\n\n"); flint_printf("r1 = "); acb_printd(r1, 30); flint_printf("\n\n"); flint_printf("r2 = "); acb_printd(r2, 30); flint_printf("\n\n"); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); acb_clear(r1); acb_clear(r2); acb_clear(x); acb_clear(y); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_rising_ui_rs(acb_t y, const acb_t x, ulong n, ulong m, slong prec) { acb_ptr xs; acb_t t, u, v; ulong i, k, rem; fmpz_t c, h; fmpz *s, *d; slong wp; if (n == 0) { acb_one(y); return; } if (n == 1) { acb_set_round(y, x, prec); return; } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); acb_init(t); acb_init(u); acb_init(v); fmpz_init(c); fmpz_init(h); if (m == 0) { ulong m1, m2; m1 = 0.2 * pow(2.0 * wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MIN(m, n); m = FLINT_MAX(m, 1); xs = _acb_vec_init(m + 1); d = _fmpz_vec_init(m * m); s = _fmpz_vec_init(m + 1); _acb_vec_set_powers(xs, x, m + 1, wp); rising_difference_polynomial(s, d, m); /* tail */ rem = m; while (rem + m <= n) rem += m; acb_one(y); for (k = rem; k < n; k++) { acb_add_ui(t, xs + 1, k, wp); acb_mul(y, y, t, wp); } /* initial rising factorial */ acb_zero(t); for (i = 1; i <= m; i++) acb_addmul_fmpz(t, xs + i, s + i, wp); acb_mul(y, y, t, wp); /* the leading coefficient is always the same */ acb_mul_fmpz(xs + m - 1, xs + m - 1, d + m - 1 + 0, wp); for (k = 0; k + 2 * m <= n; k += m) { for (i = 0; i < m - 1; i++) { fmpz_set_ui(h, k); _fmpz_poly_evaluate_horner_fmpz(c, d + i * m, m - i, h); if (i == 0) acb_add_fmpz(t, t, c, wp); else acb_addmul_fmpz(t, xs + i, c, wp); } acb_add(t, t, xs + m - 1, wp); acb_mul(y, y, t, wp); } acb_set_round(y, y, prec); acb_clear(t); acb_clear(u); acb_clear(v); _acb_vec_clear(xs, m + 1); _fmpz_vec_clear(d, m * m); _fmpz_vec_clear(s, m + 1); fmpz_clear(c); fmpz_clear(h); }