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_arf(arb_t z, const arb_t x, const arf_t y, slong prec) { mag_t ym; int inexact; if (arb_is_exact(x)) { inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else if (ARB_IS_LAGOM(x) && ARF_IS_LAGOM(y) && ARB_IS_LAGOM(z)) { mag_fast_init_set_arf(ym, y); mag_fast_addmul(arb_radref(z), ym, arb_radref(x)); inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); } else { mag_init_set_arf(ym, y); mag_addmul(arb_radref(z), ym, arb_radref(x)); inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND); if (inexact) arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec); mag_clear(ym); } }
static void _acb_mul_fast(acb_t z, const acb_t x, const acb_t y, slong prec) { int inexact; mag_t am, bm, cm, dm, er, fr; mag_fast_init_set_arf(am, arb_midref(a)); mag_fast_init_set_arf(bm, arb_midref(b)); mag_fast_init_set_arf(cm, arb_midref(c)); mag_fast_init_set_arf(dm, arb_midref(d)); mag_init(er); mag_init(fr); mag_fast_addmul(er, am, cr); mag_fast_addmul(er, bm, dr); mag_fast_addmul(er, cm, ar); mag_fast_addmul(er, dm, br); mag_fast_addmul(er, ar, cr); mag_fast_addmul(er, br, dr); mag_fast_addmul(fr, am, dr); mag_fast_addmul(fr, bm, cr); mag_fast_addmul(fr, cm, br); mag_fast_addmul(fr, dm, ar); mag_fast_addmul(fr, br, cr); mag_fast_addmul(fr, ar, dr); inexact = arf_complex_mul(arb_midref(e), arb_midref(f), arb_midref(a), arb_midref(b), arb_midref(c), arb_midref(d), prec, ARB_RND); if (inexact & 1) arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec); else mag_set(arb_radref(e), er); if (inexact & 2) arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec); else mag_set(arb_radref(f), fr); }
static void _acb_sqr_fast(acb_t z, const acb_t x, slong prec) { int inexact; mag_t am, bm, er, fr; mag_fast_init_set_arf(am, arb_midref(a)); mag_fast_init_set_arf(bm, arb_midref(b)); mag_init(er); mag_init(fr); mag_fast_addmul(er, am, ar); mag_fast_addmul(er, bm, br); mag_fast_mul_2exp_si(er, er, 1); mag_fast_addmul(er, ar, ar); mag_fast_addmul(er, br, br); mag_fast_addmul(fr, bm, ar); mag_fast_addmul(fr, am, br); mag_fast_addmul(fr, ar, br); mag_fast_mul_2exp_si(fr, fr, 1); inexact = arf_complex_sqr(arb_midref(e), arb_midref(f), arb_midref(a), arb_midref(b), prec, ARB_RND); if (inexact & 1) arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec); else mag_set(arb_radref(e), er); if (inexact & 2) arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec); else mag_set(arb_radref(f), fr); }