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 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); } }
void fmpr_randtest_not_zero(fmpr_t x, flint_rand_t state, slong bits, slong mag_bits) { fmpz_randtest_not_zero(fmpr_manref(x), state, bits); fmpz_randtest(fmpr_expref(x), state, mag_bits); fmpz_sub_ui(fmpr_expref(x), fmpr_expref(x), fmpz_bits(fmpr_manref(x))); _fmpr_normalise(fmpr_manref(x), fmpr_expref(x), bits, FMPR_RND_DOWN); }
void _fmprb_get_rand_fmpq(fmpz_t num, fmpz_t den, flint_rand_t state, const fmpz_t den_mult, const fmprb_t x) { fmpz_t a, b, exp; fmpz_init(a); fmpz_init(b); fmpz_init(exp); fmprb_get_interval_fmpz_2exp(a, b, exp, x); if (COEFF_IS_MPZ(*exp)) { printf("exception: fmprb_get_rand_fmpq: too large exponent\n"); abort(); } if (*exp >= 0) { fmpz_mul_2exp(a, a, *exp); fmpz_mul_2exp(b, b, *exp); } /* generate random integer in [a*den, b*den] */ fmpz_mul(a, a, den_mult); fmpz_mul(b, b, den_mult); fmpz_add_ui(b, b, 1UL); fmpz_sub(b, b, a); /* return one endpoint with high probability (used for stress testing rounding) */ if (n_randint(state, 6) == 0) { if (n_randint(state, 2)) fmpz_zero(num); else fmpz_sub_ui(num, b, 1UL); } else { fmpz_randtest_mod(num, state, b); } fmpz_add(num, num, a); fmpz_set(den, den_mult); if (*exp < 0) fmpz_mul_2exp(den, den, -(*exp)); fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); }
int padic_log_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx) { if (padic_val(op) < 0) { return 0; } else { fmpz_t x; int ans; fmpz_init(x); padic_get_fmpz(x, op, ctx); fmpz_sub_ui(x, x, 1); if (fmpz_is_zero(x)) { padic_zero(rop); ans = 1; } else { fmpz_t t; long v; fmpz_init(t); v = fmpz_remove(t, x, ctx->p); fmpz_clear(t); if (v >= 2 || (*(ctx->p) != 2L && v >= 1)) { if (v >= ctx->N) { padic_zero(rop); } else { _padic_log_balanced(padic_unit(rop), x, v, ctx->p, ctx->N); padic_val(rop) = 0; padic_reduce(rop, ctx); } ans = 1; } else { ans = 0; } } fmpz_clear(x); return ans; } }
int main(void) { long i; fmpz_t x; printf("fits_si...."); fflush(stdout); fmpz_init(x); fmpz_set_si(x, COEFF_MIN); check(x, 1); fmpz_set_si(x, COEFF_MAX); check(x, 1); fmpz_set_si(x, LONG_MAX); check(x, 1); fmpz_set_si(x, LONG_MIN); check(x, 1); fmpz_set_ui(x, ULONG_MAX); check(x, 0); fmpz_set_ui(x, ULONG_MAX); fmpz_neg(x, x); check(x, 0); fmpz_set_si(x, LONG_MAX); fmpz_add_ui(x, x, 1); check(x, 0); fmpz_set_si(x, LONG_MIN); fmpz_sub_ui(x, x, 1); check(x, 0); for (i = 0; i < 1000; i++) { fmpz_set_ui(x, 1); fmpz_mul_2exp(x, x, i); check(x, i < FLINT_BITS - 1); fmpz_neg(x, x); check(x, i < FLINT_BITS); /* LONG_MIN fits */ } fmpz_clear(x); _fmpz_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m) { fmpz_t t; fmpz_init(t); fmpz_randtest_unsigned(t, state, fmpz_bits(m) + 2); fmpz_mod(t, t, m); if (n_randlimb(state) & UWORD(1)) { fmpz_sub(t, m, t); fmpz_sub_ui(t, t, UWORD(1)); } fmpz_set(f, t); fmpz_clear(t); }
mpz_class renf_elem_class::ceil() const noexcept { fmpz_t tmp; fmpz_init(tmp); if (nf == nullptr) { fmpz_add(tmp, fmpq_numref(b), fmpq_denref(b)); fmpz_sub_ui(tmp, tmp, 1); fmpz_fdiv_q(tmp, tmp, fmpq_denref(b)); } else renf_elem_ceil(tmp, a, nf->renf_t()); mpz_class z; fmpz_get_mpz(z.get_mpz_t(), tmp); fmpz_clear(tmp); return z; }
void fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha) { long r, c, i, j, d; fmpz_t tmp; r = mat->r; c = mat->c; d = r; if (c != r) { printf("Exception: fmpz_mat_ajtai called on an ill-formed matrix\n"); abort(); } fmpz_init(tmp); for (i = 0; i < d; i++) { mp_bitcnt_t bits = (mp_bitcnt_t) pow((double) (2 * d - i), alpha); fmpz_one(tmp); fmpz_mul_2exp(tmp, tmp, bits); fmpz_sub_ui(tmp, tmp, 1); fmpz_randm(mat->rows[i] + i, state, tmp); fmpz_add_ui(mat->rows[i] + i, mat->rows[i] + i, 2); fmpz_fdiv_q_2exp(mat->rows[i] + i, mat->rows[i] + i, 1); for (j = i + 1; j <= d; j++) { fmpz_randm(mat->rows[j] + i, state, tmp); if (n_randint(state, 2)) fmpz_neg(mat->rows[j] + i, mat->rows[j] + i); fmpz_zero(mat->rows[i] + j); } } fmpz_clear(tmp); }
void arith_euler_phi(fmpz_t res, const fmpz_t n) { fmpz_factor_t factors; fmpz_t t; ulong exp; slong i; if (fmpz_sgn(n) <= 0) { fmpz_zero(res); return; } if (fmpz_abs_fits_ui(n)) { fmpz_set_ui(res, n_euler_phi(fmpz_get_ui(n))); return; } fmpz_factor_init(factors); fmpz_factor(factors, n); fmpz_one(res); fmpz_init(t); for (i = 0; i < factors->num; i++) { fmpz_sub_ui(t, factors->p + i, UWORD(1)); fmpz_mul(res, res, t); exp = factors->exp[i]; if (exp != 1) { fmpz_pow_ui(t, factors->p + i, exp - UWORD(1)); fmpz_mul(res, res, t); } } fmpz_clear(t); fmpz_factor_clear(factors); }
void test0(slong b) { fmpz_t M; fmpz_init_set_ui(M,1); fmpz_mul_2exp(M,M,(ulong)b); test1_ui(b,M,0); test1_ui(b,M,1); test1_ui(b,M,(mp_limb_t)-1); test1(b,M,M); // M fmpz_t n; fmpz_init_set(n,M); fmpz_add_ui(n,M,1); test1(b,M,n); // M+1 fmpz_sub_ui(n,M,1); test1(b,M,n); // M-1 slong i; fmpz_t m; fmpz_init(m); fmpz_t Mhalf; fmpz_init(Mhalf); fmpz_fdiv_q_2exp(Mhalf,M,1); for(i=100;i--;) { fmpz_randm(m,rst,n); // m = random(M-1) test1(b,M,m); fmpz_add(m,m,Mhalf); // m+M/2 test1(b,M,m); } fmpz_mul_2exp(m,M,1); test1(b,M,m); // M<<1 fmpz_mul_2exp(m,m,1); test1(b,M,m); // M<<2 fmpz_mul_2exp(m,m,1); test1(b,M,m); // M<<3 fmpz_mul(m,m,M); test1(b,M,m); // M*(M<<3) fmpz_clear(Mhalf); fmpz_clear(m); fmpz_clear(n); fmpz_clear(M); }
void fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha) { const slong c = mat->c, r = mat->r, d = r; slong i, j; fmpz_t tmp; if (c != r) { flint_printf("Exception (fmpz_mat_ajtai): Non-square matrix.\n"); abort(); } fmpz_init(tmp); for (i = 0; i < d; i++) { mp_bitcnt_t bits = (mp_bitcnt_t) pow((double) (2 * d - i), alpha); fmpz_one(tmp); fmpz_mul_2exp(tmp, tmp, bits); fmpz_sub_ui(tmp, tmp, 1); fmpz_randm(mat->rows[i] + i, state, tmp); fmpz_add_ui(mat->rows[i] + i, mat->rows[i] + i, 2); fmpz_fdiv_q_2exp(mat->rows[i] + i, mat->rows[i] + i, 1); for (j = i + 1; j <= d; j++) { fmpz_randm(mat->rows[j] + i, state, tmp); if (n_randint(state, 2)) fmpz_neg(mat->rows[j] + i, mat->rows[j] + i); fmpz_zero(mat->rows[i] + j); } } fmpz_clear(tmp); }
static __inline__ void _arb_vec_get_fmpz_2exp_blocks(fmpz * coeffs, fmpz * exps, slong * blocks, const fmpz_t scale, arb_srcptr x, slong len, slong prec) { fmpz_t top, bot, t, b, v, block_top, block_bot; slong i, j, s, block, bits, maxheight; int in_zero; fmpz_init(top); fmpz_init(bot); fmpz_init(t); fmpz_init(b); fmpz_init(v); fmpz_init(block_top); fmpz_init(block_bot); blocks[0] = 0; block = 0; in_zero = 1; if (prec == ARF_PREC_EXACT) maxheight = ARF_PREC_EXACT; else maxheight = ALPHA * prec + BETA; for (i = 0; i < len; i++) { bits = arf_bits(arb_midref(x + i)); /* Skip (must be zero, since we assume there are no Infs/NaNs). */ if (bits == 0) continue; /* Bottom and top exponent of current number */ fmpz_set(top, ARF_EXPREF(arb_midref(x + i))); fmpz_submul_ui(top, scale, i); fmpz_sub_ui(bot, top, bits); /* Extend current block. */ if (in_zero) { fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } else { fmpz_max(t, top, block_top); fmpz_min(b, bot, block_bot); fmpz_sub(v, t, b); /* extend current block */ if (fmpz_cmp_ui(v, maxheight) < 0) { fmpz_swap(block_top, t); fmpz_swap(block_bot, b); } else /* start new block */ { /* write exponent for previous block */ fmpz_set(exps + block, block_bot); block++; blocks[block] = i; fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } } in_zero = 0; } /* write exponent for last block */ fmpz_set(exps + block, block_bot); /* end marker */ blocks[block + 1] = len; /* write the block data */ for (i = 0; blocks[i] != len; i++) { for (j = blocks[i]; j < blocks[i + 1]; j++) { if (arf_is_special(arb_midref(x + j))) { fmpz_zero(coeffs + j); } else { /* TODO: make this a single operation */ arf_get_fmpz_2exp(coeffs + j, bot, arb_midref(x + j)); fmpz_mul_ui(t, scale, j); fmpz_sub(t, bot, t); s = _fmpz_sub_small(t, exps + i); if (s < 0) abort(); /* Bug catcher */ fmpz_mul_2exp(coeffs + j, coeffs + j, s); } } } fmpz_clear(top); fmpz_clear(bot); fmpz_clear(t); fmpz_clear(b); fmpz_clear(v); fmpz_clear(block_top); fmpz_clear(block_bot); }
void arb_mul_naive(arb_t z, const arb_t x, const arb_t y, slong prec) { arf_t zm_exact, zm_rounded, zr, t, u; arf_init(zm_exact); arf_init(zm_rounded); arf_init(zr); arf_init(t); arf_init(u); arf_mul(zm_exact, arb_midref(x), arb_midref(y), ARF_PREC_EXACT, ARF_RND_DOWN); arf_set_round(zm_rounded, zm_exact, prec, ARB_RND); /* rounding error */ if (arf_equal(zm_exact, zm_rounded)) { arf_zero(zr); } else { fmpz_t e; fmpz_init(e); /* more accurate, but not what we are testing arf_sub(zr, zm_exact, zm_rounded, MAG_BITS, ARF_RND_UP); arf_abs(zr, zr); */ fmpz_sub_ui(e, ARF_EXPREF(zm_rounded), prec); arf_one(zr); arf_mul_2exp_fmpz(zr, zr, e); fmpz_clear(e); } /* propagated error */ if (!arb_is_exact(x)) { arf_set_mag(t, arb_radref(x)); arf_abs(u, arb_midref(y)); arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP); } if (!arb_is_exact(y)) { arf_set_mag(t, arb_radref(y)); arf_abs(u, arb_midref(x)); arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP); } if (!arb_is_exact(x) && !arb_is_exact(y)) { arf_set_mag(t, arb_radref(x)); arf_set_mag(u, arb_radref(y)); arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP); } arf_set(arb_midref(z), zm_rounded); arf_get_mag(arb_radref(z), zr); arf_clear(zm_exact); arf_clear(zm_rounded); arf_clear(zr); arf_clear(t); arf_clear(u); }
void fmpz_addmul_ui(fmpz_t f, const fmpz_t g, ulong x) { fmpz c1, r; c1 = *g; if ((x == 0) || (c1 == 0)) /* product is zero */ return; r = *f; if (r == 0) { fmpz_mul_ui(f, g, x); /* we are adding product to 0 */ return; } if (x == UWORD(1)) /* special case, adding g*1 to f */ { fmpz_add(f, f, g); return; } if (c1 == UWORD(1)) /* special case, adding 1*x to f */ { fmpz_add_ui(f, f, x); return; } if (!COEFF_IS_MPZ(c1)) /* c1 is small */ { mp_limb_t prod[2]; ulong uc1 = FLINT_ABS(c1); umul_ppmm(prod[1], prod[0], uc1, x); /* compute product */ if (prod[1] == 0) /* product fits in one limb */ { if (c1 < WORD(0)) fmpz_sub_ui(f, f, prod[0]); else fmpz_add_ui(f, f, prod[0]); return; } else if ((prod[1] == 1) && (!COEFF_IS_MPZ(r)) && ((r ^ c1) < WORD(0))) { /* only chance at cancellation is if product is one bit past a limb and res is small and opposite sign to this product */ ulong ur = FLINT_ABS(r); if (ur > prod[0]) /* cancellation will occur */ { fmpz_set_ui(f, prod[0] - ur); if (r > WORD(0)) fmpz_neg(f, f); return; } } /* in all remaining cases res is either big already, or will be big in the end */ { __mpz_struct * mpz_ptr = _fmpz_promote_val(f); mpz_t temp; /* set up a temporary, cheap mpz_t to contain prod */ temp->_mp_d = prod; temp->_mp_size = (c1 < WORD(0) ? -2 : 2); mpz_add(mpz_ptr, mpz_ptr, temp); _fmpz_demote_val(f); /* cancellation may have occurred */ } } else /* c1 is large */ { __mpz_struct * mpz_ptr = _fmpz_promote_val(f); flint_mpz_addmul_ui(mpz_ptr, COEFF_TO_PTR(c1), x); _fmpz_demote_val(f); /* cancellation may have occurred */ } }
/* 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(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("sub_ui...."); fflush(stdout); for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b; mpz_t d, e, f; ulong x; fmpz_init(a); fmpz_init(b); mpz_init(d); mpz_init(e); mpz_init(f); fmpz_randtest(a, state, 200); fmpz_get_mpz(d, a); x = n_randtest(state); fmpz_sub_ui(b, a, x); flint_mpz_sub_ui(e, d, x); fmpz_get_mpz(f, b); result = (mpz_cmp(e, f) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); abort(); } fmpz_clear(a); fmpz_clear(b); mpz_clear(d); mpz_clear(e); mpz_clear(f); } /* Check aliasing of a and b */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a; mpz_t d, e, f; ulong x; fmpz_init(a); mpz_init(d); mpz_init(e); mpz_init(f); fmpz_randtest(a, state, 200); fmpz_get_mpz(d, a); x = n_randtest(state); fmpz_sub_ui(a, a, x); flint_mpz_sub_ui(e, d, x); fmpz_get_mpz(f, a); result = (mpz_cmp(e, f) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); abort(); } fmpz_clear(a); mpz_clear(d); mpz_clear(e); mpz_clear(f); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) { if (fmpz_equal_ui(p, 2)) { fmpz_one(rop); } else if (N == 1) { fmpz_mod(rop, op, p); } else { slong *a, i, n; fmpz *pow, *u; fmpz_t s, t; fmpz_t inv; fmpz_t pm1; a = _padic_lifts_exps(&n, N); pow = _fmpz_vec_init(2 * n); u = pow + n; _padic_lifts_pows(pow, a, n, p); fmpz_init(s); fmpz_init(t); fmpz_init(inv); fmpz_init(pm1); fmpz_sub_ui(pm1, p, 1); /* Compute reduced units for (p-1) */ { fmpz_mod(u + 0, pm1, pow + 0); } for (i = 1; i < n; i++) { fmpz_mod(u + i, u + (i - 1), pow + i); } /* Run Newton iteration */ i = n - 1; { fmpz_mod(rop, op, pow + i); fmpz_set(inv, pm1); } for (i--; i >= 0; i--) { /* Lift rop */ fmpz_powm(s, rop, p, pow + i); fmpz_sub(s, s, rop); fmpz_mul(t, s, inv); fmpz_sub(rop, rop, t); fmpz_mod(rop, rop, pow + i); /* Lift inv */ if (i > 0) { fmpz_mul(s, inv, inv); fmpz_mul(t, u + i, s); fmpz_mul_2exp(inv, inv, 1); fmpz_sub(inv, inv, t); fmpz_mod(inv, inv, pow + i); } } fmpz_clear(s); fmpz_clear(t); fmpz_clear(inv); fmpz_clear(pm1); _fmpz_vec_clear(pow, 2 * n); flint_free(a); } }
int main(void) { long iter; int result; flint_rand_t state; printf("abs_ubound_ui_2exp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000; iter++) { fmpz_t x, y; long bits, yexp; long exp; mp_limb_t man; fmpz_init(x); fmpz_init(y); fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 400)); bits = 1 + n_randint(state, FLINT_BITS - 1); /* compute an exactly rounded mantissa */ fmpz_abs(y, x); if (fmpz_is_zero(y)) { yexp = 0; } else { yexp = fmpz_bits(y) - bits; if (yexp >= 0) { fmpz_cdiv_q_2exp(y, y, yexp); if (fmpz_bits(y) == bits + 1) { fmpz_tdiv_q_2exp(y, y, 1); yexp--; } } else { fmpz_mul_2exp(y, y, -yexp); } } man = fmpz_abs_ubound_ui_2exp(&exp, x, bits); if (FLINT_BIT_COUNT(man) != bits) { printf("wrong number of bits!\n"); printf("bits = %ld, count = %u\n\n", bits, FLINT_BIT_COUNT(man)); printf("x = "); fmpz_print(x); printf("\n\n"); printf("bits(x) = %ld\n\n", fmpz_bits(x)); printf("y = "); fmpz_print(y); printf("\n\n"); printf("yexp = %ld\n\n", yexp); printf("man = %lu, exp = %ld\n", man, exp); abort(); } /* ok if equal */ result = (fmpz_cmp_ui(y, man) == 0); /* ok if mantissa is 1 larger */ if (!result) { result = ((exp == yexp) && (fmpz_cmp_ui(y, man - 1) == 0)); } /* ok if the exact mantissa is 2^r-1 and overflow to 2^r happened */ if (!result) { fmpz_t t; fmpz_init(t); fmpz_set_ui(t, man); fmpz_mul_ui(t, t, 2); fmpz_sub_ui(t, t, 1); result = (exp == yexp + 1) && fmpz_equal(t, y); fmpz_clear(t); } if (!result) { printf("different from exact ceiling division\n"); printf("bits = %ld\n\n", bits); printf("x = "); fmpz_print(x); printf("\n\n"); printf("bits(x) = %ld\n\n", fmpz_bits(x)); printf("y = "); fmpz_print(y); printf(", yexp = %ld\n\n", yexp); printf("man = %lu, exp = %ld\n", man, exp); abort(); } fmpz_clear(x); fmpz_clear(y); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
void eis_series(fmpz_poly_t *eis, ulong k, ulong prec) { ulong i, p, ee, p_pow, ind; fmpz_t last, last_m1, mult, fp, t_coeff, term, term_m1; long bern_fac[15] = {0, 0, 0, 0, 240, 0, -504, 0, 480, 0, -264, 0, 0, 0, -24}; // Now, we compute the eisenstein series // First, compute primes by sieving. // allocate memory for the array. /* char *primes; primes = calloc(prec + 1, sizeof(char)); for(i = 0; i <= prec; i++) { primes[i] = 1; } primes[0] = 0; primes[1] = 0; p = 2; while(p*p <= prec) { j = p*p; while(j <= prec) { primes[j] = 0; j += p; } p += 1; while(primes[p] != 1) p += 1; } */ // Now, create the eisenstein series. // We build up each coefficient using the multiplicative properties of the // divisor sum function. fmpz_poly_set_coeff_si(*eis, 0, 1); for(i = 1; i <= prec; i++) fmpz_poly_set_coeff_si(*eis, i, bern_fac[k]); fmpz_init(last); fmpz_init(last_m1); fmpz_init(mult); fmpz_init(fp); fmpz_init(t_coeff); fmpz_init(term); fmpz_init(term_m1); ee = k - 1; p = 2; while(p <= prec) { p_pow = p; fmpz_set_ui(fp, p); fmpz_pow_ui(mult, fp, ee); fmpz_pow_ui(term, mult, 2); fmpz_set(last, mult); while(p_pow <= prec) { ind = p_pow; fmpz_sub_ui(term_m1, term, 1); fmpz_sub_ui(last_m1, last, 1); while(ind <= prec) { fmpz_poly_get_coeff_fmpz(t_coeff, *eis, ind); fmpz_mul(t_coeff, t_coeff, term_m1); fmpz_divexact(t_coeff, t_coeff, last_m1); fmpz_poly_set_coeff_fmpz(*eis, ind, t_coeff); ind += p_pow; } p_pow *= p; fmpz_set(last, term); fmpz_mul(term, term, mult); } p = n_nextprime(p, 1); } fmpz_clear(last); fmpz_clear(last_m1); fmpz_clear(mult); fmpz_clear(fp); fmpz_clear(t_coeff); fmpz_clear(term); fmpz_clear(term_m1); }
static __inline__ void _mag_vec_get_fmpz_2exp_blocks(fmpz * coeffs, double * dblcoeffs, fmpz * exps, slong * blocks, const fmpz_t scale, arb_srcptr x, mag_srcptr xm, slong len) { fmpz_t top, bot, t, b, v, block_top, block_bot; slong i, j, s, block, bits, maxheight; int in_zero; mag_srcptr cur; fmpz_init(top); fmpz_init(bot); fmpz_init(t); fmpz_init(b); fmpz_init(v); fmpz_init(block_top); fmpz_init(block_bot); blocks[0] = 0; block = 0; in_zero = 1; maxheight = ALPHA * MAG_BITS + BETA; if (maxheight > DOUBLE_BLOCK_MAX_HEIGHT) abort(); for (i = 0; i < len; i++) { cur = (x == NULL) ? (xm + i) : arb_radref(x + i); /* Skip (must be zero, since we assume there are no Infs/NaNs). */ if (mag_is_special(cur)) continue; /* Bottom and top exponent of current number */ bits = MAG_BITS; fmpz_set(top, MAG_EXPREF(cur)); fmpz_submul_ui(top, scale, i); fmpz_sub_ui(bot, top, bits); /* Extend current block. */ if (in_zero) { fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } else { fmpz_max(t, top, block_top); fmpz_min(b, bot, block_bot); fmpz_sub(v, t, b); /* extend current block */ if (fmpz_cmp_ui(v, maxheight) < 0) { fmpz_swap(block_top, t); fmpz_swap(block_bot, b); } else /* start new block */ { /* write exponent for previous block */ fmpz_set(exps + block, block_bot); block++; blocks[block] = i; fmpz_swap(block_top, top); fmpz_swap(block_bot, bot); } } in_zero = 0; } /* write exponent for last block */ fmpz_set(exps + block, block_bot); /* end marker */ blocks[block + 1] = len; /* write the block data */ for (i = 0; blocks[i] != len; i++) { for (j = blocks[i]; j < blocks[i + 1]; j++) { cur = (x == NULL) ? (xm + j) : arb_radref(x + j); if (mag_is_special(cur)) { fmpz_zero(coeffs + j); dblcoeffs[j] = 0.0; } else { mp_limb_t man; double c; man = MAG_MAN(cur); /* TODO: only write and use doubles when block is short? */ /* Divide by 2^(scale * j) */ fmpz_mul_ui(t, scale, j); fmpz_sub(t, MAG_EXPREF(cur), t); fmpz_sub_ui(t, t, MAG_BITS); /* bottom exponent */ s = _fmpz_sub_small(t, exps + i); if (s < 0) abort(); /* Bug catcher */ fmpz_set_ui(coeffs + j, man); fmpz_mul_2exp(coeffs + j, coeffs + j, s); c = man; c = ldexp(c, s - DOUBLE_BLOCK_SHIFT); if (c < 1e-150 || c > 1e150) /* Bug catcher */ abort(); dblcoeffs[j] = c; } } } fmpz_clear(top); fmpz_clear(bot); fmpz_clear(t); fmpz_clear(b); fmpz_clear(v); fmpz_clear(block_top); fmpz_clear(block_bot); }
void arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd) { if (arf_is_special(x)) { if (arf_is_zero(x)) { fmpz_zero(z); } else { flint_printf("arf_get_fmpz: cannot convert infinity or nan to integer\n"); abort(); } } else if (COEFF_IS_MPZ(*ARF_EXPREF(x))) { /* tiny */ if (fmpz_sgn(ARF_EXPREF(x)) < 0) { int negative = ARF_SGNBIT(x); if (rnd == ARF_RND_NEAR || rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } } else { flint_printf("arf_get_fmpz: number too large to convert to integer\n"); abort(); } } else { slong exp; int negative, inexact; mp_size_t xn, zn; mp_srcptr xp; __mpz_struct * zz; /* TBD: implement efficiently */ if (rnd == ARF_RND_NEAR) { fmpr_t t; fmpr_init(t); arf_get_fmpr(t, x); fmpr_get_fmpz(z, t, rnd); fmpr_clear(t); return; } exp = ARF_EXP(x); negative = ARF_SGNBIT(x); /* |x| < 1 */ if (exp <= 0) { if (rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } return; } ARF_GET_MPN_READONLY(xp, xn, x); /* |x| < 2^31 or 2^63 (must save 1 bit for rounding up!) */ if (exp < FLINT_BITS) { mp_limb_t v, v2; v = xp[xn - 1]; v2 = v >> (FLINT_BITS - exp); inexact = (xn > 1) || ((v2 << (FLINT_BITS - exp)) != v); if (inexact && rnd != ARF_RND_DOWN) { if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR)) v2++; if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL)) v2++; } if (negative) fmpz_neg_ui(z, v2); else fmpz_set_ui(z, v2); return; } /* |x| >= 1 */ zn = (exp + FLINT_BITS - 1) / FLINT_BITS; zz = _fmpz_promote(z); if (zz->_mp_alloc < zn) mpz_realloc2(zz, zn * FLINT_BITS); inexact = _arf_get_integer_mpn(zz->_mp_d, xp, xn, exp); zz->_mp_size = negative ? -zn : zn; _fmpz_demote_val(z); if (inexact && rnd != ARF_RND_DOWN) { if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR)) fmpz_sub_ui(z, z, 1); if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL)) fmpz_add_ui(z, z, 1); } }
slong fmpr_div(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { if (fmpr_is_special(x) || fmpr_is_special(y)) { _fmpr_div_special(z, x, y); return FMPR_RESULT_EXACT; } /* division by power of two <=> shift exponents */ if (fmpz_is_pm1(fmpr_manref(y))) { if (fmpz_is_one(fmpr_manref(y))) fmpz_set(fmpr_manref(z), fmpr_manref(x)); else fmpz_neg(fmpr_manref(z), fmpr_manref(x)); fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y)); return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } else { slong xbits, ybits, extra, extra_pad, extra_control; int negative; fmpz_t t, u; /* todo: work out exact needed shift */ xbits = fmpz_bits(fmpr_manref(x)); ybits = fmpz_bits(fmpr_manref(y)); extra = prec - xbits + ybits; extra = FLINT_MAX(extra, 0); extra_pad = 32; extra_control = 24; extra += extra_pad; fmpz_init(t); fmpz_init(u); fmpz_mul_2exp(t, fmpr_manref(x), extra); fmpz_tdiv_q(u, t, fmpr_manref(y)); if (low_bits_are_zero(u, extra_control)) { fmpz_t v; fmpz_init(v); fmpz_mul(v, u, fmpr_manref(y)); negative = fmpz_sgn(fmpr_manref(x)) != fmpz_sgn(fmpr_manref(y)); if (!fmpz_equal(t, v)) { if (negative) fmpz_sub_ui(u, u, 1); else fmpz_add_ui(u, u, 1); } fmpz_clear(v); } fmpz_swap(fmpr_manref(z), u); fmpz_clear(t); fmpz_clear(u); fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y)); fmpz_sub_ui(fmpr_expref(z), fmpr_expref(z), extra); return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); } }