void _fmpq_poly_integral(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, slong len) { slong k; fmpz_t t; fmpz_init(t); fmpz_one(t); for (k = len - 1; k > 0; k--) { fmpz_mul(rpoly + k, poly + k - 1, t); fmpz_mul_ui(t, t, k); } fmpz_mul(rden, den, t); fmpz_set_ui(t, UWORD(2)); for (k = 3; k < len; k++) { fmpz_mul(rpoly + k, rpoly + k, t); fmpz_mul_ui(t, t, k); } fmpz_zero(rpoly); _fmpq_poly_canonicalise(rpoly, rden, len); fmpz_clear(t); }
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 _gamma_rf_bsplit(fmpz * A, ulong a, ulong b) { ulong n = b - a; if (n == 0) { fmpz_one(A); } else if (n < 8) { ulong j, k; fmpz_set_ui(A, a); fmpz_one(A + 1); for (j = 1; j < n; j++) { fmpz_one(A + j + 1); for (k = j; k > 0; k--) { fmpz_mul_ui(A + k, A + k, a + j); fmpz_add(A + k, A + k, A + k - 1); } fmpz_mul_ui(A, A, a + j); } } else { ulong m = a + (b - a) / 2; ulong w = m - a; ulong v = b - m; fmpz *t, *A1, *A2; t = _fmpz_vec_init(w + v + 2); A1 = t; A2 = A1 + w + 1; _gamma_rf_bsplit(A1, a, m); _gamma_rf_bsplit(A2, m, b); _fmpz_poly_mul(A, A2, v + 1, A1, w + 1); _fmpz_vec_clear(t, w + v + 2); } }
void _fmpz_poly_pow_binomial(fmpz * res, const fmpz * poly, ulong e) { ulong i, f; fmpz_t a, b, c; *a = 1L; *b = 1L; *c = 1L; fmpz_one(res); fmpz_one(res + e); for (i = 1UL, f = e - 1UL; i <= (e - 1UL) >> 1; i++, f--) { fmpz_mul(a, a, poly); fmpz_mul(b, b, poly + 1); fmpz_mul_ui(c, c, f + 1UL); fmpz_divexact_ui(c, c, i); fmpz_mul(res + i, b, c); fmpz_mul(res + f, a, c); } if ((e & 1UL) == 0UL) { fmpz_mul(a, a, poly); fmpz_mul(b, b, poly + 1); fmpz_mul_ui(c, c, f + 1UL); fmpz_divexact_ui(c, c, i); fmpz_mul(res + i, b, c); fmpz_mul(res + i, res + i, a); i++, f--; } for ( ; i <= e; i++, f--) { fmpz_mul(a, a, poly); fmpz_mul(b, b, poly + 1); fmpz_mul(res + i, res + i, b); fmpz_mul(res + f, res + f, a); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); }
int _fmpq_poly_is_squarefree(const fmpz * poly, const fmpz_t den, long len) { if (len < 3) return 1; else if (len == 3) { int ans; fmpz_t lhs, rhs; fmpz_init(lhs); fmpz_init(rhs); fmpz_mul(lhs, poly + 1, poly + 1); fmpz_mul(rhs, poly, poly + 2); fmpz_mul_ui(rhs, rhs, 4); ans = !fmpz_equal(lhs, rhs); fmpz_clear(lhs); fmpz_clear(rhs); return ans; } else { long gdeg; fmpz * w = _fmpz_vec_init(2 * len); _fmpz_poly_derivative(w, poly, len); _fmpz_poly_gcd(w + len, poly, len, w, len - 1L); for (gdeg = len - 2L; w[gdeg] == 0L; gdeg--) ; _fmpz_vec_clear(w, 2 * len); return (gdeg == 0); } }
void fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1, const fmpz_t m1, const nmod_mat_t mat2, int sign) { long i, j; mp_limb_t c; mp_limb_t m2 = mat2->mod.n; mp_limb_t m2inv = mat2->mod.ninv; fmpz_t m1m2; c = fmpz_fdiv_ui(m1, m2); c = n_invmod(c, m2); if (c == 0) { printf("Exception in fmpz_mat_CRT_ui: m1 not invertible modulo m2!\n"); abort(); } fmpz_init(m1m2); fmpz_mul_ui(m1m2, m1, m2); for (i = 0; i < mat1->r; i++) { for (j = 0; j < mat1->c; j++) _fmpz_CRT_ui_precomp(fmpz_mat_entry(res, i, j), fmpz_mat_entry(mat1, i, j), m1, nmod_mat_entry(mat2, i, j), m2, m2inv, m1m2, c, sign); } fmpz_clear(m1m2); }
void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, ulong c) { if (c == 1UL) { if (rpoly != poly) _fmpz_vec_set(rpoly, poly, len); fmpz_set(rden, den); } else { fmpz_t d, fc; ulong ud; fmpz_init(d); fmpz_init(fc); _fmpz_vec_content(d, poly, len); fmpz_set_ui(fc, c); fmpz_gcd(d, d, fc); ud = fmpz_get_ui(d); /* gcd of d and c fits into a ulong */ _fmpz_vec_scalar_divexact_ui(rpoly, poly, len, ud); fmpz_mul_ui(rden, den, c / ud); fmpz_clear(d); fmpz_clear(fc); } }
void fmpz_poly_scalar_mul_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2, ulong x) { long i; /* Either scalar or input poly is zero */ if ((x == 0) || (poly2->length == 0)) { fmpz_poly_zero(poly1); return; } /* Special case, multiply by 1 */ if (x == 1) { fmpz_poly_set(poly1, poly2); return; } fmpz_poly_fit_length(poly1, poly2->length); for (i = 0; i < poly2->length; i++) fmpz_mul_ui(poly1->coeffs + i, poly2->coeffs + i, x); _fmpz_poly_set_length(poly1, poly2->length); }
static void dsum_p( fmpz_t rop, const fmpz *dinv, const fmpz *mu, long M, const long *C, long lenC, const fmpz_t a, long ui, long vi, long n, long d, long p, long N) { long m, r, idx; fmpz_t apm1, apow, f, g, P, PN; fmpz_init(apm1); fmpz_init(apow); fmpz_init(f); fmpz_init(g); fmpz_init_set_ui(P, p); fmpz_init(PN); fmpz_pow_ui(PN, P, N); fmpz_zero(rop); r = 0; m = (p * (ui + 1) - (vi + 1)) / d; if (m <= M) /* Step {r = 0} */ { idx = _bsearch(C, 0, lenC, m % p); fmpz_powm_ui(apm1, a, p - 1, PN); fmpz_one(apow); fmpz_one(f); fmpz_mod(rop, mu + idx + lenC * (m / p), PN); } for (r = 1, m += p; m <= M; r++, m += p) { idx = _bsearch(C, 0, lenC, m % p); fmpz_mul(apow, apow, apm1); fmpz_mod(apow, apow, PN); fmpz_mul_ui(f, f, ui + 1 + (r - 1) * d); fmpz_mod(f, f, PN); fmpz_mul(g, f, dinv + r); fmpz_mul(g, g, apow); fmpz_mul(g, g, mu + idx + lenC * (m / p)); fmpz_mod(g, g, PN); fmpz_add(rop, rop, g); } fmpz_mod(rop, rop, PN); fmpz_clear(apm1); fmpz_clear(apow); fmpz_clear(f); fmpz_clear(g); fmpz_clear(P); fmpz_clear(PN); }
/* atan(x) = x + eps, |eps| < x^3*/ void arb_atan_eps(arb_t z, const arf_t x, slong prec) { fmpz_t mag; fmpz_init(mag); fmpz_mul_ui(mag, ARF_EXPREF(x), 3); arb_set_arf(z, x); arb_set_round(z, z, prec); arb_add_error_2exp_fmpz(z, mag); fmpz_clear(mag); }
void qsieve_ll_compute_C(qs_t qs_inf) { mp_limb_t A = qs_inf->A; mp_limb_t B = qs_inf->B; if ((mp_limb_signed_t) B < 0L) B = -B; fmpz_set_ui(qs_inf->C, B); fmpz_mul_ui(qs_inf->C, qs_inf->C, B); fmpz_sub(qs_inf->C, qs_inf->C, qs_inf->kn); fmpz_divexact_ui(qs_inf->C, qs_inf->C, A); }
mp_limb_t fmpz_triU_inverse_dim3( MATR W ) { fmpz_mat_window_unsh_print("dim3 starts",W); fmpz* e0 = W->rows[0]; fmpz* e1 = W->rows[1]; fmpz* e2 = W->rows[2]; mp_limb_t a0 = fmpz_to_t( e0 ); mp_limb_t b0_b2 = fmpz_to_t( e1+1 ) * fmpz_to_t( e2+2 ); fmpz_set_ui( e0, b0_b2 ); fmpz_mat_window_unsh_print("UL fixed",W); // swap b2 <-> b0, using e2[0] as temp, don't zero e2[0] e2[0]=e2[2]; e2[2]=e1[1]; e1[1]=e2[0]; fmpz* p=e1+2; fmpz_neg_1arg( p ); fmpz_mat_window_unsh_print("B' counted",W); // e2[0] := a1 e2[0]=e0[1]; // e0[1] := vector (a1,a2) by 0th col of matrice B' fmpz* q=e0+1; fmpz_mul( q, e2, e1+1 ); fmpz_neg_1arg( q ); fmpz_mat_window_unsh_print("0th col of B' multiplied",W); // a2 := vector (a1,a2) by 1st col of matrice B' q++;p=e2+2; fmpz_mul ( q, q, p ); fmpz_addmul( q, e2, e1+2 ); fmpz_neg_1arg( q ); fmpz_mat_window_unsh_print("1st col of B' multiplied",W); // e2[0], thank you for being scratch e2[0]=WORD(0); // multiply B' by a0 fmpz_mul_ui( p, p, a0 ); p=e1+2; fmpz_mul_ui( p, p, a0 ); p--; fmpz_mul_ui( p, p, a0 ); fmpz_mat_window_unsh_print("B' multiplied by a0",W); return a0*b0_b2; }
static __inline__ void fmpz_mat_window_unsh_mult_ui( MATR R, mp_limb_t m ) // R := R*m { slong rc=R->r, cc=R->c, i,j; fmpz* p; for( i=rc; i--; ) { p=R->rows[i]; for( j=cc; j--; p++ ) fmpz_mul_ui( p, p, m ); } }
void rising_difference_polynomial(fmpz * s, fmpz * c, ulong m) { long i, j, k; fmpz_t t; fmpz_init(t); arith_stirling_number_1u_vec(s, m, m + 1); for (k = 0; k < m; k++) { for (i = 0; i <= m - k - 1; i++) { fmpz_zero(c + m * k + i); for (j = i + 1; j + k <= m; j++) { if (j == i + 1) { fmpz_bin_uiui(t, 1+i+k, k); fmpz_mul_ui(t, t, m * (i+1)); } else { fmpz_mul_ui(t, t, m * (k + j)); fmpz_divexact_ui(t, t, j - i); } fmpz_addmul(c + m * k + i, s + j + k, t); } } } fmpz_clear(t); }
static void bsplit(fmpz_t T, fmpz_t Q, mp_bitcnt_t * Qexp, const slong * xexp, const fmpz * xpow, mp_bitcnt_t r, slong a, slong b) { int cc; if (b - a == 1) { count_trailing_zeros(cc, (2 * a + 2)); fmpz_neg_ui(Q, (2 * a + 2) >> cc); fmpz_mul_ui(Q, Q, 2 * a + 3); *Qexp = 2 * r + cc; fmpz_set(T, xpow); }
void arith_stirling_number_2_vec_next(fmpz * row, const fmpz * prev, slong n, slong klen) { slong k; if (klen > n) fmpz_one(row + n); if (n != 0 && klen != 0) fmpz_zero(row); for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) { fmpz_mul_ui(row + k, prev + k, k); fmpz_add(row + k, prev + k - 1, row + k); } for (k = n + 1; k < klen; k++) fmpz_zero(row + k); }
void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, long c) { if (c == 1) { if (rpoly != poly) { _fmpz_vec_set(rpoly, poly, len); fmpz_set(rden, den); } } else if (c == -1) { _fmpz_vec_neg(rpoly, poly, len); fmpz_set(rden, den); } else { fmpz_t d, f; fmpz_init(d); fmpz_init(f); fmpz_set_si(f, c); _fmpz_vec_content(d, poly, len); fmpz_gcd(d, d, f); if (c > 0) { _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); fmpz_mul_si(rden, den, c / fmpz_get_si(d)); } else { ulong q = (- (ulong) c) / fmpz_get_ui(d); fmpz_neg(d, d); _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); fmpz_mul_ui(rden, den, q); } fmpz_clear(d); fmpz_clear(f); } }
void _fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long n) { long m; fmpz * t, * u; fmpz_t tden, uden; if (n == 1) { fmpz_one(rpoly); fmpz_one(rden); return; } m = (n + 1) / 2; _fmpq_poly_invsqrt_series(rpoly, rden, poly, den, m); fmpz_init(tden); fmpz_init(uden); t = _fmpz_vec_init(n); u = _fmpz_vec_init(n); _fmpz_vec_zero(rpoly + m, n - m); _fmpq_poly_mul(t, tden, rpoly, rden, m, rpoly, rden, m); if (2*m - 1 < n) fmpz_zero(t + n - 1); _fmpq_poly_mullow(u, uden, t, tden, n, rpoly, rden, n, n); _fmpq_poly_mullow(t, tden, u, uden, n, poly, den, n, n); _fmpz_vec_neg(t + m, t + m, n - m); _fmpz_vec_zero(t, m); fmpz_mul_ui(tden, tden, 2UL); _fmpq_poly_canonicalise(t, tden, n); _fmpq_poly_add(rpoly, rden, rpoly, rden, m, t, tden, n); fmpz_clear(tden); fmpz_clear(uden); _fmpz_vec_clear(t, n); _fmpz_vec_clear(u, n); }
void mag_root(mag_t y, const mag_t x, ulong n) { if (n == 0) { mag_inf(y); } else if (n == 1 || mag_is_special(x)) { mag_set(y, x); } else if (n == 2) { mag_sqrt(y, x); } else if (n == 4) { mag_sqrt(y, x); mag_sqrt(y, y); } else { fmpz_t e, f; fmpz_init_set_ui(e, MAG_BITS); fmpz_init(f); /* We evaluate exp(log(1+2^(kn)x)/n) 2^-k where k is chosen so that 2^(kn) x ~= 2^30. TODO: this rewriting is probably unnecessary with the new exp/log functions. */ fmpz_sub(e, e, MAG_EXPREF(x)); fmpz_cdiv_q_ui(e, e, n); fmpz_mul_ui(f, e, n); mag_mul_2exp_fmpz(y, x, f); mag_log1p(y, y); mag_div_ui(y, y, n); mag_exp(y, y); fmpz_neg(e, e); mag_mul_2exp_fmpz(y, y, e); fmpz_clear(e); fmpz_clear(f); } }
int main(void) { long i, n; fmpz_t x; fmpz_t y; printf("fac_ui...."); fflush(stdout); fmpz_init(x); fmpz_init(y); /* Twice to check demotion */ for (n = 0; n < 2; n++) { fmpz_set_ui(y, 1UL); for (i = 0; i < 100; i++) { fmpz_fac_ui(x, i); fmpz_mul_ui(y, y, FLINT_MAX(1, i)); if (!fmpz_equal(x, y)) { printf("FAIL: %ld\n", i); fmpz_print(x); printf("\n"); fmpz_print(y); printf("\n"); abort(); } } } fmpz_clear(x); fmpz_clear(y); _fmpz_cleanup(); printf("PASS\n"); return 0; }
static void bsplit(arb_t y, const fmpz_t p, const fmpz_t q, ulong a, ulong b, long prec) { if (b - a <= 8) { fmpz_t t, u; ulong c; fmpz_init(t); fmpz_init(u); fmpz_mul_ui(t, q, a); fmpz_add(t, t, p); fmpz_set(u, t); for (c = a + 1; c < b; c++) { fmpz_add(u, u, q); fmpz_mul(t, t, u); } arb_set_round_fmpz(y, t, prec); fmpz_clear(t); fmpz_clear(u); } else { arb_t w; ulong m = a + (b - a) / 2; arb_init(w); bsplit(y, p, q, a, m, prec); bsplit(w, p, q, m, b, prec); arb_mul(y, y, w, prec); arb_clear(w); } }
/* Assumes len > 0. */ void _fmpz_poly_sqr_classical(fmpz *rop, const fmpz *op, long len) { if (len == 1) /* Special case */ { fmpz_mul(rop, op, op); } else /* Ordinary case */ { long i; _fmpz_vec_scalar_mul_fmpz(rop, op, len, op); _fmpz_vec_scalar_mul_fmpz(rop + len, op + 1, len - 1, op + len - 1); for (i = 1; i < len - 1; i++) _fmpz_vec_scalar_addmul_fmpz(rop + i + 1, op + 1, i - 1, op + i); for (i = 1; i < 2 * len - 2; i++) fmpz_mul_ui(rop + i, rop + i, 2); for (i = 1; i < len - 1; i++) fmpz_addmul(rop + 2 * i, op + i, op + i); } }
int main(void) { int i; FLINT_TEST_INIT(state); flint_printf("multi_CRT_ui...."); fflush(stdout); for (i = 0; i < 1000 * flint_test_multiplier(); i++) { slong bits, prime_bits, rows, cols, num_primes, j; fmpz_t mod; fmpz_mat_t A, B, C; nmod_mat_t Amod[1000]; mp_limb_t primes[1000]; bits = n_randint(state, 500) + 1; rows = n_randint(state, 10); cols = n_randint(state, 10); prime_bits = 1 + n_randint(state, FLINT_BITS - 1); fmpz_mat_init(A, rows, cols); fmpz_mat_init(B, rows, cols); fmpz_mat_init(C, rows, cols); fmpz_mat_randtest(A, state, bits); fmpz_init(mod); num_primes = 0; primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); fmpz_set_ui(mod, primes[0]); /* + 1 for sign */ while (fmpz_bits(mod) <= bits + 1) { primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); fmpz_mul_ui(mod, mod, primes[num_primes + 1]); num_primes++; } num_primes++; for (j = 0; j < num_primes; j++) nmod_mat_init(Amod[j], rows, cols, primes[j]); fmpz_mat_multi_mod_ui(Amod, num_primes, A); fmpz_mat_multi_CRT_ui(B, Amod, num_primes, 1); if (!fmpz_mat_equal(B, A)) { flint_printf("FAIL!\n"); flint_printf("primes: "); for (j = 0; j < num_primes; j++) flint_printf("%wu ", primes[j]); flint_printf("\nA: \n"); fmpz_mat_print_pretty(A); flint_printf("\nB: \n"); fmpz_mat_print_pretty(B); flint_printf("\n"); abort(); } for (j = 0; j < num_primes; j++) nmod_mat_clear(Amod[j]); fmpz_mat_clear(A); fmpz_mat_clear(B); fmpz_mat_clear(C); fmpz_clear(mod); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
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); }
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); }
int main() { long i, j; int sign; fmpz_t input; fmpz_t result; fmpz_t r1; fmpz_t m1; fmpz_t mprod; ulong r2, m2; flint_rand_t state; printf("CRT_ui...."); fflush(stdout); fmpz_init(input); fmpz_init(result); fmpz_init(r1); fmpz_init(m1); fmpz_init(mprod); flint_randinit(state); for (i = 0; i < 10000; i++) { long nprimes; m2 = n_randtest_prime(state, 0); nprimes = 1 + n_randint(state, 4); fmpz_set_ui(m1, 1UL); for (j = 0; j < nprimes; ) { ulong t = n_randtest_prime(state, 0); if (t != m2) { fmpz_mul_ui(m1, m1, t); j++; } } fmpz_mul_ui(mprod, m1, m2); sign = n_randint(state, 2); if (sign) fmpz_randtest_mod_signed(input, state, mprod); else fmpz_randtest_mod(input, state, mprod); fmpz_mod(r1, input, m1); r2 = fmpz_fdiv_ui(input, m2); if (sign) fmpz_CRT_ui(result, r1, m1, r2, m2); else fmpz_CRT_ui_unsigned(result, r1, m1, r2, m2); if (!fmpz_equal(result, input)) { printf("FAIL:\n"); printf("m1: "); fmpz_print(m1); printf("\n"); printf("m2: %lu\n", m2); printf("m1*m2: "); fmpz_print(mprod); printf("\n"); printf("input: "); fmpz_print(input); printf("\n"); printf("r1: "); fmpz_print(r1); printf("\n"); printf("r2: %lu\n", r2); printf("result: "); fmpz_print(result); printf("\n"); printf("%ld Equalness: %d\n", i, fmpz_equal(result, input)); printf("\n"); abort(); } } fmpz_clear(input); fmpz_clear(result); fmpz_clear(r1); fmpz_clear(m1); fmpz_clear(mprod); flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
void _fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, slong n) { slong i, j, k, m; fmpz *R, *Rden, *S, *T, *dens, *tmp; fmpz_t Sden, Tden, t; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); return; } if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } return; } m = n_sqrt(n); fmpz_init(t); dens = _fmpz_vec_init(n); R = _fmpz_vec_init((n - 1) * m); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); Rden = _fmpz_vec_init(m); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1); for (i = 2; i <= m; i++) { _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1, Ri(1), Rdeni(1), n - 1, n - 1); _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1); } for (i = 1; i < m; i++) { fmpz_set(Qinv + i, Ri(i) + i - 1); fmpz_mul_ui(dens + i, Rdeni(i), i); } _fmpz_vec_set(S, Ri(m), n - 1); fmpz_set(Sden, Rdeni(m)); for (i = m; i < n; i += m) { fmpz_set(Qinv + i, S + i - 1); fmpz_mul_ui(dens + i, Sden, i); for (j = 1; j < m && i + j < n; j++) { fmpz_mul(t, S + 0, Ri(j) + i + j - 1); for (k = 1; k <= i + j - 1; k++) fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k); fmpz_set(Qinv + i + j, t); fmpz_mul(dens + i + j, Sden, Rdeni(j)); fmpz_mul_ui(dens + i + j, dens + i + j, i + j); } if (i + 1 < n) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, Ri(m), Rdeni(m), n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_swap(Tden, Sden); tmp = S; S = T; T = tmp; } } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); fmpz_clear(t); _fmpz_vec_clear(dens, n); _fmpz_vec_clear(R, (n - 1) * m); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(Rden, m); fmpz_clear(Sden); fmpz_clear(Tden); }
void _fmpq_poly_revert_series_lagrange(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, long n) { long i; fmpz *R, *S, *T, *dens, *tmp; fmpz_t Rden, Sden, Tden; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); } else if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } } else { dens = _fmpz_vec_init(n); R = _fmpz_vec_init(n - 1); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); fmpz_init(Rden); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); fmpz_set(Qinv + 1, Qden); fmpz_set(dens + 1, Q + 1); _fmpq_poly_inv_series(R, Rden, Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(R, Rden, n - 1); _fmpz_vec_set(S, R, n - 1); fmpz_set(Sden, Rden); for (i = 2; i < n; i++) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, R, Rden, n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_set(Qinv + i, T + i - 1); fmpz_mul_ui(dens + i, Tden, i); tmp = S; S = T; T = tmp; fmpz_swap(Sden, Tden); } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); _fmpz_vec_clear(R, n - 1); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(dens, n); fmpz_clear(Rden); fmpz_clear(Sden); fmpz_clear(Tden); } }
/* todo: use log(1-z) when this is better? would also need to adjust strategy in the main function */ void acb_hypgeom_dilog_bernoulli(acb_t res, const acb_t z, slong prec) { acb_t s, w, w2; slong n, k; fmpz_t c, d; mag_t m, err; double lm; int real; acb_init(s); acb_init(w); acb_init(w2); fmpz_init(c); fmpz_init(d); mag_init(m); mag_init(err); real = 0; if (acb_is_real(z)) { arb_sub_ui(acb_realref(w), acb_realref(z), 1, 30); real = arb_is_nonpositive(acb_realref(w)); } acb_log(w, z, prec); acb_get_mag(m, w); /* for k >= 4, the terms are bounded by (|w| / (2 pi))^k */ mag_set_ui_2exp_si(err, 2670177, -24); /* upper bound for 1/(2pi) */ mag_mul(err, err, m); lm = mag_get_d_log2_approx(err); if (lm < -0.25) { n = prec / (-lm) + 1; n = FLINT_MAX(n, 4); mag_geom_series(err, err, n); BERNOULLI_ENSURE_CACHED(n) acb_mul(w2, w, w, prec); for (k = n - (n % 2 == 0); k >= 3; k -= 2) { fmpz_mul_ui(c, fmpq_denref(bernoulli_cache + k - 1), k - 1); fmpz_mul_ui(d, c, (k + 1) * (k + 2)); acb_mul(s, s, w2, prec); acb_mul_fmpz(s, s, c, prec); fmpz_mul_ui(c, fmpq_numref(bernoulli_cache + k - 1), (k + 1) * (k + 2)); acb_sub_fmpz(s, s, c, prec); acb_div_fmpz(s, s, d, prec); } acb_mul(s, s, w, prec); acb_mul_2exp_si(s, s, 1); acb_sub_ui(s, s, 3, prec); acb_mul(s, s, w2, prec); acb_mul_2exp_si(s, s, -1); acb_const_pi(w2, prec); acb_addmul(s, w2, w2, prec); acb_div_ui(s, s, 6, prec); acb_neg(w2, w); acb_log(w2, w2, prec); acb_submul(s, w2, w, prec); acb_add(res, s, w, prec); acb_add_error_mag(res, err); if (real) arb_zero(acb_imagref(res)); } else { acb_indeterminate(res); } acb_clear(s); acb_clear(w); acb_clear(w2); fmpz_clear(c); fmpz_clear(d); mag_clear(m); mag_clear(err); }
void fmpz_multi_CRT_ui(fmpz_t output, unsigned long * residues, fmpz_comb_t comb, fmpz_t ** comb_temp) { ulong i, j, k; ulong n = comb->n; ulong num; ulong log_res; mp_limb_t * ptr; ulong size; ulong num_primes = comb->num_primes; if (num_primes == 1) // the output is less than a single prime, so just output the result { unsigned long p = comb->primes[0]; if ((p - residues[0]) < residues[0]) fmpz_set_si(output, (long) (residues[0] - p)); else fmpz_set_ui(output, residues[0]); return; } // first layer of reconstruction num = (1L<<n); mp_limb_t temps[3]; mp_limb_t temp2s[3]; for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) { fmpz_set_ui(temps, residues[i]); fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1])); fmpz_sub_ui_inplace(temp2s, residues[i + 1]); temp2s[0] = -temp2s[0]; fmpz_mul(temps, temp2s, comb->res[0][j]); fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1])); fmpz_mul_ui(temps, temp2s, comb->primes[i]); fmpz_add_ui(comb_temp[0][j], temps, residues[i]); } if (i < num_primes) fmpz_set_ui(comb_temp[0][j], residues[i]); // compute other layers of reconstruction fmpz_t temp = (fmpz_t) flint_heap_alloc(2*num + 1); fmpz_t temp2 = (fmpz_t) flint_heap_alloc(2*num + 1); num /= 2; log_res = 1; while (log_res < n) { for (i = 0, j = 0; i < num; i += 2, j++) { if (fmpz_is_one(comb->comb[log_res-1][i+1])) { if (!fmpz_is_one(comb->comb[log_res-1][i])) fmpz_set(comb_temp[log_res][j], comb_temp[log_res-1][i]); } else { fmpz_mod(temp2, comb_temp[log_res-1][i], comb->comb[log_res-1][i+1]); fmpz_sub(temp, temp2, comb_temp[log_res-1][i+1]); temp[0] = -temp[0]; fmpz_mul(temp2, temp, comb->res[log_res][j]); fmpz_mod(temp, temp2, comb->comb[log_res-1][i+1]); fmpz_mul(temp2, temp, comb->comb[log_res-1][i]); fmpz_add(comb_temp[log_res][j], temp2, comb_temp[log_res-1][i]); } } log_res++; num /= 2; } // write out the output __fmpz_multi_CRT_sign(comb_temp[log_res - 1][0], comb_temp[log_res - 1][0], comb); fmpz_set(output, comb_temp[log_res - 1][0]); flint_heap_free(temp2); //temp2 flint_heap_free(temp); //temp }