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); }
static slong _fmpr_add_special(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_zero(x)) { if (fmpr_is_zero(y)) { fmpr_zero(z); return FMPR_RESULT_EXACT; } else return fmpr_set_round(z, y, prec, rnd); } else if (fmpr_is_zero(y)) { return fmpr_set_round(z, x, prec, rnd); } else if (fmpr_is_nan(x) || fmpr_is_nan(y) || (fmpr_is_pos_inf(x) && fmpr_is_neg_inf(y)) || (fmpr_is_neg_inf(x) && fmpr_is_pos_inf(y))) { fmpr_nan(z); return FMPR_RESULT_EXACT; } else if (fmpr_is_special(x)) { fmpr_set(z, x); return FMPR_RESULT_EXACT; } else { fmpr_set(z, y); return FMPR_RESULT_EXACT; } }
slong fmpr_mul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpz xv, yv; fmpz yexp; if (fmpr_is_special(x) || fmpz_is_zero(y)) { if (fmpr_is_zero(x)) { fmpr_zero(z); } else if (fmpz_is_zero(y) && fmpr_is_finite(x)) { fmpr_zero(z); } else if (fmpr_is_inf(x) && !fmpz_is_zero(y)) { if (fmpr_sgn(x) == fmpz_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); yv = *y; if (!COEFF_IS_MPZ(xv) && !COEFF_IS_MPZ(yv)) { mp_limb_t ytmp; unsigned int bc; ytmp = FLINT_ABS(yv); count_trailing_zeros(bc, ytmp); ytmp >>= bc; yexp = bc; return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), ytmp, &yexp, (xv ^ yv) < 0, prec, rnd); }
void _fmpcb_poly_refine_roots_durand_kerner(fmpcb_ptr roots, fmpcb_srcptr poly, long len, long prec) { long i, j; fmpcb_t x, y, t; fmpcb_init(x); fmpcb_init(y); fmpcb_init(t); for (i = 0; i < len - 1; i++) { _fmpcb_poly_evaluate_mid(x, poly, len, roots + i, prec); fmpcb_set(y, poly + len - 1); for (j = 0; j < len - 1; j++) { if (i != j) { fmpcb_sub_mid(t, roots + i, roots + j, prec); fmpcb_mul_mid(y, y, t, prec); } } fmpr_zero(fmprb_radref(fmpcb_realref(y))); fmpr_zero(fmprb_radref(fmpcb_imagref(y))); fmpcb_inv_mid(t, y, prec); fmpcb_mul_mid(t, t, x, prec); fmpcb_sub_mid(roots + i, roots + i, t, prec); fmpr_set_round(fmprb_radref(fmpcb_realref(roots + i)), fmprb_midref(fmpcb_realref(t)), FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_set_round(fmprb_radref(fmpcb_imagref(roots + i)), fmprb_midref(fmpcb_imagref(t)), FMPRB_RAD_PREC, FMPR_RND_UP); } fmpcb_clear(x); fmpcb_clear(y); fmpcb_clear(t); }
slong fmpr_rsqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { slong r; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_pos_inf(y); else if (fmpr_is_pos_inf(x)) fmpr_zero(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } if (fmpr_sgn(x) < 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } /* special case: 4^n */ if (fmpz_is_one(fmpr_manref(x)) && fmpz_is_even(fmpr_expref(x))) { r = fmpr_set_round(y, x, prec, rnd); fmpz_tdiv_q_2exp(fmpr_expref(y), fmpr_expref(y), 1); fmpz_neg(fmpr_expref(y), fmpr_expref(y)); return r; } { fmpr_t t; fmpz_t e; fmpr_init(t); fmpz_init(e); fmpz_neg(e, fmpr_expref(x)); if (fmpz_is_odd(e)) fmpz_add_ui(e, e, 1); fmpr_mul_2exp_fmpz(t, x, e); CALL_MPFR_FUNC(r, mpfr_rec_sqrt, y, t, prec, rnd); fmpz_tdiv_q_2exp(e, e, 1); fmpr_mul_2exp_fmpz(y, y, e); fmpr_clear(t); fmpz_clear(e); return r; } }
void fmprb_vec_get_fmpr_2norm_squared_bound(fmpr_t s, fmprb_srcptr vec, long len, long prec) { long i; fmpr_t t; fmpr_init(t); fmpr_zero(s); for (i = 0; i < len; i++) { fmprb_get_abs_ubound_fmpr(t, vec + i, prec); fmpr_addmul(s, t, t, prec, FMPR_RND_UP); } fmpr_clear(t); }
void zeta_ui_borwein_bsplit(fmprb_t x, ulong s, long prec) { zeta_bsplit_t sum; fmpr_t err; long wp, n; /* zeta(0) = -1/2 */ if (s == 0) { fmpr_set_si_2exp_si(fmprb_midref(x), -1, -1); fmpr_zero(fmprb_radref(x)); return; } if (s == 1) { printf("zeta_ui_borwein_bsplit: zeta(1)"); abort(); } n = prec / ERROR_B + 2; wp = prec + 30; zeta_bsplit_init(sum); zeta_bsplit(sum, 0, n + 1, n, s, 0, wp); /* A/Q3 - B/Q3 / (C/Q1) = (A*C - B*Q1) / (Q3*C) */ fmprb_mul(sum->A, sum->A, sum->C, wp); fmprb_mul(sum->B, sum->B, sum->Q1, wp); fmprb_sub(sum->A, sum->A, sum->B, wp); fmprb_mul(sum->Q3, sum->Q3, sum->C, wp); fmprb_div(sum->C, sum->A, sum->Q3, wp); fmpr_init(err); borwein_error(err, n); fmprb_add_error_fmpr(sum->C, err); fmpr_clear(err); /* convert from eta(s) to zeta(s) */ fmprb_div_2expm1_ui(x, sum->C, s - 1, wp); fmprb_mul_2exp_si(x, x, s - 1); zeta_bsplit_clear(sum); }
static void _fmpr_div_special(fmpr_t z, const fmpr_t x, const fmpr_t y) { if ((fmpr_is_zero(x) && !fmpr_is_zero(y) && !fmpr_is_nan(y)) || (fmpr_is_inf(y) && !fmpr_is_special(x))) { fmpr_zero(z); } else if (fmpr_is_zero(y) || (fmpr_is_special(x) && fmpr_is_special(y)) || fmpr_is_nan(x) || fmpr_is_nan(y)) { fmpr_nan(z); } else if (fmpr_sgn(x) == fmpr_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); }
void arf_get_fmpr(fmpr_t y, const arf_t x) { if (arf_is_special(x)) { if (arf_is_zero(x)) fmpr_zero(y); else if (arf_is_pos_inf(x)) fmpr_pos_inf(y); else if (arf_is_neg_inf(x)) fmpr_neg_inf(y); else fmpr_nan(y); } else { arf_get_fmpz_2exp(fmpr_manref(y), fmpr_expref(y), x); } }
void fmpr_randtest_special(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) { switch (n_randint(state, 32)) { case 0: fmpr_zero(x); break; case 1: fmpr_pos_inf(x); break; case 2: fmpr_neg_inf(x); break; case 3: fmpr_nan(x); break; default: fmpr_randtest_not_zero(x, state, bits, mag_bits); } }
void bound_rfac(fmprb_ptr F, const fmpcb_t s, ulong n, long len, long wp) { if (len == 1) { fmpcb_rfac_abs_ubound2(fmprb_midref(F + 0), s, n, wp); fmpr_zero(fmprb_radref(F + 0)); } else { fmprb_struct sx[2]; fmprb_init(sx + 0); fmprb_init(sx + 1); fmpcb_abs(sx + 0, s, wp); fmprb_one(sx + 1); _fmprb_vec_zero(F, len); _fmprb_poly_rising_ui_series(F, sx, 2, n, len, wp); fmprb_clear(sx + 0); fmprb_clear(sx + 1); } }
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); } }
/* 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); }
void zeta_series_em_vec_bound(fmprb_ptr bound, const fmpcb_t s, const fmpcb_t a, ulong N, ulong M, long len, long wp) { fmprb_t K, C, AN, S2M; fmprb_ptr F, R; long k; fmprb_srcptr alpha = fmpcb_realref(a); fmprb_srcptr beta = fmpcb_imagref(a); fmprb_srcptr sigma = fmpcb_realref(s); fmprb_srcptr tau = fmpcb_imagref(s); fmprb_init(AN); fmprb_init(S2M); /* require alpha + N > 1, sigma + 2M > 1 */ fmprb_add_ui(AN, alpha, N - 1, wp); fmprb_add_ui(S2M, sigma, 2*M - 1, wp); if (!fmprb_is_positive(AN) || !fmprb_is_positive(S2M) || N < 1 || M < 1) { fmprb_clear(AN); fmprb_clear(S2M); for (k = 0; k < len; k++) { fmpr_pos_inf(fmprb_midref(bound + k)); fmpr_zero(fmprb_radref(bound + k)); } return; } /* alpha + N, sigma + 2M */ fmprb_add_ui(AN, AN, 1, wp); fmprb_add_ui(S2M, S2M, 1, wp); R = _fmprb_vec_init(len); F = _fmprb_vec_init(len); fmprb_init(K); fmprb_init(C); /* bound for power integral */ bound_C(C, AN, beta, wp); bound_K(K, AN, beta, tau, wp); bound_I(R, AN, S2M, C, len, wp); for (k = 0; k < len; k++) { fmprb_mul(R + k, R + k, K, wp); fmprb_div_ui(K, K, k + 1, wp); } /* bound for rising factorial */ bound_rfac(F, s, 2*M, len, wp); /* product (TODO: only need upper bound; write a function for this) */ _fmprb_poly_mullow(bound, F, len, R, len, len, wp); /* bound for bernoulli polynomials, 4 / (2pi)^(2M) */ fmprb_const_pi(C, wp); fmprb_mul_2exp_si(C, C, 1); fmprb_pow_ui(C, C, 2 * M, wp); fmprb_ui_div(C, 4, C, wp); _fmprb_vec_scalar_mul(bound, bound, len, C, wp); fmprb_clear(K); fmprb_clear(C); fmprb_clear(AN); fmprb_clear(S2M); _fmprb_vec_clear(R, len); _fmprb_vec_clear(F, len); }
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; }