void arb_addmul(arb_t z, const arb_t x, const arb_t y, slong prec) { mag_t zr, xm, ym; int inexact; if (arb_is_exact(y)) { arb_addmul_arf(z, x, arb_midref(y), prec); } else if (arb_is_exact(x)) { arb_addmul_arf(z, y, arb_midref(x), prec); } else if (ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(xm, arb_midref(x)); mag_fast_init_set_arf(ym, arb_midref(y)); mag_fast_init_set(zr, arb_radref(z)); mag_fast_addmul(zr, xm, arb_radref(y)); mag_fast_addmul(zr, ym, arb_radref(x)); mag_fast_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_addmul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); if (inexact) arf_mag_fast_add_ulp(zr, zr, arb_midref(z), prec); *arb_radref(z) = *zr; } else { mag_init_set_arf(xm, arb_midref(x)); mag_init_set_arf(ym, arb_midref(y)); mag_init_set(zr, arb_radref(z)); mag_addmul(zr, xm, arb_radref(y)); mag_addmul(zr, ym, arb_radref(x)); mag_addmul(zr, arb_radref(x), arb_radref(y)); inexact = arf_addmul(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARF_RND_DOWN); if (inexact) arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec); else mag_set(arb_radref(z), zr); mag_clear(zr); mag_clear(xm); mag_clear(ym); } }
void arb_addmul_ui(arb_t z, const arb_t x, ulong y, slong prec) { arf_t t; arf_init_set_ui(t, y); /* no need to free */ arb_addmul_arf(z, x, t, prec); }
void arb_addmul_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec) { arf_t t; if (!COEFF_IS_MPZ(*y)) { arf_init_set_si(t, *y); /* no need to free */ arb_addmul_arf(z, x, t, prec); } else { arf_init(t); arf_set_fmpz(t, y); arb_addmul_arf(z, x, t, prec); arf_clear(t); } }
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); }