#include "acb.h"
#include "acb_dirichlet.h"
static 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);
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
{
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);
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);
}
acb_add(res, R1, R2, prec);
acb_clear(R1);
acb_clear(R2);
acb_clear(X);
acb_clear(t);
}
void
acb_dirichlet_zeta_rs(acb_t res, const acb_t s, slong K, slong prec)
{
if (acb_is_exact(s))
{
acb_dirichlet_zeta_rs_mid(res, s, K, prec);
}
else
{
acb_t t;
mag_t rad, err, err2;
slong acc;
acc = acb_rel_accuracy_bits(s);
acc = FLINT_MAX(acc, 0);
acc = FLINT_MIN(acc, prec);
prec = FLINT_MIN(prec, acc + 20);
acb_init(t);
mag_init(rad);
mag_init(err);
mag_init(err2);
mag_hypot(rad, arb_radref(acb_realref(s)), arb_radref(acb_imagref(s)));
acb_dirichlet_zeta_deriv_bound(err, err2, s);
mag_mul(err, err, rad);
acb_get_mid(t, s);
acb_dirichlet_zeta_rs_mid(res, t, K, prec);
acb_add_error_mag(res, err);
acb_clear(t);
mag_clear(rad);
mag_clear(err);
mag_clear(err2);
}
}