void acb_dot_simple(acb_t res, const acb_t initial, int subtract, acb_srcptr x, slong xstep, acb_srcptr y, slong ystep, slong len, slong prec) { slong i; if (len <= 0) { if (initial == NULL) acb_zero(res); else acb_set_round(res, initial, prec); return; } if (initial == NULL) { acb_mul(res, x, y, prec); } else { if (subtract) acb_neg(res, initial); else acb_set(res, initial); acb_addmul(res, x, y, prec); } for (i = 1; i < len; i++) acb_addmul(res, x + i * xstep, y + i * ystep, prec); if (subtract) acb_neg(res, res); }
int acb_mat_lu(long * P, acb_mat_t LU, const acb_mat_t A, long prec) { acb_t d, e; acb_ptr * a; long i, j, m, n, r, row, col; int result; m = acb_mat_nrows(A); n = acb_mat_ncols(A); result = 1; if (m == 0 || n == 0) return result; acb_mat_set(LU, A); a = LU->rows; row = col = 0; for (i = 0; i < m; i++) P[i] = i; acb_init(d); acb_init(e); while (row < m && col < n) { r = acb_mat_find_pivot_partial(LU, row, m, col); if (r == -1) { result = 0; break; } else if (r != row) acb_mat_swap_rows(LU, P, row, r); acb_set(d, a[row] + col); for (j = row + 1; j < m; j++) { acb_div(e, a[j] + col, d, prec); acb_neg(e, e); _acb_vec_scalar_addmul(a[j] + col, a[row] + col, n - col, e, prec); acb_zero(a[j] + col); acb_neg(a[j] + row, e); } row++; col++; } acb_clear(d); acb_clear(e); return result; }
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_polygamma(acb_t res, const acb_t s, const acb_t z, long prec) { if (acb_is_zero(s)) { acb_digamma(res, z, prec); } else if (acb_is_int(s) && arb_is_positive(acb_realref(s))) { acb_t t, u; acb_init(t); acb_init(u); acb_add_ui(t, s, 1, prec); acb_gamma(u, t, prec); acb_hurwitz_zeta(t, t, z, prec); if (arf_is_int_2exp_si(arb_midref(acb_realref(s)), 1)) acb_neg(t, t); acb_mul(res, t, u, prec); acb_clear(t); acb_clear(u); } else { acb_t t, u; acb_struct v[2]; acb_init(t); acb_init(u); acb_init(v); acb_init(v + 1); /* u = psi(-s) + gamma */ acb_neg(t, s); acb_digamma(u, t, prec); arb_const_euler(acb_realref(v), prec); arb_add(acb_realref(u), acb_realref(u), acb_realref(v), prec); acb_add_ui(t, s, 1, prec); _acb_poly_zeta_cpx_series(v, t, z, 0, 2, prec); acb_addmul(v + 1, v, u, prec); acb_neg(t, s); acb_rgamma(u, t, prec); acb_mul(res, v + 1, u, prec); acb_clear(v); acb_clear(v + 1); acb_clear(t); acb_clear(u); } }
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_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); }
/* 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); }
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_laguerre_l(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; if (use_recurrence(n, m, prec)) { acb_hypgeom_laguerre_l_ui_recurrence(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), m, z, prec); return; } /* todo: should be a test of whether n contains any negative integer */ if (acb_contains_int(n) && !arb_is_nonnegative(acb_realref(n))) { acb_indeterminate(res); return; } acb_init(t); acb_init(u); acb_init(v); acb_neg(t, n); acb_add_ui(u, m, 1, prec); acb_hypgeom_m(t, t, u, z, 1, prec); acb_add_ui(u, n, 1, prec); acb_rising(u, u, m, prec); acb_mul(res, t, u, prec); acb_clear(t); acb_clear(u); acb_clear(v); }
void _acb_poly_sin_cos_pi_series(acb_ptr s, acb_ptr c, const acb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { acb_sin_cos_pi(s, c, h, prec); _acb_vec_zero(s + 1, n - 1); _acb_vec_zero(c + 1, n - 1); } else if (n == 2) { acb_t t; acb_init(t); acb_const_pi(t, prec); acb_mul(t, t, h + 1, prec); acb_sin_cos_pi(s, c, h, prec); acb_mul(s + 1, c, t, prec); acb_neg(t, t); acb_mul(c + 1, s, t, prec); acb_clear(t); } else if (hlen < TANGENT_CUTOFF) _acb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 1); else _acb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 1); }
/* 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; }
/* f(z) = sin((1/1000 + (1-z)^2)^(-3/2)), example from Mioara Joldes' thesis (suggested by Nicolas Brisebarre) */ int f_sin_near_essing(acb_ptr res, const acb_t z, void * param, slong order, slong prec) { acb_t t, u; if (order > 1) flint_abort(); /* Would be needed for Taylor method. */ acb_init(t); acb_init(u); acb_sub_ui(t, z, 1, prec); acb_neg(t, t); acb_mul(t, t, t, prec); acb_one(u); acb_div_ui(u, u, 1000, prec); acb_add(t, t, u, prec); acb_set_d(u, -1.5); acb_pow_analytic(t, t, u, order != 0, prec); acb_sin(res, t, prec); acb_clear(t); acb_clear(u); return 0; }
void acb_modular_elliptic_e(acb_t res, const acb_t m, long prec) { if (acb_is_zero(m)) { acb_const_pi(res, prec); acb_mul_2exp_si(res, res, -1); } else if (acb_is_one(m)) { acb_one(res); } else { acb_struct t[2]; acb_init(t + 0); acb_init(t + 1); acb_modular_elliptic_k_cpx(t, m, 2, prec); acb_mul(t + 1, t + 1, m, prec); acb_mul_2exp_si(t + 1, t + 1, 1); acb_add(t, t, t + 1, prec); acb_sub_ui(t + 1, m, 1, prec); acb_mul(res, t, t + 1, prec); acb_neg(res, res); acb_clear(t + 0); acb_clear(t + 1); } }
/* Extremely close to the branch point at -1/e, use the series expansion directly. */ int acb_lambertw_try_near_branch_point(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { 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)))) { if (acb_contains_zero(ez1) || (arf_cmpabs_2exp_si(arb_midref(acb_realref(ez1)), -prec / 4.5 - 6) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(ez1)), -prec / 4.5 - 6) < 0)) { acb_t t; acb_init(t); acb_mul_2exp_si(t, ez1, 1); acb_sqrt(t, t, prec); if (!fmpz_is_zero(k)) acb_neg(t, t); acb_lambertw_branchpoint_series(res, t, 1, prec); acb_clear(t); return 1; } } 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); }
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_hypgeom_bessel_j_asymp_prefactors(acb_t Ap, acb_t Am, acb_t C, const acb_t nu, const acb_t z, long prec) { if (arb_is_positive(acb_realref(z))) { acb_t t, u; acb_init(t); acb_init(u); /* -(2nu+1)/4 * pi + z */ acb_mul_2exp_si(t, nu, 1); acb_add_ui(t, t, 1, prec); acb_mul_2exp_si(t, t, -2); acb_neg(t, t); acb_const_pi(u, prec); acb_mul(t, t, u, prec); acb_add(t, t, z, prec); acb_mul_onei(t, t); acb_exp_invexp(Ap, Am, t, prec); /* (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); acb_clear(t); acb_clear(u); return; } acb_hypgeom_bessel_j_asymp_prefactors_fallback(Ap, Am, C, nu, z, prec); }
void acb_hypgeom_erfi(acb_t res, const acb_t z, slong prec) { acb_mul_onei(res, z); acb_hypgeom_erf(res, res, prec); acb_mul_onei(res, res); acb_neg(res, res); }
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_poly_product_roots(acb_ptr poly, acb_srcptr xs, slong n, slong prec) { if (n == 0) { acb_one(poly); } else if (n == 1) { acb_neg(poly, xs); acb_one(poly + 1); } else if (n == 2) { acb_mul(poly, xs + 0, xs + 1, prec); acb_add(poly + 1, xs + 0, xs + 1, prec); acb_neg(poly + 1, poly + 1); acb_one(poly + 2); } else if (n == 3) { acb_mul(poly + 1, xs, xs + 1, prec); acb_mul(poly, poly + 1, xs + 2, prec); acb_neg(poly, poly); acb_add(poly + 2, xs, xs + 1, prec); acb_addmul(poly + 1, poly + 2, xs + 2, prec); acb_add(poly + 2, poly + 2, xs + 2, prec); acb_neg(poly + 2, poly + 2); acb_one(poly + 3); } else { const slong m = (n + 1) / 2; acb_ptr tmp; tmp = _acb_vec_init(n + 2); _acb_poly_product_roots(tmp, xs, m, prec); _acb_poly_product_roots(tmp + m + 1, xs + m, n - m, prec); _acb_poly_mul_monic(poly, tmp, m + 1, tmp + m + 1, n - m + 1, prec); _acb_vec_clear(tmp, n + 2); } }
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_expint(acb_t res, const acb_t s, const acb_t z, slong prec) { acb_t t; acb_init(t); acb_sub_ui(t, s, 1, prec); acb_neg(t, t); acb_hypgeom_gamma_upper(res, t, z, 2, prec); acb_clear(t); }
void acb_mat_neg(acb_mat_t dest, const acb_mat_t src) { slong i, j; for (i = 0; i < acb_mat_nrows(src); i++) for (j = 0; j < acb_mat_ncols(src); j++) acb_neg(acb_mat_entry(dest, i, j), acb_mat_entry(src, i, j)); }
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_hypgeom_jacobi_p(acb_t res, const acb_t n, const acb_t a, const acb_t b, const acb_t z, slong prec) { acb_t t, u, v, w; if (use_recurrence(n, a, b, prec)) { acb_hypgeom_jacobi_p_ui_direct(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), a, b, z, prec); return; } acb_init(t); acb_init(u); acb_init(v); acb_init(w); acb_neg(t, n); acb_add_ui(v, a, 1, prec); acb_add(u, n, v, prec); acb_add(u, u, b, prec); acb_sub_ui(w, z, 1, prec); acb_mul_2exp_si(w, w, -1); acb_neg(w, w); acb_hypgeom_2f1(w, t, u, v, w, 0, prec); acb_rising(t, v, n, prec); acb_mul(w, w, t, prec); acb_add_ui(t, n, 1, prec); acb_rgamma(t, t, prec); acb_mul(w, w, t, prec); acb_set(res, w); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(w); }
/* (+/- 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); }
/* f(z) = exp(-z^2) */ int f_gaussian(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(res, z, z, prec); acb_neg(res, res); acb_exp(res, res, prec); return 0; }
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); }
void acb_modular_elliptic_k(acb_t k, const acb_t m, slong prec) { acb_t t; acb_init(t); acb_sub_ui(t, m, 1, prec); acb_neg(t, t); acb_sqrt(t, t, prec); acb_agm1(k, t, prec); acb_const_pi(t, prec); acb_div(k, t, k, prec); acb_mul_2exp_si(k, k, -1); acb_clear(t); }