void fmprb_sqrt(fmprb_t z, const fmprb_t x, slong prec) { slong r; if (fmprb_contains_negative(x)) { fmpr_nan(fmprb_midref(z)); fmpr_pos_inf(fmprb_radref(z)); return; } if (fmprb_is_exact(x)) { r = fmpr_sqrt(fmprb_midref(z), fmprb_midref(x), prec, FMPR_RND_DOWN); fmpr_set_error_result(fmprb_radref(z), fmprb_midref(z), r); } else { fmpr_t err; fmpr_init(err); fmpr_sub(err, fmprb_midref(x), fmprb_radref(x), FMPRB_RAD_PREC, FMPR_RND_DOWN); fmpr_rsqrt(err, err, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_mul(err, fmprb_radref(x), err, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_mul_2exp_si(err, err, -1); r = fmpr_sqrt(fmprb_midref(z), fmprb_midref(x), prec, FMPR_RND_DOWN); fmpr_add_error_result(fmprb_radref(z), err, fmprb_midref(z), r, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_clear(err); } fmprb_adjust(z); }
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); }
int main() { slong iter; flint_rand_t state; flint_printf("set_d...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t a, b, c; mag_t m; double x; fmpr_init(a); fmpr_init(b); fmpr_init(c); mag_init(m); x = d_randtest2(state); x = ldexp(x, 100 - n_randint(state, 200)); if (n_randint(state, 100) == 0) x = 0.0; fmpr_set_d(a, x); mag_set_d(m, x); mag_get_fmpr(b, m); fmpr_set(c, a); fmpr_mul_ui(c, c, 1025, MAG_BITS, FMPR_RND_UP); fmpr_mul_2exp_si(c, c, -10); MAG_CHECK_BITS(m) if (!(fmpr_cmpabs(a, b) <= 0 && fmpr_cmpabs(b, c) <= 0)) { flint_printf("FAIL\n\n"); flint_printf("a = "); fmpr_print(a); flint_printf("\n\n"); flint_printf("b = "); fmpr_print(b); flint_printf("\n\n"); flint_printf("c = "); fmpr_print(c); flint_printf("\n\n"); abort(); } fmpr_clear(a); fmpr_clear(b); fmpr_clear(c); mag_clear(m); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("mul_2exp_si...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { fmpr_t x, y, z; mag_t xb, yb; slong e; fmpr_init(x); fmpr_init(y); fmpr_init(z); mag_init(xb); mag_init(yb); mag_randtest_special(xb, state, 100); e = z_randtest(state); mag_get_fmpr(x, xb); mag_mul_2exp_si(yb, xb, e); fmpr_mul_2exp_si(y, x, e); mag_get_fmpr(z, yb); MAG_CHECK_BITS(yb) if (!fmpr_equal(z, y)) { flint_printf("FAIL\n\n"); flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n"); flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n"); flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n"); abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); mag_clear(xb); mag_clear(yb); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
/* Absolute value of rising factorial (could speed up once complex gamma is available). */ void fmpcb_rfac_abs_ubound2(fmpr_t bound, const fmpcb_t s, ulong n, long prec) { fmpr_t term, t; ulong k; /* M(k) = (a+k)^2 + b^2 M(0) = a^2 + b^2 M(k+1) = M(k) + 2*a + (2*k+1) */ fmpr_init(t); fmpr_init(term); fmpr_one(bound); /* M(0) = a^2 + b^2 */ fmprb_get_abs_ubound_fmpr(t, fmpcb_realref(s), prec); fmpr_mul(term, t, t, prec, FMPR_RND_UP); fmprb_get_abs_ubound_fmpr(t, fmpcb_imagref(s), prec); fmpr_mul(t, t, t, prec, FMPR_RND_UP); fmpr_add(term, term, t, prec, FMPR_RND_UP); /* we add t = 2*a to each term. note that this can be signed; we always want the most positive value */ fmpr_add(t, fmprb_midref(fmpcb_realref(s)), fmprb_radref(fmpcb_realref(s)), prec, FMPR_RND_CEIL); fmpr_mul_2exp_si(t, t, 1); for (k = 0; k < n; k++) { fmpr_mul(bound, bound, term, prec, FMPR_RND_UP); fmpr_add_ui(term, term, 2 * k + 1, prec, FMPR_RND_UP); fmpr_add(term, term, t, prec, FMPR_RND_UP); } fmpr_sqrt(bound, bound, prec, FMPR_RND_UP); fmpr_clear(t); fmpr_clear(term); }
static __inline__ void fmprb_nonnegative_part(fmprb_t z, const fmprb_t x, slong prec) { if (fmprb_contains_negative(x)) { fmpr_add(fmprb_midref(z), fmprb_midref(x), fmprb_radref(x), prec, FMPR_RND_CEIL); if (fmpr_sgn(fmprb_midref(z)) <= 0) { fmpr_zero(fmprb_radref(z)); } else { fmpr_mul_2exp_si(fmprb_midref(z), fmprb_midref(z), -1); fmpr_set(fmprb_midref(z), fmprb_radref(z)); } } else { fmprb_set(z, x); } }
void fmprb_sqrtpos(fmprb_t z, const fmprb_t x, slong prec) { if (!fmprb_is_finite(x)) { if (fmpr_is_zero(fmprb_radref(x)) && fmpr_is_pos_inf(fmprb_midref(x))) fmprb_pos_inf(z); else fmprb_zero_pm_inf(z); } else if (fmprb_contains_nonpositive(x)) { fmpr_t t; fmpr_init(t); fmpr_add(t, fmprb_midref(x), fmprb_radref(x), FMPRB_RAD_PREC, FMPR_RND_CEIL); if (fmpr_sgn(t) <= 0) { fmprb_zero(z); } else { fmpr_sqrt(t, t, FMPRB_RAD_PREC, FMPR_RND_CEIL); fmpr_mul_2exp_si(t, t, -1); fmpr_set(fmprb_midref(z), t); fmpr_set(fmprb_radref(z), t); } fmpr_clear(t); } else { fmprb_sqrt(z, x, prec); } fmprb_nonnegative_part(z, z, prec); }
void _fmprb_poly_mullow_ztrunc(fmprb_ptr C, fmprb_srcptr A, long lenA, fmprb_srcptr B, long lenB, long n, long prec) { fmpz * Acoeffs, * Bcoeffs, * Ccoeffs; fmpz_t Aexp, Bexp, Cexp; fmpr_t Aerr, Berr, Anorm, Bnorm, err; long i; int squaring; lenA = FLINT_MIN(lenA, n); lenB = FLINT_MIN(lenB, n); squaring = (A == B) && (lenA == lenB); /* TODO: make the code below work correctly with out this workaround */ if (_fmprb_vec_rad_has_inf_nan(A, lenA) || (!squaring && _fmprb_vec_rad_has_inf_nan(B, lenB))) { _fmprb_vec_indeterminate(C, n); return; } fmpz_init(Aexp); fmpz_init(Bexp); fmpz_init(Cexp); Acoeffs = _fmpz_vec_init(lenA); Bcoeffs = _fmpz_vec_init(lenB); Ccoeffs = _fmpz_vec_init(n); fmpr_init(Aerr); fmpr_init(Berr); fmpr_init(Anorm); fmpr_init(Bnorm); fmpr_init(err); _fmprb_poly_get_fmpz_poly_2exp(Aerr, Aexp, Acoeffs, A, lenA, prec); if (squaring) { _fmpz_poly_sqrlow(Ccoeffs, Acoeffs, lenA, n); fmpz_add(Cexp, Aexp, Aexp); /* cross-multiply error bounds: (A+r)(B+s) = A^2 + 2Ar + r^2 */ _fmpr_fmpz_vec_max_norm(Anorm, Acoeffs, lenA, FMPRB_RAD_PREC); fmpr_mul_2exp_fmpz(Anorm, Anorm, Aexp); fmpr_mul(err, Anorm, Aerr, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_mul_2exp_si(err, err, 1); fmpr_addmul(err, Aerr, Aerr, FMPRB_RAD_PREC, FMPR_RND_UP); } else { _fmprb_poly_get_fmpz_poly_2exp(Berr, Bexp, Bcoeffs, B, lenB, prec); /* main multiplication */ if (lenA >= lenB) _fmpz_poly_mullow(Ccoeffs, Acoeffs, lenA, Bcoeffs, lenB, n); else _fmpz_poly_mullow(Ccoeffs, Bcoeffs, lenB, Acoeffs, lenA, n); fmpz_add(Cexp, Aexp, Bexp); /* cross-multiply error bounds: (A+r)(B+s) = AB + As + Br + rs */ _fmpr_fmpz_vec_max_norm(Anorm, Acoeffs, lenA, FMPRB_RAD_PREC); fmpr_mul_2exp_fmpz(Anorm, Anorm, Aexp); _fmpr_fmpz_vec_max_norm(Bnorm, Bcoeffs, lenB, FMPRB_RAD_PREC); fmpr_mul_2exp_fmpz(Bnorm, Bnorm, Bexp); fmpr_mul(err, Aerr, Berr, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_addmul(err, Anorm, Berr, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_addmul(err, Bnorm, Aerr, FMPRB_RAD_PREC, FMPR_RND_UP); } for (i = 0; i < n; i++) { fmprb_set_round_fmpz_2exp(C + i, Ccoeffs + i, Cexp, prec); /* there are at most (i+1) error terms for coefficient i */ /* TODO: make this tight */ fmpr_addmul_ui(fmprb_radref(C + i), err, i + 1, FMPRB_RAD_PREC, FMPR_RND_UP); } fmpr_clear(Aerr); fmpr_clear(Berr); fmpr_clear(Anorm); fmpr_clear(Bnorm); fmpr_clear(err); _fmpz_vec_clear(Acoeffs, lenA); _fmpz_vec_clear(Bcoeffs, lenB); _fmpz_vec_clear(Ccoeffs, n); fmpz_clear(Aexp); fmpz_clear(Bexp); fmpz_clear(Cexp); }