void test_1(fmpz_t n) { mpfr_t q0; mpfr_init(q0); mpfr_t q1; mpfr_init(q1); fmpz_t m; fmpz_init(m); int c; fmpz_get_mpfr( q0, n , MPFR_RNDA ); fmpz_get_mpfr_3arg(q1, n[0], MPFR_RNDA ); assert( mpfr_equal_p( q0, q1 ) ); fmpz_set_mpfr(m, q0, MPFR_RNDA); if( fmpz_cmp_ui( n, WORD(0) ) >= 0 ) { if( fmpz_cmp(n,m) > 0 ) { flint_printf("RNDA test failed, n="); fmpz_print(n); flint_printf(", m="); fmpz_print(m); flint_printf("\n"); assert(0); } fmpz_sub(m, m, n); IF_MORE_THAN_2; } else { if( fmpz_cmp(n,m) < 0 ) { flint_printf("RNDA test failed, n="); fmpz_print(n); flint_printf(", m="); fmpz_print(m); flint_printf("\n"); assert(0); } fmpz_sub(m, n, m); IF_MORE_THAN_2; } fmpz_get_mpfr( q0, n, MPFR_RNDZ ); fmpz_set_mpfr( m, q0, MPFR_RNDZ ); c=fmpz_cmp_si( n, WORD(0) ); if(c==0) assert(0 == fmpz_cmp_si(m,WORD(0))); else { if(c<0) { fmpz_neg(n, n); fmpz_neg(m, m); } assert( fmpz_cmp(n,m) >= 0 ); if(c) assert( fmpz_cmp_si(m,WORD(0)) >= 0 ); fmpz_sub(m, n, m); IF_MORE_THAN_2_AGAIN; } fmpz_clear(m); mpfr_clear(q1); mpfr_clear(q0); }
slong hypgeom_root_norm(const fmpz_poly_t P) { slong res, i, p; fmpz_t t, A; fmpz_init(A); fmpz_init(t); p = fmpz_poly_degree(P); fmpz_zero(A); for (i = 1; i <= p; i++) { fmpz_cdiv_abs_q(t, P->coeffs + p - i, P->coeffs + p); fmpz_root(t, t, i); fmpz_add_ui(t, t, 1); if (fmpz_cmp(t, A) > 0) fmpz_swap(t, A); } if (!fmpz_fits_si(A)) abort(); res = fmpz_get_si(A); fmpz_clear(A); fmpz_clear(t); return res; }
int _arf_are_close(const arf_t x, const arf_t y, long prec) { fmpz_t xb, yb; fmpz_t delta; int result; fmpz_init(xb); fmpz_init(yb); fmpz_init(delta); arf_bot(xb, x); arf_bot(yb, y); if (fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)) >= 0) fmpz_sub(delta, xb, ARF_EXPREF(y)); else fmpz_sub(delta, yb, ARF_EXPREF(x)); fmpz_sub_ui(delta, delta, 64); result = (fmpz_cmp_ui(delta, prec) < 0); fmpz_clear(xb); fmpz_clear(yb); fmpz_clear(delta); return result; }
void bernoulli_rev_init(bernoulli_rev_t iter, ulong nmax) { long j; fmpz_t t; fmprb_t x; int round1, round2; long wp; nmax -= (nmax % 2); iter->n = nmax; iter->alloc = 0; if (nmax < BERNOULLI_REV_MIN) return; iter->prec = wp = global_prec(nmax); iter->max_power = zeta_terms(nmax, iter->prec); iter->alloc = iter->max_power + 1; iter->powers = _fmpz_vec_init(iter->alloc); fmpz_init(iter->pow_error); fmprb_init(iter->prefactor); fmprb_init(iter->two_pi_squared); fmprb_init(x); fmpz_init(t); /* precompute powers */ for (j = 3; j <= iter->max_power; j += 2) { fmprb_ui_pow_ui(x, j, nmax, power_prec(j, nmax, wp)); fmprb_ui_div(x, 1UL, x, power_prec(j, nmax, wp)); round1 = fmpr_get_fmpz_fixed_si(t, fmprb_midref(x), -wp); fmpz_set(iter->powers + j, t); /* error: the radius, plus two roundings */ round2 = fmpr_get_fmpz_fixed_si(t, fmprb_radref(x), -wp); fmpz_add_ui(t, t, (round1 != 0) + (round2 != 0)); if (fmpz_cmp(iter->pow_error, t) < 0) fmpz_set(iter->pow_error, t); } /* precompute (2pi)^2 and 2*(n!)/(2pi)^n */ fmprb_fac_ui(iter->prefactor, nmax, wp); fmprb_mul_2exp_si(iter->prefactor, iter->prefactor, 1); fmprb_const_pi(x, wp); fmprb_mul_2exp_si(x, x, 1); fmprb_mul(iter->two_pi_squared, x, x, wp); fmprb_pow_ui(x, iter->two_pi_squared, nmax / 2, wp); fmprb_div(iter->prefactor, iter->prefactor, x, wp); fmpz_clear(t); fmprb_clear(x); }
int _fmprb_poly_mid_get_hull(fmpz_t bot_exp, fmpz_t top_exp, fmprb_srcptr A, long lenA) { long i; fmpz_t t; int have_nonzero = 0; fmpz_init(t); fmpz_zero(bot_exp); fmpz_zero(top_exp); for (i = 0; i < lenA; i++) { if (fmpr_is_normal(fmprb_midref(A + i))) { if (!have_nonzero) { have_nonzero = 1; fmpr_get_bot_exp(bot_exp, fmprb_midref(A + i)); fmpr_get_top_exp(top_exp, fmprb_midref(A + i)); } else { fmpr_get_bot_exp(t, fmprb_midref(A + i)); if (fmpz_cmp(t, bot_exp) < 0) fmpz_swap(t, bot_exp); fmpr_get_top_exp(t, fmprb_midref(A + i)); if (fmpz_cmp(t, top_exp) > 0) fmpz_swap(t, top_exp); } } else if (!fmpr_is_zero(fmprb_midref(A + i))) { printf("exception: inf or nan encountered in polynomial\n"); abort(); } } fmpz_clear(t); return have_nonzero; }
static __inline__ long _zeta_function(const fmpz_t p, long a, long n, long d) { const long b = gmc_basis_size(n, d); long i, N; fmpz_t f, g, max; fmpz_init(f); fmpz_init(g); fmpz_init(max); if (n == 3 && fmpz_cmp_ui(p, 2) != 0) { fmpz_bin_uiui(f, d-1, 3); fmpz_bin_uiui(g, b, b / 2); fmpz_mul_ui(g, g, 2); N = a * (*f) + fmpz_clog(g, p); } else if (n % 2L == 0) /* n even implies b even */ { fmpz_bin_uiui(f, b, b / 2); fmpz_pow_ui(g, p, (a * (b / 2) * (n - 1) + 1) / 2); fmpz_mul(f, f, g); fmpz_mul_ui(f, f, 2); N = fmpz_flog(f, p) + 1; } else { for (i = b / 2; i <= b; i++) { fmpz_bin_uiui(f, b, i); fmpz_pow_ui(g, p, (a * i * (n - 1) + 1) / 2); fmpz_mul(f, f, g); fmpz_mul_ui(f, f, 2); if (fmpz_cmp(max, f) < 0) fmpz_swap(max, f); } N = fmpz_flog(max, p) + 1; } fmpz_clear(f); fmpz_clear(g); fmpz_clear(max); return N; }
void _fmpz_vec_scalar_smod_fmpz(fmpz *res, const fmpz *vec, slong len, const fmpz_t p) { slong i; fmpz_t pdiv2; fmpz_init(pdiv2); fmpz_fdiv_q_2exp(pdiv2, p, 1); for (i = 0; i < len; i++) { fmpz_mod(res + i, vec + i, p); if (fmpz_cmp(res + i, pdiv2) > 0) { fmpz_sub(res + i, res + i, p); } } fmpz_clear(pdiv2); }
int arf_cmpabs(const arf_t x, const arf_t y) { int ec, mc; mp_size_t xn, yn; mp_srcptr xp, yp; if (arf_is_special(x) || arf_is_special(y)) { if (arf_equal(x, y)) return 0; if (arf_is_nan(x) || arf_is_nan(y)) return 0; if (arf_is_zero(x)) return -1; if (arf_is_zero(y)) return 1; if (arf_is_inf(x)) return arf_is_inf(y) ? 0 : 1; if (arf_is_inf(y)) return -1; return -1; } ec = fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)); if (ec != 0) return (ec < 0) ? -1 : 1; ARF_GET_MPN_READONLY(xp, xn, x); ARF_GET_MPN_READONLY(yp, yn, y); if (xn >= yn) mc = mpn_cmp(xp + xn - yn, yp, yn); else mc = mpn_cmp(xp, yp + yn - xn, xn); if (mc != 0) return (mc < 0) ? -1 : 1; if (xn != yn) return (xn < yn) ? -1 : 1; return 0; }
int fmpr_cmp(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(y)) return fmpr_sgn(x); if (fmpr_is_zero(x)) return -fmpr_sgn(y); if (fmpr_is_pos_inf(x)) return 1; if (fmpr_is_neg_inf(y)) return 1; return -1; } xsign = fmpr_sgn(x); ysign = fmpr_sgn(y); if (xsign != ysign) return (xsign < 0) ? -1 : 1; /* Reduces to integer comparison if bottom exponents are the same */ if (fmpz_equal(fmpr_expref(x), fmpr_expref(y))) return fmpz_cmp(fmpr_manref(x), fmpr_manref(y)) < 0 ? -1 : 1; /* TODO: compare position of top exponents to avoid subtraction */ fmpr_init(t); fmpr_sub(t, x, y, 2, FMPR_RND_DOWN); res = fmpr_sgn(t); fmpr_clear(t); return res; }
void fmpz_mat_solve_bound(fmpz_t N, fmpz_t D, const fmpz_mat_t A, const fmpz_mat_t B) { slong i, j, m, n; fmpz_t t, u; m = B->r; n = B->c; fmpz_mat_det_bound(D, A); fmpz_init(t); fmpz_init(u); fmpz_zero(t); /* Largest column norm of B */ for (j = 0; j < n; j++) { fmpz_zero(u); for (i = 0; i < m; i++) fmpz_addmul(u, fmpz_mat_entry(B, i, j), fmpz_mat_entry(B, i, j)); if (fmpz_cmp(t, u) < 0) fmpz_set(t, u); } fmpz_sqrtrem(t, u, t); if (!fmpz_is_zero(u)) fmpz_add_ui(t, t, UWORD(1)); fmpz_mul(N, D, t); fmpz_clear(t); fmpz_clear(u); }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("divrem_f...."); fflush(stdout); /* Check q*b + r = a when gcd(lead(B),p) = 1, no aliasing */ for (i = 0; i < 5000; i++) { fmpz_t f, p; fmpz_mod_poly_t a, b, q, r, t; fmpz_init(f); fmpz_init(p); fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); fmpz_add_ui(p, p, 2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_init(r, p); fmpz_mod_poly_init(t, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); while (!fmpz_is_one(d)) { fmpz_divexact(leadB, leadB, d); fmpz_gcd(d, p, leadB); } fmpz_clear(d); } fmpz_mod_poly_divrem_f(f, q, r, a, b); fmpz_mod_poly_mul(t, q, b); fmpz_mod_poly_add(t, t, r); result = (fmpz_is_one(f) && fmpz_mod_poly_equal(a, t)); if (!result) { flint_printf("FAIL (divrem):\n"); flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_mod_poly_clear(r); fmpz_mod_poly_clear(t); fmpz_clear(f); fmpz_clear(p); } /* Check f | p when gcd(lead(B),p) > 1 */ for (i = 0; i < 5000; i++) { fmpz_t f, p, q1, q2; fmpz_mod_poly_t a, b, q, r, t; fmpz_init(f); fmpz_init(p); fmpz_init(q1); fmpz_init(q2); fmpz_randtest_unsigned(q1, state, 2 * FLINT_BITS); fmpz_randtest_unsigned(q2, state, 2 * FLINT_BITS); fmpz_add_ui(q1, q1, 2); fmpz_add_ui(q2, q2, 2); fmpz_mul(p, q1, q2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_init(r, p); fmpz_mod_poly_init(t, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); if (fmpz_is_one(d)) fmpz_set(leadB, q1); fmpz_clear(d); } fmpz_mod_poly_divrem_f(f, q, r, a, b); fmpz_mod_poly_mul(t, q, b); fmpz_mod_poly_add(t, t, r); result = (fmpz_cmp_ui(f, 1) > 0 && fmpz_cmp(f, p) < 0 && fmpz_divisible(p, f)); if (!result) { flint_printf("FAIL (factor):\n"); flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); flint_printf("q1 = "), fmpz_print(q1), flint_printf("\n\n"); flint_printf("q2 = "), fmpz_print(q2), flint_printf("\n\n"); flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_mod_poly_clear(r); fmpz_mod_poly_clear(t); fmpz_clear(f); fmpz_clear(p); fmpz_clear(q1); fmpz_clear(q2); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
int arb_get_unique_fmpz(fmpz_t z, const arb_t x) { if (!arb_is_finite(x)) { return 0; } else if (arb_is_exact(x)) { /* x = b*2^e, e >= 0 */ if (arf_is_int(arb_midref(x))) { /* arf_get_fmpz aborts on overflow */ arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN); return 1; } else { return 0; } } /* if the radius is >= 1, there are at least two integers */ else if (mag_cmp_2exp_si(arb_radref(x), 0) >= 0) { return 0; } /* there are 0 or 1 integers if the radius is < 1 */ else { fmpz_t a, b, exp; int res; /* if the midpoint is exactly an integer, it is what we want */ if (arf_is_int(arb_midref(x))) { /* arf_get_fmpz aborts on overflow */ arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN); return 1; } fmpz_init(a); fmpz_init(b); fmpz_init(exp); /* if the radius is tiny, it can't be an integer */ arf_bot(a, arb_midref(x)); if (fmpz_cmp(a, MAG_EXPREF(arb_radref(x))) > 0) { res = 0; } else { arb_get_interval_fmpz_2exp(a, b, exp, x); if (COEFF_IS_MPZ(*exp)) { flint_printf("arb_get_unique_fmpz: input too large\n"); abort(); } if (*exp >= 0) { res = fmpz_equal(a, b); if (res) { fmpz_mul_2exp(a, a, *exp); fmpz_mul_2exp(b, b, *exp); } } else { fmpz_cdiv_q_2exp(a, a, -(*exp)); fmpz_fdiv_q_2exp(b, b, -(*exp)); res = fmpz_equal(a, b); } if (res) fmpz_set(z, a); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); return res; } }
void _arb_bell_sum_taylor(arb_t res, const fmpz_t n, const fmpz_t a, const fmpz_t b, const fmpz_t mmag, long tol) { fmpz_t m, r, R, tmp; mag_t B, C, D, bound; arb_t t, u; long wp, k, N; if (_fmpz_sub_small(b, a) < 5) { arb_bell_sum_bsplit(res, n, a, b, mmag, tol); return; } fmpz_init(m); fmpz_init(r); fmpz_init(R); fmpz_init(tmp); /* r = max(m - a, b - m) */ /* m = a + (b - a) / 2 */ fmpz_sub(r, b, a); fmpz_cdiv_q_2exp(r, r, 1); fmpz_add(m, a, r); fmpz_mul_2exp(R, r, RADIUS_BITS); mag_init(B); mag_init(C); mag_init(D); mag_init(bound); arb_init(t); arb_init(u); if (fmpz_cmp(R, m) >= 0) { mag_inf(C); mag_inf(D); } else { /* C = exp(R * |F'(m)| + (1/2) R^2 * (n/(m-R)^2 + 1/(m-R))) */ /* C = exp(R * (|F'(m)| + (1/2) R * (n/(m-R) + 1)/(m-R))) */ /* D = (1/2) R * (n/(m-R) + 1)/(m-R) */ fmpz_sub(tmp, m, R); mag_set_fmpz(D, n); mag_div_fmpz(D, D, tmp); mag_one(C); mag_add(D, D, C); mag_div_fmpz(D, D, tmp); mag_mul_fmpz(D, D, R); mag_mul_2exp_si(D, D, -1); /* C = |F'(m)| */ wp = 20 + 1.05 * fmpz_bits(n); arb_set_fmpz(t, n); arb_div_fmpz(t, t, m, wp); fmpz_add_ui(tmp, m, 1); arb_set_fmpz(u, tmp); arb_digamma(u, u, wp); arb_sub(t, t, u, wp); arb_get_mag(C, t); /* C = exp(R * (C + D)) */ mag_add(C, C, D); mag_mul_fmpz(C, C, R); mag_exp(C, C); } if (mag_cmp_2exp_si(C, tol / 4 + 2) > 0) { _arb_bell_sum_taylor(res, n, a, m, mmag, tol); _arb_bell_sum_taylor(t, n, m, b, mmag, tol); arb_add(res, res, t, 2 * tol); } else { arb_ptr mx, ser1, ser2, ser3; /* D = T(m) */ wp = 20 + 1.05 * fmpz_bits(n); arb_set_fmpz(t, m); arb_pow_fmpz(t, t, n, wp); fmpz_add_ui(tmp, m, 1); arb_gamma_fmpz(u, tmp, wp); arb_div(t, t, u, wp); arb_get_mag(D, t); /* error bound: (b-a) * C * D * B^N / (1 - B), B = r/R */ /* ((b-a) * C * D * 2) * 2^(-N*RADIUS_BITS) */ /* ((b-a) * C * D * 2) */ mag_mul(bound, C, D); mag_mul_2exp_si(bound, bound, 1); fmpz_sub(tmp, b, a); mag_mul_fmpz(bound, bound, tmp); /* N = (tol + log2((b-a)*C*D*2) - mmag) / RADIUS_BITS */ if (mmag == NULL) { /* estimate D ~= 2^mmag */ fmpz_add_ui(tmp, MAG_EXPREF(C), tol); fmpz_cdiv_q_ui(tmp, tmp, RADIUS_BITS); } else { fmpz_sub(tmp, MAG_EXPREF(bound), mmag); fmpz_add_ui(tmp, tmp, tol); fmpz_cdiv_q_ui(tmp, tmp, RADIUS_BITS); } if (fmpz_cmp_ui(tmp, 5 * tol / 4) > 0) N = 5 * tol / 4; else if (fmpz_cmp_ui(tmp, 2) < 0) N = 2; else N = fmpz_get_ui(tmp); /* multiply by 2^(-N*RADIUS_BITS) */ mag_mul_2exp_si(bound, bound, -N * RADIUS_BITS); mx = _arb_vec_init(2); ser1 = _arb_vec_init(N); ser2 = _arb_vec_init(N); ser3 = _arb_vec_init(N); /* estimate (this should work for moderate n and tol) */ wp = 1.1 * tol + 1.05 * fmpz_bits(n) + 5; /* increase precision until convergence */ while (1) { /* (m+x)^n / gamma(m+1+x) */ arb_set_fmpz(mx, m); arb_one(mx + 1); _arb_poly_log_series(ser1, mx, 2, N, wp); for (k = 0; k < N; k++) arb_mul_fmpz(ser1 + k, ser1 + k, n, wp); arb_add_ui(mx, mx, 1, wp); _arb_poly_lgamma_series(ser2, mx, 2, N, wp); _arb_vec_sub(ser1, ser1, ser2, N, wp); _arb_poly_exp_series(ser3, ser1, N, N, wp); /* t = a - m, u = b - m */ arb_set_fmpz(t, a); arb_sub_fmpz(t, t, m, wp); arb_set_fmpz(u, b); arb_sub_fmpz(u, u, m, wp); arb_power_sum_vec(ser1, t, u, N, wp); arb_zero(res); for (k = 0; k < N; k++) arb_addmul(res, ser3 + k, ser1 + k, wp); if (mmag != NULL) { if (_fmpz_sub_small(MAG_EXPREF(arb_radref(res)), mmag) <= -tol) break; } else { if (arb_rel_accuracy_bits(res) >= tol) break; } wp = 2 * wp; } /* add the series truncation bound */ arb_add_error_mag(res, bound); _arb_vec_clear(mx, 2); _arb_vec_clear(ser1, N); _arb_vec_clear(ser2, N); _arb_vec_clear(ser3, N); } mag_clear(B); mag_clear(C); mag_clear(D); mag_clear(bound); arb_clear(t); arb_clear(u); fmpz_clear(m); fmpz_clear(r); fmpz_clear(R); fmpz_clear(tmp); }
inline int integer_comp(void* v1,void* v2){return fmpz_cmp((fmpz*)v1,(fmpz*)v2);}