static __inline__ void fmpcb_add_mid(fmpcb_t z, const fmpcb_t x, const fmpcb_t y, long prec) { fmpr_add(fmprb_midref(fmpcb_realref(z)), fmprb_midref(fmpcb_realref(x)), fmprb_midref(fmpcb_realref(y)), prec, FMPR_RND_DOWN); fmpr_add(fmprb_midref(fmpcb_imagref(z)), fmprb_midref(fmpcb_imagref(x)), fmprb_midref(fmpcb_imagref(y)), prec, FMPR_RND_DOWN); }
void fmprb_add(fmprb_t z, const fmprb_t x, const fmprb_t y, slong prec) { slong r; fmpr_add(fmprb_radref(z), fmprb_radref(x), fmprb_radref(y), FMPRB_RAD_PREC, FMPR_RND_UP); r = fmpr_add(fmprb_midref(z), fmprb_midref(x), fmprb_midref(y), prec, FMPR_RND_DOWN); fmpr_add_error_result(fmprb_radref(z), fmprb_radref(z), fmprb_midref(z), r, FMPRB_RAD_PREC, FMPR_RND_UP); fmprb_adjust(z); }
void fmprb_add_error(fmprb_t x, const fmprb_t error) { fmpr_t high; fmpr_init(high); fmpr_add(high, fmprb_midref(error), fmprb_radref(error), FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_add(fmprb_radref(x), fmprb_radref(x), high, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_clear(high); }
void fmprb_mul_main_naive(fmprb_t z, const fmprb_t x, const fmprb_t y, slong prec) { if (fmpr_is_pos_inf(fmprb_radref(x)) || fmpr_is_pos_inf(fmprb_radref(y))) { fmpr_mul(fmprb_midref(z), fmprb_midref(x), fmprb_midref(y), prec, FMPR_RND_DOWN); fmpr_pos_inf(fmprb_radref(z)); } else { fmpr_t t, u; slong r; fmpr_init(t); fmpr_init(u); /* (x+a)*(y+b) = x*y + x*b + y*a + a*b*/ fmpr_mul(t, fmprb_midref(x), fmprb_radref(y), FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_abs(t, t); fmpr_mul(u, fmprb_midref(y), fmprb_radref(x), FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_abs(u, u); fmpr_add(t, t, u, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_addmul(t, fmprb_radref(x), fmprb_radref(y), FMPRB_RAD_PREC, FMPR_RND_UP); r = fmpr_mul(fmprb_midref(z), fmprb_midref(x), fmprb_midref(y), prec, FMPR_RND_DOWN); fmpr_add_error_result(fmprb_radref(z), t, fmprb_midref(z), r, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_clear(t); fmpr_clear(u); } }
void fmpcb_mat_bound_inf_norm(fmpr_t b, const fmpcb_mat_t A, long prec) { long i, j, r, c; fmpr_t s, t; r = fmpcb_mat_nrows(A); c = fmpcb_mat_ncols(A); fmpr_zero(b); if (r == 0 || c == 0) return; fmpr_init(s); fmpr_init(t); for (i = 0; i < r; i++) { fmpr_zero(s); for (j = 0; j < c; j++) { fmpcb_get_abs_ubound_fmpr(t, fmpcb_mat_entry(A, i, j), prec); fmpr_add(s, s, t, prec, FMPR_RND_UP); } fmpr_max(b, b, s); } fmpr_clear(s); fmpr_clear(t); }
int arf_add_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd) { if (rnd == ARF_RND_NEAR) { arf_add(z, x, y, ARF_PREC_EXACT, ARF_RND_DOWN); return arf_set_round(z, z, prec, rnd); } else { fmpr_t a, b; slong r; fmpr_init(a); fmpr_init(b); arf_get_fmpr(a, x); arf_get_fmpr(b, y); r = fmpr_add(a, a, b, prec, rnd); arf_set_fmpr(z, a); fmpr_clear(a); fmpr_clear(b); return (r == FMPR_RESULT_EXACT) ? 0 : 1; } }
slong fmpr_add_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_add(z, x, t, prec, rnd); fmpr_clear(t); return r; }
long fmpr_add_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, long prec, fmpr_rnd_t rnd) { fmpr_t t; long r; fmpr_init(t); fmpr_set_fmpz(t, y); r = fmpr_add(z, x, t, prec, rnd); fmpr_clear(t); return r; }
slong fmpr_addmul(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { fmpr_t t; slong r; fmpr_init(t); fmpr_mul(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); r = fmpr_add(z, z, t, prec, rnd); fmpr_clear(t); return r; }
/* 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 fmpcb_mul_mid(fmpcb_t z, const fmpcb_t x, const fmpcb_t y, long prec) { #define a fmprb_midref(fmpcb_realref(x)) #define b fmprb_midref(fmpcb_imagref(x)) #define c fmprb_midref(fmpcb_realref(y)) #define d fmprb_midref(fmpcb_imagref(y)) #define e fmprb_midref(fmpcb_realref(z)) #define f fmprb_midref(fmpcb_imagref(z)) fmpr_t t, u, v; fmpr_init(t); fmpr_init(u); fmpr_init(v); fmpr_add(t, a, b, prec, FMPR_RND_DOWN); fmpr_add(u, c, d, prec, FMPR_RND_DOWN); fmpr_mul(v, t, u, prec, FMPR_RND_DOWN); fmpr_mul(t, a, c, prec, FMPR_RND_DOWN); fmpr_mul(u, b, d, prec, FMPR_RND_DOWN); fmpr_sub(e, t, u, prec, FMPR_RND_DOWN); fmpr_sub(f, v, t, prec, FMPR_RND_DOWN); fmpr_sub(f, f, u, prec, FMPR_RND_DOWN); fmpr_clear(t); fmpr_clear(u); fmpr_clear(v); #undef a #undef b #undef c #undef d #undef e #undef f }
void fmprb_hypgeom_infsum(fmprb_t P, fmprb_t Q, hypgeom_t hyp, long target_prec, long prec) { mag_t err, z; long n; mag_init(err); mag_init(z); mag_set_fmpz(z, hyp->P->coeffs + hyp->P->length - 1); mag_div_fmpz(z, z, hyp->Q->coeffs + hyp->Q->length - 1); if (!hyp->have_precomputed) { hypgeom_precompute(hyp); hyp->have_precomputed = 1; } n = hypgeom_bound(err, hyp->r, hyp->boundC, hyp->boundD, hyp->boundK, hyp->MK, z, target_prec); fmprb_hypgeom_sum(P, Q, hyp, n, prec); if (fmpr_sgn(fmprb_midref(Q)) < 0) { fmprb_neg(P, P); fmprb_neg(Q, Q); } /* We have p/q = s + err i.e. (p + q*err)/q = s */ { fmpr_t u, v; fmpr_init(u); fmpr_init(v); mag_get_fmpr(v, err); fmpr_add(u, fmprb_midref(Q), fmprb_radref(Q), FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_mul(u, u, v, FMPRB_RAD_PREC, FMPR_RND_UP); fmprb_add_error_fmpr(P, u); fmpr_clear(u); fmpr_clear(v); } mag_clear(z); mag_clear(err); }
int fmpr_cmpabs(const fmpr_t x, const fmpr_t y) { int res, xsign, ysign; fmpr_t t; if (fmpr_equal(x, y)) return 0; if (fmpr_is_special(x) || fmpr_is_special(y)) { if (fmpr_is_nan(x) || fmpr_is_nan(y)) return 0; if (fmpr_is_zero(x)) return -1; if (fmpr_is_zero(y)) return 1; if (fmpr_is_inf(x)) return fmpr_is_inf(y) ? 0 : 1; if (fmpr_is_inf(y)) return -1; return -1; } /* Reduces to integer comparison if bottom exponents are the same */ if (fmpz_equal(fmpr_expref(x), fmpr_expref(y))) { res = fmpz_cmpabs(fmpr_manref(x), fmpr_manref(y)); if (res != 0) res = (res < 0) ? -1 : 1; } else { /* TODO: compare position of top exponents to avoid subtraction */ xsign = fmpr_sgn(x); ysign = fmpr_sgn(y); fmpr_init(t); if (xsign == ysign) fmpr_sub(t, x, y, 2, FMPR_RND_DOWN); else fmpr_add(t, x, y, 2, FMPR_RND_DOWN); res = fmpr_sgn(t) * xsign; fmpr_clear(t); } return res; }
void fmprb_get_interval_fmpz_2exp(fmpz_t a, fmpz_t b, fmpz_t exp, const fmprb_t x) { if (fmprb_is_exact(x)) { fmpr_get_fmpz_2exp(a, exp, fmprb_midref(x)); fmpz_set(b, a); } else { fmpr_t t; fmpz_t exp2; slong s; fmpr_init(t); fmpz_init(exp2); fmpr_sub(t, fmprb_midref(x), fmprb_radref(x), FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_get_fmpz_2exp(a, exp, t); fmpr_add(t, fmprb_midref(x), fmprb_radref(x), FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_get_fmpz_2exp(b, exp2, t); s = _fmpz_sub_small(exp, exp2); if (s <= 0) { fmpz_mul_2exp(b, b, -s); } else { fmpz_mul_2exp(a, a, s); fmpz_set(exp, exp2); } fmpr_clear(t); fmpz_clear(exp2); } }
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); } }
long gamma_taylor_bound_mag(long n) { fmprb_t t, u; long v; fmprb_init(t); fmprb_init(u); /* (pi-1) n */ fmprb_const_pi(t, FMPRB_RAD_PREC); fmprb_sub_ui(t, t, 1, FMPRB_RAD_PREC); fmprb_mul_ui(t, t, n, FMPRB_RAD_PREC); /* (3-5n) log(n/6) */ fmprb_set_ui(u, n); fmprb_div_ui(u, u, 6, FMPRB_RAD_PREC); fmprb_log(u, u, FMPRB_RAD_PREC); fmprb_mul_si(u, u, 3 - 5*n, FMPRB_RAD_PREC); fmprb_add(t, t, u, FMPRB_RAD_PREC); /* divide by 6 log(2) */ fmprb_log_ui(u, 2, FMPRB_RAD_PREC); fmprb_mul_ui(u, u, 6, FMPRB_RAD_PREC); fmprb_div(t, t, u, FMPRB_RAD_PREC); /* upper bound */ fmpr_add(fmprb_midref(t), fmprb_midref(t), fmprb_radref(t), FMPRB_RAD_PREC, FMPR_RND_CEIL); v = fmpr_get_si(fmprb_midref(t), FMPR_RND_CEIL); fmprb_clear(t); fmprb_clear(u); return v; }
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); }
int fmprb_contains(const fmprb_t x, const fmprb_t y) { fmpr_t t; fmpr_t u; fmpr_struct tmp[4]; int left_ok, right_ok; if (fmprb_is_exact(y)) return fmprb_contains_fmpr(x, fmprb_midref(y)); if (fmpr_is_nan(fmprb_midref(y))) return fmpr_is_nan(fmprb_midref(x)); fmpr_init(t); fmpr_init(u); /* fast check */ fmpr_sub(t, fmprb_midref(x), fmprb_radref(x), 30, FMPR_RND_CEIL); fmpr_sub(u, fmprb_midref(y), fmprb_radref(y), 30, FMPR_RND_FLOOR); left_ok = fmpr_cmp(t, u) <= 0; /* exact check */ if (!left_ok) { fmpr_init(tmp + 0); fmpr_init(tmp + 1); fmpr_init(tmp + 2); fmpr_init(tmp + 3); fmpr_set(tmp + 0, fmprb_midref(x)); fmpr_neg(tmp + 1, fmprb_radref(x)); fmpr_neg(tmp + 2, fmprb_midref(y)); fmpr_set(tmp + 3, fmprb_radref(y)); fmpr_sum(t, tmp, 4, 30, FMPR_RND_DOWN); left_ok = fmpr_sgn(t) <= 0; fmpr_clear(tmp + 0); fmpr_clear(tmp + 1); fmpr_clear(tmp + 2); fmpr_clear(tmp + 3); } /* fast check */ fmpr_add(t, fmprb_midref(x), fmprb_radref(x), 30, FMPR_RND_FLOOR); fmpr_add(u, fmprb_midref(y), fmprb_radref(y), 30, FMPR_RND_CEIL); right_ok = (fmpr_cmp(t, u) >= 0); /* exact check */ if (!right_ok) { fmpr_init(tmp + 0); fmpr_init(tmp + 1); fmpr_init(tmp + 2); fmpr_init(tmp + 3); fmpr_set(tmp + 0, fmprb_midref(x)); fmpr_set(tmp + 1, fmprb_radref(x)); fmpr_neg(tmp + 2, fmprb_midref(y)); fmpr_neg(tmp + 3, fmprb_radref(y)); fmpr_sum(t, tmp, 4, 30, FMPR_RND_DOWN); right_ok = fmpr_sgn(t) >= 0; fmpr_clear(tmp + 0); fmpr_clear(tmp + 1); fmpr_clear(tmp + 2); fmpr_clear(tmp + 3); } fmpr_clear(t); fmpr_clear(u); return left_ok && right_ok; }
void fmprb_add_error_fmpr(fmprb_t x, const fmpr_t err) { fmpr_add(fmprb_radref(x), fmprb_radref(x), err, FMPRB_RAD_PREC, FMPR_RND_UP); }
/* convert to an fmpz poly with a common exponent and coefficients at most prec bits, also bounding input error plus rounding error */ void _fmprb_poly_get_fmpz_poly_2exp(fmpr_t error, fmpz_t exp, fmpz * coeffs, fmprb_srcptr A, long lenA, long prec) { fmpz_t top_exp, bot_exp; long shift; long i; int rounding; fmpz_init(top_exp); fmpz_init(bot_exp); if (!_fmprb_poly_mid_get_hull(bot_exp, top_exp, A, lenA)) { fmpz_zero(exp); _fmpz_vec_zero(coeffs, lenA); fmpr_zero(error); for (i = 0; i < lenA; i++) { if (fmpr_cmp(fmprb_radref(A + i), error) > 0) fmpr_set(error, fmprb_radref(A + i)); } return; /* no need to clear fmpzs */ } /* only take as much precision as necessary */ shift = _fmpz_sub_small(top_exp, bot_exp); prec = FLINT_MIN(prec, shift); fmpz_sub_ui(exp, top_exp, prec); /* extract integer polynomial */ rounding = 0; for (i = 0; i < lenA; i++) rounding |= fmpr_get_fmpz_fixed_fmpz(coeffs + i, fmprb_midref(A + i), exp); fmpr_zero(error); /* compute maximum of input errors */ for (i = 0; i < lenA; i++) { if (fmpr_cmp(fmprb_radref(A + i), error) > 0) fmpr_set(error, fmprb_radref(A + i)); } /* add rounding error */ if (rounding) { fmpr_t t; fmpr_init(t); fmpz_set_ui(fmpr_manref(t), 1UL); fmpz_set(fmpr_expref(t), exp); fmpr_add(error, error, t, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_clear(t); } fmpz_clear(top_exp); }
int main() { slong iter; flint_rand_t state; flint_printf("add...."); fflush(stdout); flint_randinit(state); /* test exact addition: (x + y) + z == x + (y + z) */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { slong bits, res1, res2, res3, res4; fmpr_t x, y, z, t, u; bits = 2 + n_randint(state, 200); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(t); fmpr_init(u); fmpr_randtest_special(x, state, bits, 10); fmpr_randtest_special(y, state, bits, 10); fmpr_randtest_special(z, state, bits, 10); fmpr_randtest_special(t, state, bits, 10); fmpr_randtest_special(u, state, bits, 10); res1 = fmpr_add(t, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); res2 = fmpr_add(t, t, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res3 = fmpr_add(u, y, z, FMPR_PREC_EXACT, FMPR_RND_DOWN); res4 = fmpr_add(u, x, u, FMPR_PREC_EXACT, FMPR_RND_DOWN); if (!fmpr_equal(t, u) || res1 != FMPR_RESULT_EXACT || res2 != FMPR_RESULT_EXACT || res3 != FMPR_RESULT_EXACT || res4 != FMPR_RESULT_EXACT) { flint_printf("FAIL\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("t = "); fmpr_print(t); flint_printf("\n\n"); flint_printf("u = "); fmpr_print(u); flint_printf("\n\n"); abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(t); fmpr_clear(u); } /* compare with add_naive */ for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { slong prec, ret1, ret2; fmpr_t x, y, z, w; fmpr_rnd_t rnd; fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); fmpr_randtest_special(x, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); fmpr_randtest_special(y, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); fmpr_randtest_special(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 200)); prec = 2 + n_randint(state, 1000); if (n_randint(state, 10) == 0 && fmpz_bits(fmpr_expref(x)) < 10 && fmpz_bits(fmpr_expref(y)) < 10) prec = FMPR_PREC_EXACT; switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } ret1 = fmpr_add(z, x, y, prec, rnd); ret2 = fmpr_add_naive(w, x, y, prec, rnd); if (!fmpr_equal(z, w) || ret1 != ret2 || !fmpr_check_ulp(z, ret1, prec) || !fmpr_check_ulp(w, ret2, prec)) { flint_printf("FAIL\n\n"); flint_printf("iter %wd\n", iter); flint_printf("prec = %wd\n", prec); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_printf("ret1 = %wd, ret2 = %wd\n", ret1, ret2); abort(); } fmpr_clear(x); fmpr_clear(y); fmpr_clear(z); fmpr_clear(w); } /* compare rounding with mpfr */ for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { slong bits, res; int mpfr_res; fmpr_t x, y, z, w; mpfr_t X, Y, Z; bits = 2 + n_randint(state, 500); fmpr_init(x); fmpr_init(y); fmpr_init(z); fmpr_init(w); mpfr_init2(X, bits + 500); mpfr_init2(Y, bits + 500); mpfr_init2(Z, bits); fmpr_randtest_special(x, state, bits + n_randint(state, 500), 10); fmpr_randtest_special(y, state, bits + n_randint(state, 500), 10); fmpr_randtest_special(z, state, bits, 10); fmpr_get_mpfr(X, x, MPFR_RNDN); fmpr_get_mpfr(Y, y, MPFR_RNDN); switch (n_randint(state, 4)) { case 0: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDZ); res = fmpr_add(z, x, y, bits, FMPR_RND_DOWN); break; case 1: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDA); res = fmpr_add(z, x, y, bits, FMPR_RND_UP); break; case 2: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDD); res = fmpr_add(z, x, y, bits, FMPR_RND_FLOOR); break; default: mpfr_res = mpfr_add(Z, X, Y, MPFR_RNDU); res = fmpr_add(z, x, y, bits, FMPR_RND_CEIL); break; } fmpr_set_mpfr(w, Z); if (!fmpr_equal(z, w) || (res == FMPR_RESULT_EXACT) != (mpfr_res == 0) || !fmpr_check_ulp(z, res, bits)) { flint_printf("FAIL\n\n"); flint_printf("iter %wd\n", iter); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("w = "); fmpr_print(w); flint_printf("\n\n"); flint_printf("returned: %wd, %d\n", res, mpfr_res); abort(); } /* check error bound */ if (!fmpr_is_nan(z) && !fmpr_is_inf(z)) { fmpr_t z_exact, error_bound, true_error; fmpr_init(z_exact); fmpr_init(error_bound); fmpr_init(true_error); fmpr_set_error_result(error_bound, z, res); fmpr_add(z_exact, x, y, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_sub(true_error, z, z_exact, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_abs(true_error, true_error); if (fmpr_is_zero(error_bound) != fmpr_is_zero(true_error) || fmpr_cmp(true_error, error_bound) > 0) { flint_printf("FAIL: error bound\n\n"); flint_printf("bits = %wd\n", bits); flint_printf("x = "); fmpr_print(x); flint_printf("\n\n"); flint_printf("y = "); fmpr_print(y); flint_printf("\n\n"); flint_printf("z = "); fmpr_print(z); flint_printf("\n\n"); flint_printf("z_exact = "); fmpr_print(z_exact); flint_printf("\n\n"); flint_printf("true_error = "); fmpr_print(true_error); flint_printf("\n\n"); flint_printf("error_bound = "); fmpr_print(error_bound); flint_printf("\n\n"); abort(); } fmpr_clear(z_exact); fmpr_clear(error_bound); fmpr_clear(true_error); } 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(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("sum...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++) { slong i, len, prec, bits, expbits, res1, res2; fmpr_t s1, s2, s3, err, err_bound; fmpr_struct terms[20]; fmpr_rnd_t rnd; len = n_randint(state, 20); bits = 2 + n_randint(state, 1000); prec = 2 + n_randint(state, 1000); expbits = n_randint(state, 14); fmpr_init(s1); fmpr_init(s2); fmpr_init(s3); fmpr_init(err); fmpr_init(err_bound); for (i = 0; i < len; i++) { fmpr_init(terms + i); fmpr_randtest_special(terms + i, state, bits, expbits); } switch (n_randint(state, 4)) { case 0: rnd = FMPR_RND_DOWN; break; case 1: rnd = FMPR_RND_UP; break; case 2: rnd = FMPR_RND_FLOOR; break; default: rnd = FMPR_RND_CEIL; break; } res1 = fmpr_sum(s1, terms, len, prec, rnd); fmpr_zero(s2); for (i = 0; i < len; i++) fmpr_add(s2, s2, terms + i, FMPR_PREC_EXACT, FMPR_RND_DOWN); res2 = fmpr_set_round(s3, s2, prec, rnd); if (!fmpr_equal(s1, s3) || res1 != res2 || !fmpr_check_ulp(s1, res1, prec) || !fmpr_check_ulp(s3, res2, prec)) { flint_printf("FAIL (%wd)\n\n", iter); flint_printf("prec = %wd\n\n", prec); for (i = 0; i < len; i++) { flint_printf("terms[%wd] = ", i); fmpr_print(terms + i); flint_printf("\n\n"); } flint_printf("s1 = "); fmpr_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); fmpr_print(s2); flint_printf("\n\n"); flint_printf("s3 = "); fmpr_print(s3); flint_printf("\n\n"); flint_printf("res1 = %wd, res2 = %wd\n\n", res1, res2); abort(); } fmpr_sub(err, s1, s2, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_abs(err, err); fmpr_set_error_result(err_bound, s1, res1); if (fmpr_cmp(err, err_bound) > 0) { flint_printf("FAIL (error bound)!\n"); flint_printf("prec = %wd\n\n", prec); for (i = 0; i < len; i++) { flint_printf("terms[%wd] = ", i); fmpr_print(terms + i); flint_printf("\n\n"); } flint_printf("s1 = "); fmpr_print(s1); flint_printf("\n\n"); flint_printf("s2 = "); fmpr_print(s2); flint_printf("\n\n"); flint_printf("s3 = "); fmpr_print(s3); flint_printf("\n\n"); flint_printf("error: "); fmpr_print(err); flint_printf("\n\n"); flint_printf("error bound: "); fmpr_print(err_bound); flint_printf("\n\n"); flint_printf("res1 = %wd, res2 = %wd\n\n", res1, res2); abort(); } fmpr_clear(s1); fmpr_clear(s2); fmpr_clear(s3); fmpr_clear(err); fmpr_clear(err_bound); for (i = 0; i < len; i++) fmpr_clear(terms + i); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { fmprb_ptr blocks; fmprb_calc_func_t function; int * info; long digits, low_prec, high_prec, i, num, found_roots, found_unknown; long maxdepth, maxeval, maxfound; int refine; double a, b; fmprb_t t; fmpr_t fa, fb, C; if (argc < 4) { printf("real_roots function a b [-refine d] [-verbose] " "[-maxdepth n] [-maxeval n] [-maxfound n] [-prec n]\n"); printf("available functions:\n"); printf(" 0 Z(x), Riemann-Siegel Z-function\n"); printf(" 1 sin(x)\n"); printf(" 2 sin(x^2)\n"); printf(" 3 sin(1/x)\n"); return 1; } switch (atoi(argv[1])) { case 0: function = z_function; break; case 1: function = sin_x; break; case 2: function = sin_x2; break; case 3: function = sin_1x; break; default: printf("require a function 0-3\n"); return 1; } a = atof(argv[2]); b = atof(argv[3]); if (a >= b) { printf("require a < b!\n"); return 1; } refine = 0; digits = 0; maxdepth = 30; maxeval = 100000; maxfound = 100000; low_prec = 30; for (i = 4; i < argc; i++) { if (!strcmp(argv[i], "-refine")) { refine = 1; digits = atol(argv[i+1]); } else if (!strcmp(argv[i], "-verbose")) { fmprb_calc_verbose = 1; } else if (!strcmp(argv[i], "-maxdepth")) { maxdepth = atol(argv[i+1]); } else if (!strcmp(argv[i], "-maxeval")) { maxeval = atol(argv[i+1]); } else if (!strcmp(argv[i], "-maxfound")) { maxfound = atol(argv[i+1]); } else if (!strcmp(argv[i], "-prec")) { low_prec = atol(argv[i+1]); } } high_prec = digits * 3.32192809488736 + 10; found_roots = 0; found_unknown = 0; fmprb_init(t); fmpr_init(C); fmpr_init(fa); fmpr_init(fb); fmpr_set_d(fa, a); fmpr_set_d(fb, b); fmpr_add(fmprb_midref(t), fb, fa, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmpr_sub(fmprb_radref(t), fb, fa, FMPR_PREC_EXACT, FMPR_RND_DOWN); fmprb_mul_2exp_si(t, t, -1); printf("interval: "); fmprb_printd(t, 15); printf("\n"); printf("maxdepth = %ld, maxeval = %ld, maxfound = %ld, low_prec = %ld\n", maxdepth, maxeval, maxfound, low_prec); TIMEIT_ONCE_START num = fmprb_calc_isolate_roots(&blocks, &info, function, NULL, t, maxdepth, maxeval, maxfound, low_prec); for (i = 0; i < num; i++) { if (info[i] != 1) { if (fmprb_calc_verbose) { printf("unable to count roots in "); fmprb_printd(blocks + i, 15); printf("\n"); } found_unknown++; continue; } found_roots++; if (!refine) continue; if (fmprb_calc_refine_root_bisect(t, function, NULL, blocks + i, 5, low_prec) != FMPRB_CALC_SUCCESS) { printf("warning: some bisection steps failed!\n"); } if (fmprb_calc_verbose) { printf("after bisection 1: "); fmprb_printd(t, 15); printf("\n"); } if (fmprb_calc_refine_root_bisect(blocks + i, function, NULL, t, 5, low_prec) != FMPRB_CALC_SUCCESS) { printf("warning: some bisection steps failed!\n"); } if (fmprb_calc_verbose) { printf("after bisection 2: "); fmprb_printd(blocks + i, 15); printf("\n"); } fmprb_calc_newton_conv_factor(C, function, NULL, t, low_prec); if (fmprb_calc_refine_root_newton(blocks + i, function, NULL, blocks + i, t, C, 10, high_prec) != FMPRB_CALC_SUCCESS) { printf("warning: some newton steps failed!\n"); } printf("refined root:\n"); fmprb_printd(blocks + i, digits + 2); printf("\n\n"); } printf("---------------------------------------------------------------\n"); printf("Found roots: %ld\n", found_roots); printf("Subintervals possibly containing undetected roots: %ld\n", found_unknown); printf("Function evaluations: %ld\n", eval_count); TIMEIT_ONCE_STOP SHOW_MEMORY_USAGE fmprb_clear(t); fmpr_clear(C); fmpr_clear(fa); fmpr_clear(fb); flint_cleanup(); return 0; }