int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { long i, dim = fmpz_mat_nrows(A); if (dim == 0) { fmpz_one(den); return 1; } else if (dim == 1) { fmpz_set(den, fmpz_mat_entry(A, 0, 0)); if (fmpz_is_zero(den)) return 0; if (!fmpz_mat_is_empty(B)) _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B)); return 1; } else if (dim == 2) { fmpz_t t, u; _fmpz_mat_det_cofactor_2x2(den, A->rows); if (fmpz_is_zero(den)) return 0; fmpz_init(t); fmpz_init(u); for (i = 0; i < fmpz_mat_ncols(B); i++) { fmpz_mul (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i)); fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i)); fmpz_mul (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i)); fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i)); fmpz_swap(fmpz_mat_entry(X, 0, i), t); fmpz_swap(fmpz_mat_entry(X, 1, i), u); } fmpz_clear(t); fmpz_clear(u); return 1; } else if (dim == 3) { return _fmpz_mat_solve_cramer_3x3(X, den, A, B); } else { printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p) { fmpz_t t, q, pow; if (fmpz_sgn(op) <= 0) { printf("Exception (padic_val_fac). op is non-positive.\n"); abort(); } fmpz_init(t); fmpz_init(q); fmpz_init(pow); fmpz_one(pow); do { fmpz_mul(pow, pow, p); fmpz_fdiv_q(q, op, pow); fmpz_add(t, t, q); } while (!fmpz_is_zero(q)); fmpz_swap(rop, t); fmpz_clear(t); fmpz_clear(q); fmpz_clear(pow); }
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 _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_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a) { if (res == a) { fmpz_t t; fmpz_init(t); _fmpz_poly_evaluate_horner_fmpz(t, f->coeffs, f->length, a); fmpz_swap(res, t); fmpz_clear(t); } else _fmpz_poly_evaluate_horner_fmpz(res, f->coeffs, f->length, a); }
void _fmpz_mod_poly_shift_right(fmpz * res, const fmpz * poly, long len, long n) { long i; /* Copy in forward order to avoid writing over unshifted coefficients */ if (res != poly) { for (i = 0; i < len - n; i++) fmpz_set(res + i, poly + n + i); } else { for (i = 0; i < len - n; i++) fmpz_swap(res + i, res + n + i); } }
void fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz_mod_poly_t poly, const fmpz_t a) { if (res == a) { fmpz_t t; fmpz_init(t); _fmpz_mod_poly_evaluate_fmpz(t, poly->coeffs, poly->length, a, &(poly->p)); fmpz_swap(res, t); fmpz_clear(t); } else { _fmpz_mod_poly_evaluate_fmpz(res, poly->coeffs, poly->length, a, &(poly->p)); } }
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); }
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); } }
int _fmpz_mat_solve_cramer_3x3(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { fmpz_t t15, t16, t17; int success; fmpz_init(t15); fmpz_init(t16); fmpz_init(t17); fmpz_mul(t17, AA(1,0), AA(2,1)); fmpz_submul(t17, AA(1,1), AA(2,0)); fmpz_mul(t16, AA(1,2), AA(2,0)); fmpz_submul(t16, AA(1,0), AA(2,2)); fmpz_mul(t15, AA(1,1), AA(2,2)); fmpz_submul(t15, AA(1,2), AA(2,1)); fmpz_mul (den, t15, AA(0,0)); fmpz_addmul(den, t16, AA(0,1)); fmpz_addmul(den, t17, AA(0,2)); success = !fmpz_is_zero(den); if (success) { fmpz_t t12, t13, t14, x0, x1, x2; long i, n = fmpz_mat_ncols(B); fmpz_init(t12); fmpz_init(t13); fmpz_init(t14); fmpz_init(x0); fmpz_init(x1); fmpz_init(x2); for (i = 0; i < n; i++) { fmpz_mul(t14, AA(2,0), BB(1,i)); fmpz_submul(t14, AA(1,0), BB(2,i)); fmpz_mul(t13, AA(2,1), BB(1,i)); fmpz_submul(t13, AA(1,1), BB(2,i)); fmpz_mul(t12, AA(2,2), BB(1,i)); fmpz_submul(t12, AA(1,2), BB(2,i)); fmpz_mul (x0, t15, BB(0,i)); fmpz_addmul(x0, t13, AA(0,2)); fmpz_submul(x0, t12, AA(0,1)); fmpz_mul (x1, t16, BB(0,i)); fmpz_addmul(x1, t12, AA(0,0)); fmpz_submul(x1, t14, AA(0,2)); fmpz_mul (x2, t17, BB(0,i)); fmpz_addmul(x2, t14, AA(0,1)); fmpz_submul(x2, t13, AA(0,0)); fmpz_swap(XX(0,i), x0); fmpz_swap(XX(1,i), x1); fmpz_swap(XX(2,i), x2); } fmpz_clear(t12); fmpz_clear(t13); fmpz_clear(t14); fmpz_clear(x0); fmpz_clear(x1); fmpz_clear(x2); } fmpz_clear(t15); fmpz_clear(t16); fmpz_clear(t17); return success; }
static void dsum_2( 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 N) { const fmpz_t P = {2L}; const long m0 = (2 * (ui + 1) - (vi + 1)) / d; const long u = ui + 1; long m, r; fmpz_t apow, f0, f1, f2, g; fmpz_init(apow); fmpz_init(f0); fmpz_init(f1); fmpz_init(f2); fmpz_init(g); fmpz_zero(rop); for (m = m0; m <= M; m += 2) { /* Note that r = 0 in the first iteration */ r = m / 2; switch (r) { case 0: fmpz_one(f2); break; case 1: fmpz_one(f1); fmpz_set_ui(f2, u); break; case 5: fmpz_swap(f1, f2); fmpz_set_ui(f2, (u * (u + d) * (u + 2*d) * (u + 3*d) * (u + 4*d)) / ((m0 == 0) ? 4 : 8)); break; default: fmpz_swap(f0, f1); fmpz_swap(f1, f2); fmpz_mul_ui(f2, f0, ((u + (r-2)*d) * (u + (r-1)*d)) / 2); fmpz_fdiv_r_2exp(f2, f2, N); } if (r == 0) { fmpz_one(apow); } else { fmpz_mul(apow, apow, a); fmpz_fdiv_r_2exp(apow, apow, N); } /* g = a_i^r f_{r} d^{-r} \mu_m = h * f2 * dinv[r] * mu[m] */ fmpz_mul(g, f2, dinv + r); fmpz_fdiv_r_2exp(g, g, N); fmpz_mul(g, g, apow); fmpz_fdiv_r_2exp(g, g, N); fmpz_mul(g, g, mu + m); fmpz_fdiv_r_2exp(g, g, N); fmpz_add(rop, rop, g); } fmpz_fdiv_r_2exp(rop, rop, N); fmpz_clear(apow); fmpz_clear(f0); fmpz_clear(f1); fmpz_clear(f2); fmpz_clear(g); }
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); } }