static __inline__ void fmpcb_inv_mid(fmpcb_t z, const fmpcb_t x, long prec) { fmpr_t t; fmpr_init(t); #define a fmprb_midref(fmpcb_realref(x)) #define b fmprb_midref(fmpcb_imagref(x)) #define e fmprb_midref(fmpcb_realref(z)) #define f fmprb_midref(fmpcb_imagref(z)) fmpr_mul(t, a, a, prec, FMPR_RND_DOWN); fmpr_addmul(t, b, b, prec, FMPR_RND_DOWN); fmpr_div(e, a, t, prec, FMPR_RND_DOWN); fmpr_div(f, b, t, prec, FMPR_RND_DOWN); fmpr_neg(f, f); #undef a #undef b #undef e #undef f fmpr_clear(t); }
void gamma_taylor_bound_remainder(fmpr_t err, const fmpr_t z, long n) { fmpr_t t, u; gamma_taylor_bound_extend_cache(n + 1); fmpr_init(t); fmpr_init(u); /* denominator: 1 - r(n+1) * z, rounded down */ fmpr_mul(t, gamma_taylor_bound_ratio_cache + n + 1, z, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_one(u); fmpr_sub(u, u, t, FMPRB_RAD_PREC, FMPR_RND_DOWN); if (fmpr_sgn(u) <= 0) { fmpr_pos_inf(err); } else { fmpr_pow_sloppy_ui(t, z, n, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_mul_2exp_si(t, t, gamma_taylor_bound_mag_cache[n + 1]); fmpr_div(err, t, u, FMPRB_RAD_PREC, FMPR_RND_UP); } fmpr_clear(t); fmpr_clear(u); }
void fmpr_divappr_abs_ubound(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec) { if (fmpr_is_special(x) || fmpr_is_special(y) || fmpz_is_pm1(fmpr_manref(y))) { fmpr_div(z, x, y, prec, FMPR_RND_UP); fmpr_abs(z, z); } else { fmpz_t t, u; slong xbits, ybits, tbits, ubits, shift; xbits = fmpz_bits(fmpr_manref(x)); ybits = fmpz_bits(fmpr_manref(y)); fmpz_init(t); fmpz_init(u); ubits = FLINT_MIN(ybits, prec); tbits = prec + ubits + 1; /* upper bound for |x|, shifted */ if (xbits <= tbits) { fmpz_mul_2exp(t, fmpr_manref(x), tbits - xbits); fmpz_abs(t, t); } else if (fmpz_sgn(fmpr_manref(x)) > 0) { fmpz_cdiv_q_2exp(t, fmpr_manref(x), xbits - tbits); } else { fmpz_fdiv_q_2exp(t, fmpr_manref(x), xbits - tbits); fmpz_neg(t, t); } /* lower bound for |y|, shifted */ if (ybits <= ubits) fmpz_mul_2exp(u, fmpr_manref(y), ubits - ybits); else fmpz_tdiv_q_2exp(u, fmpr_manref(y), ybits - ubits); fmpz_abs(u, u); fmpz_cdiv_q(fmpr_manref(z), t, u); shift = (ubits - ybits) - (tbits - xbits); fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y)); if (shift >= 0) fmpz_add_ui(fmpr_expref(z), fmpr_expref(z), shift); else fmpz_sub_ui(fmpr_expref(z), fmpr_expref(z), -shift); _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, FMPR_RND_UP); fmpz_clear(t); fmpz_clear(u); } }
slong fmpr_fmpz_div(fmpr_t z, const fmpz_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_fmpz(t, x); r = fmpr_div(z, t, y, prec, rnd); fmpr_clear(t); return r; }
slong fmpr_div_si(fmpr_t z, const fmpr_t x, slong y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_set_si(t, y); r = fmpr_div(z, x, t, prec, rnd); fmpr_clear(t); return r; }
int main() { long iter; flint_rand_t state; printf("div...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000; iter++) { long bits, r1, r2; fmpr_t x, y, z, w; mpfr_t X, Y, Z; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 100); mpfr_init2(Y, bits + 100); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 100), 10); fmpr_randtest_special(z, state, bits + n_randint(state, 100), 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: r1 = mpfr_div(Z, X, Y, MPFR_RNDZ); r2 = fmpr_div(z, x, y, bits, FMPR_RND_DOWN); break; case 1: r1 = mpfr_div(Z, X, Y, MPFR_RNDA); r2 = fmpr_div(z, x, y, bits, FMPR_RND_UP); break; case 2: r1 = mpfr_div(Z, X, Y, MPFR_RNDD); r2 = fmpr_div(z, x, y, bits, FMPR_RND_FLOOR); break; default: r1 = mpfr_div(Z, X, Y, MPFR_RNDU); r2 = fmpr_div(z, x, y, bits, FMPR_RND_CEIL); break; } /* we use slightly different semantics for special values (?) */ if (mpfr_zero_p(Y)) mpfr_set_nan(Z); if (mpfr_inf_p(X) && mpfr_zero_p(Y)) mpfr_set_nan(Z); fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || ((r1 == 0) != (r2 == FMPR_RESULT_EXACT)) || !fmpr_check_ulp(z, r2, bits)) { printf("FAIL\n\n"); printf("bits = %ld\n", bits); printf("r1 = %ld, r2 = %ld\n", r1, r2); printf("x = "); fmpr_print(x); printf("\n\n"); printf("y = "); fmpr_print(y); printf("\n\n"); printf("z = "); fmpr_print(z); printf("\n\n"); printf("w = "); fmpr_print(w); printf("\n\n"); abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); mpfr_clear(X); mpfr_clear(Y); mpfr_clear(Z); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }