void fmpz_mat_solve_cramer(fmpz * x, fmpz_t den, const fmpz_mat_t A, const fmpz * b) { long dim = A->r; switch (dim) { case 0: fmpz_set_ui(den, 1UL); break; case 1: fmpz_set(den, A->rows[0]); fmpz_set(x, b); break; case 2: _fmpz_mat_solve_cramer_2x2(x, den, A->rows, b); break; case 3: _fmpz_mat_solve_cramer_3x3(x, den, A->rows, b); break; default: printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
void fmpq_mat_mul_fmpz_mat(fmpq_mat_t C, const fmpq_mat_t A, const fmpz_mat_t B) { slong i, j; fmpz_mat_t Aclear; fmpz_mat_t Cclear; fmpz * Aden; fmpz_mat_init(Aclear, A->r, A->c); fmpz_mat_init(Cclear, A->r, B->c); Aden = _fmpz_vec_init(A->r); fmpq_mat_get_fmpz_mat_rowwise(Aclear, Aden, A); fmpz_mat_mul(Cclear, Aclear, B); for (i = 0; i < C->r; i++) { for (j = 0; j < C->c; j++) { fmpz_set(fmpq_mat_entry_num(C, i, j), fmpz_mat_entry(Cclear, i, j)); fmpz_set(fmpq_mat_entry_den(C, i, j), Aden + i); fmpq_canonicalise(fmpq_mat_entry(C, i, j)); } } fmpz_mat_clear(Aclear); fmpz_mat_clear(Cclear); _fmpz_vec_clear(Aden, A->r); }
void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, const fmpz_t a, const fmpz_t p) { if (len == 0) { fmpz_zero(res); } else if (len == 1 || fmpz_is_zero(a)) { fmpz_set(res, poly); } else { slong i = len - 1; fmpz_t t; fmpz_init(t); fmpz_set(res, poly + i); for (i = len - 2; i >= 0; i--) { fmpz_mul(t, res, a); fmpz_mod(t, t, p); fmpz_add(res, poly + i, t); } fmpz_clear(t); if (fmpz_cmpabs(res, p) >= 0) fmpz_sub(res, res, p); } }
void _fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz * f, long len, const fmpz_t a) { if (len == 0) { fmpz_zero(res); } else if (len == 1 || fmpz_is_zero(a)) { fmpz_set(res, f); } else { long i = len - 1; fmpz_t t; fmpz_init(t); fmpz_set(res, f + i); for (i = len - 2; i >= 0; i--) { fmpz_mul(t, res, a); fmpz_add(res, f + i, t); } fmpz_clear(t); } }
static void _fmpz_poly_compose_pow(fmpz *rop, const fmpz *op, long len, long k) { if (k == 1) { if (rop != op) { _fmpz_vec_set(rop, op, len); } } else if (len == 1) { fmpz_set(rop, op); } else { long i, j, h; for (i = len - 1, j = (len - 1) * k ; i >= 0; i--, j -= k) { fmpz_set(rop + j, op + i); if (i != 0) for (h = 1; h < k; h++) fmpz_zero(rop + (j - h)); } } }
void __fmpz_multi_CRT_sign(fmpz_t output, fmpz_t input, fmpz_comb_t comb) { unsigned long n = comb->n; if (n == 0L) { if (input[0] == 0L) { fmpz_set_ui(output, 0L); return; } unsigned long p = comb->primes[0]; if ((p - input[1]) < input[1]) fmpz_set_si(output, (long) (input[1] - p)); else fmpz_set_ui(output, input[1]); return; } fmpz_t temp = fmpz_init(fmpz_size(comb->comb[n-1][0]) + 1); fmpz_sub(temp, input, comb->comb[comb->n - 1][0]); if (fmpz_cmpabs(temp, input) <= 0L) fmpz_set(output, temp); else fmpz_set(output, input); fmpz_clear(temp); return; }
void _fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den, const fmpz * poly1, const fmpz_t den1, long len1, const fmpz * poly2, const fmpz_t den2, long len2, long n) { if (fmpz_is_one(den2)) { _fmpz_poly_compose_series(res, poly1, len1, poly2, len2, n); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, n); } else if (n == 1) { fmpz_set(res, poly1); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, 1); } else { long i = len1 - 1; long lenr; fmpz_t tden; fmpz * t = _fmpz_vec_init(n); fmpz_init(tden); _fmpz_vec_zero(res, n); lenr = len2; _fmpq_poly_scalar_mul_fmpz(res, den, poly2, den2, len2, poly1 + i); _fmpq_poly_scalar_div_fmpz(res, den, res, den, len2, den1); i--; _fmpq_poly_add(res, den, res, den, len2, poly1 + i, den1, 1); _fmpq_poly_canonicalise(res, den, lenr); while (i > 0) { i--; if (lenr + len2 - 1 < n) { _fmpq_poly_mul(t, tden, res, den, lenr, poly2, den2, len2); lenr = lenr + len2 - 1; } else { _fmpq_poly_mullow(t, tden, res, den, lenr, poly2, den2, len2, n); lenr = n; } _fmpq_poly_canonicalise(t, tden, lenr); _fmpq_poly_add(res, den, t, tden, lenr, poly1 + i, den1, 1); } _fmpq_poly_canonicalise(res, den, n); _fmpz_vec_clear(t, n); fmpz_clear(tden); } }
void fmpq_poly_compose(fmpq_poly_t res, const fmpq_poly_t poly1, const fmpq_poly_t poly2) { const long len1 = poly1->length; const long len2 = poly2->length; long lenr; if (len1 == 0L) { fmpq_poly_zero(res); return; } if (len1 == 1L || len2 == 0L) { fmpq_poly_fit_length(res, 1); fmpz_set(res->coeffs, poly1->coeffs); fmpz_set(res->den, poly1->den); { fmpz_t d; fmpz_init(d); fmpz_gcd(d, res->coeffs, res->den); if (*d != 1L) { fmpz_divexact(res->coeffs, res->coeffs, d); fmpz_divexact(res->den, res->den, d); } fmpz_clear(d); } _fmpq_poly_set_length(res, 1); _fmpq_poly_normalise(res); return; } lenr = (len1 - 1L) * (len2 - 1L) + 1L; if ((res != poly1) && (res != poly2)) { fmpq_poly_fit_length(res, lenr); _fmpq_poly_compose(res->coeffs, res->den, poly1->coeffs, poly1->den, len1, poly2->coeffs, poly2->den, len2); _fmpq_poly_set_length(res, lenr); _fmpq_poly_normalise(res); } else { fmpq_poly_t t; fmpq_poly_init2(t, lenr); _fmpq_poly_compose(t->coeffs, t->den, poly1->coeffs, poly1->den, len1, poly2->coeffs, poly2->den, len2); _fmpq_poly_set_length(t, lenr); _fmpq_poly_normalise(t); fmpq_poly_swap(res, t); fmpq_poly_clear(t); } }
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); }
slong fmpr_add_naive(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd) { slong shift, xsize, ysize; if (fmpr_is_special(x) || fmpr_is_special(y)) { return _fmpr_add_special(z, x, y, prec, rnd); } shift = _fmpz_sub_small(fmpr_expref(x), fmpr_expref(y)); if (shift == 0) { fmpz_add(fmpr_manref(z), fmpr_manref(x), fmpr_manref(y)); fmpz_set(fmpr_expref(z), fmpr_expref(x)); } else if (shift > 0) { ysize = _fmpz_size(fmpr_manref(y)) * FLINT_BITS; /* x and y do not overlap */ if (shift > ysize && prec != FMPR_PREC_EXACT) { /* y does not overlap with result */ if (ysize + prec - (slong) fmpz_bits(fmpr_manref(x)) < shift) { return _fmpr_add_eps(z, x, fmpz_sgn(fmpr_manref(y)), prec, rnd); } } fmpz_add_mul2exp(fmpr_manref(z), fmpr_manref(y), fmpr_manref(x), shift); fmpz_set(fmpr_expref(z), fmpr_expref(y)); } else { shift = -shift; xsize = _fmpz_size(fmpr_manref(x)) * FLINT_BITS; /* x and y do not overlap */ if (shift > xsize && prec != FMPR_PREC_EXACT) { /* y does not overlap with result */ if (xsize + prec - (slong) fmpz_bits(fmpr_manref(y)) < shift) { return _fmpr_add_eps(z, y, fmpz_sgn(fmpr_manref(x)), prec, rnd); } } fmpz_add_mul2exp(fmpr_manref(z), fmpr_manref(x), fmpr_manref(y), shift); fmpz_set(fmpr_expref(z), fmpr_expref(x)); } return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd); }
void _padic_log_balanced(fmpz_t z, const fmpz_t y, long v, const fmpz_t p, long N) { fmpz_t pv, pN, r, t, u; long val; padic_inv_t S; fmpz_init(pv); fmpz_init(pN); fmpz_init(r); fmpz_init(t); fmpz_init(u); _padic_inv_precompute(S, p, N); fmpz_set(t, y); fmpz_set(pv, p); fmpz_pow_ui(pN, p, N); fmpz_zero(z); val = 1; /* TODO: Abort earlier if larger than $p^N$, possible with variable precision? */ while (!fmpz_is_zero(t)) { fmpz_mul(pv, pv, pv); fmpz_fdiv_qr(t, r, t, pv); if (!fmpz_is_zero(t)) { fmpz_mul(t, t, pv); fmpz_add_ui(u, r, 1); _padic_inv_precomp(u, u, S); fmpz_mul(t, t, u); fmpz_mod(t, t, pN); } if (!fmpz_is_zero(r)) { fmpz_neg(r, r); _padic_log_bsplit(r, r, val, p, N); fmpz_sub(z, z, r); } val *= 2; } fmpz_clear(pv); fmpz_clear(pN); fmpz_clear(r); fmpz_clear(t); fmpz_clear(u); _padic_inv_clear(S); }
void _fmpq_bsplit_sum_abpq(fmpz_t P, fmpz_t Q, fmpz_t B, fmpz_t T, const fmpq * ab, const fmpq * pq, long n1, long n2) { if (n2 - n1 <= 0) { fmpz_zero(P); fmpz_one(Q); } else if (n2 - n1 == 1) { fmpz_set(P, fmpq_numref(pq + n1)); fmpz_set(Q, fmpq_denref(pq + n1)); fmpz_set(B, fmpq_denref(ab + n1)); fmpz_mul(T, P, fmpq_numref(ab + n1)); } else { long m = (n1 + n2) / 2; fmpz_t P2, Q2, B2, T2; fmpz_init(P2); fmpz_init(Q2); fmpz_init(B2); fmpz_init(T2); _fmpq_bsplit_sum_abpq(P, Q, B, T, ab, pq, n1, m); _fmpq_bsplit_sum_abpq(P2, Q2, B2, T2, ab, pq, m, n2); if (!fmpz_is_one(B2)) fmpz_mul(T, T, B2); fmpz_mul(T, T, Q2); if (!fmpz_is_one(B)) fmpz_mul(T2, T2, B); fmpz_mul(T2, T2, P); fmpz_add(T, T, T2); fmpz_mul(P, P, P2); fmpz_mul(Q, Q, Q2); fmpz_mul(B, B, B2); fmpz_clear(P2); fmpz_clear(Q2); fmpz_clear(B2); fmpz_clear(T2); } }
void _fmpz_ramanujan_tau(fmpz_t res, fmpz_factor_t factors) { fmpz_poly_t poly; fmpz_t tau_p, p_11, next, this, prev; long k, r; ulong max_prime; max_prime = 1UL; for (k = 0; k < factors->length; k++) { /* TODO: handle overflow properly */ max_prime = FLINT_MAX(max_prime, fmpz_get_ui(factors->p + k)); } fmpz_poly_init(poly); fmpz_poly_ramanujan_tau(poly, max_prime + 1); fmpz_set_ui(res, 1); fmpz_init(tau_p); fmpz_init(p_11); fmpz_init(next); fmpz_init(this); fmpz_init(prev); for (k = 0; k < factors->length; k++) { ulong p = fmpz_get_ui(factors->p + k); fmpz_set(tau_p, poly->coeffs + p); fmpz_set_ui(p_11, p); fmpz_pow_ui(p_11, p_11, 11); fmpz_set_ui(prev, 1); fmpz_set(this, tau_p); for (r = 1; r < fmpz_get_ui(factors->exp + k); r++) { fmpz_mul(next, tau_p, this); fmpz_submul(next, p_11, prev); fmpz_set(prev, this); fmpz_set(this, next); } fmpz_mul(res, res, this); } fmpz_clear(tau_p); fmpz_clear(p_11); fmpz_clear(next); fmpz_clear(this); fmpz_clear(prev); fmpz_poly_clear(poly); }
void _fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_struct ** num, fmpz * den, const fmpq_mat_struct ** mat, slong n) { fmpz_t t, lcm; slong i, j, k; if (fmpq_mat_is_empty(mat[0])) return; fmpz_init(t); fmpz_init(lcm); for (i = 0; i < mat[0]->r; i++) { /* Compute common denominator of row */ fmpz_set(lcm, fmpq_mat_entry_den(mat[0], i, 0)); for (k = 0; k < n; k++) for (j = (k == 0); j < mat[k]->c; j++) fmpz_lcm(lcm, lcm, fmpq_mat_entry_den(mat[k], i, j)); if (den != NULL) fmpz_set(den + i, lcm); for (k = 0; k < n; k++) { /* Rescale numerators in row */ if (fmpz_is_one(lcm)) { for (j = 0; j < mat[k]->c; j++) fmpz_set(fmpz_mat_entry(num[k], i, j), fmpq_mat_entry_num(mat[k], i, j)); } else { for (j = 0; j < mat[k]->c; j++) { fmpz_divexact(t, lcm, fmpq_mat_entry_den(mat[k], i, j)); fmpz_mul(fmpz_mat_entry(num[k], i, j), fmpq_mat_entry_num(mat[k], i, j), t); } } } } fmpz_clear(t); fmpz_clear(lcm); }
void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, const fmpz_t c) { fmpz_t gcd; /* GCD( den, c ) */ if (fmpz_is_zero(c)) { _fmpz_vec_zero(rpoly, len); fmpz_one(rden); return; } fmpz_init(gcd); fmpz_one(gcd); if (*c != 1L) fmpz_gcd(gcd, c, den); if (*gcd == 1L) { _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c); fmpz_set(rden, den); } else { fmpz_t c2; fmpz_init(c2); fmpz_divexact(c2, c, gcd); _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c2); fmpz_divexact(rden, den, gcd); fmpz_clear(c2); } fmpz_clear(gcd); }
// truncated multiplication for fmpz void fmpz_mul_trunc(fmpz_t res, fmpz_t a, fmpz_t b, unsigned long trunc) { unsigned long sizea = FLINT_MIN(fmpz_size(a), trunc); unsigned long sizeb = FLINT_MIN(fmpz_size(b), trunc); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; if ((sizea == 0) || (sizeb == 0)) { res[0] = 0; return; } if (trunc >= sizea + sizeb) { mp_limb_t mslimb; if (sizea >= sizeb) mslimb = F_mpn_mul(res+1, a+1, sizea, b+1, sizeb); else mslimb = F_mpn_mul(res+1, b+1, sizeb, a+1, sizea); res[0] = sizea + sizeb - (mslimb == 0); } else { mp_limb_t mslimb; fmpz_t temp = flint_stack_alloc(sizea + sizeb + 1); if (sizea >= sizeb) mslimb = F_mpn_mul_trunc(temp+1, a+1, sizea, b+1, sizeb, trunc); else mslimb = F_mpn_mul_trunc(temp+1, b+1, sizeb, a+1, sizea, trunc); temp[0] = trunc; if (UNLIKELY(!mslimb)) __fmpz_normalise(temp); // normalise if most significant limb == 0 fmpz_set(res, temp); flint_stack_release(); } if ((long) (a[0] ^ b[0]) < 0L) res[0] = -res[0]; }
void fmpz_div_2exp(fmpz_t output, fmpz_t x, unsigned long exp) { unsigned long limbs = (exp >> FLINT_LG_BITS_PER_LIMB); unsigned long bits = (exp & (FLINT_BITS - 1)); if ((x[0] == 0) || (limbs >= FLINT_ABS(x[0]))) { output[0] = 0L; return; } if (bits) { fmpz_t temp = fmpz_init(FLINT_ABS(x[0]) - limbs); mpn_rshift(temp + 1, x + limbs + 1, FLINT_ABS(x[0]) - limbs, bits); if ((long) x[0] >= 0L) temp[0] = x[0] - limbs; else temp[0] = limbs + x[0]; NORM(temp); fmpz_set(output, temp); fmpz_clear(temp); } else { F_mpn_copy(output + 1, x + limbs + 1, FLINT_ABS(x[0]) - limbs); if ((long) x[0] >= 0L) output[0] = x[0] - limbs; else output[0] = limbs + x[0]; } }
static void fmpz_poly_mat_get_fmpz_mat(fmpz_mat_t B, const fmpz_poly_mat_t A) { long i, j; if (!(A->r == B->r && A->c == B->c)) { printf("ERROR (fmpz_poly_mat_get_fmpz_mat). Incompatible dimensions.\n"); abort(); } for (i = 0; i < A->r; i++) for (j = 0; j < A->c; j++) { const fmpz_poly_struct *poly = fmpz_poly_mat_entry(A, i, j); const long len = poly->length; if (len == 0) { fmpz_zero(fmpz_mat_entry(B, i, j)); } else if (len == 1) { fmpz_set(fmpz_mat_entry(B, i, j), poly->coeffs + 0); } else { printf("ERROR (fmpz_poly_mat_get_fmpz_mat).\n"); printf("A contains a polynomial of length greater than 1.\n"); abort(); } } }
void _fmpq_poly_compose(fmpz * res, fmpz_t den, const fmpz * poly1, const fmpz_t den1, long len1, const fmpz * poly2, const fmpz_t den2, long len2) { if (*den2 == 1L) { _fmpz_poly_compose(res, poly1, len1, poly2, len2); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, (len1 - 1L) * (len2 - 1L) + 1L); } else { fmpz_t one; fmpz * v = _fmpz_vec_init(len1); fmpz_init(one); fmpz_one(one); _fmpq_poly_rescale(v, den, poly1, den1, len1, one, den2); _fmpz_poly_compose(res, v, len1, poly2, len2); _fmpq_poly_canonicalise(res, den, (len1 - 1L) * (len2 - 1L) + 1L); fmpz_clear(one); _fmpz_vec_clear(v, len1); } }
int fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state, const fmpz * diag, long n) { int parity; long i; long * rows; long * cols; rows = malloc(sizeof(long) * mat->r); cols = malloc(sizeof(long) * mat->c); for (i = 0; i < mat->r; i++) rows[i] = i; for (i = 0; i < mat->c; i++) cols[i] = i; parity = shuffle(rows, state, mat->r); parity ^= shuffle(cols, state, mat->c); fmpz_mat_zero(mat); for (i = 0; i < n; i++) fmpz_set(&mat->rows[rows[i]][cols[i]], &diag[i]); free(rows); free(cols); return parity; }
void _fmpz_holonomic_eval_companion_matrix_fmpz(fmpz_mat_t M, fmpz_t Q, const fmpz_holonomic_t op, long n) { fmpz_t c; long r = fmpz_holonomic_order(op); long i, j; fmpz_init(c); fmpz_set_si(c, n); fmpz_poly_evaluate_fmpz(Q, op->coeffs + r, c); for (i = 0; i < r - 1; i++) { for (j = 0; j < r; j++) { if (i + 1 == j) fmpz_set(M->rows[i] + j, Q); else fmpz_zero(M->rows[i] + j); } } for (j = 0; j < r; j++) { fmpz_poly_evaluate_fmpz(M->rows[r - 1] + j, op->coeffs + j, c); fmpz_neg(M->rows[r - 1] + j, M->rows[r - 1] + j); } fmpz_clear(c); }
void fmpq_poly_get_slice(fmpq_poly_t rop, const fmpq_poly_t op, long i, long j) { i = FLINT_MAX(i, 0); j = FLINT_MIN(j, op->length); if (i < j) { long k; if (rop == op) { for (k = 0; k < i; k++) fmpz_zero(rop->coeffs + k); for (k = j; k < rop->length; k++) fmpz_zero(rop->coeffs + k); fmpq_poly_canonicalise(rop); } else { fmpq_poly_fit_length(rop, j); _fmpq_poly_set_length(rop, j); _fmpz_vec_set(rop->coeffs + i, op->coeffs + i, j - i); fmpz_set(rop->den, op->den); fmpq_poly_canonicalise(rop); } } else { fmpq_poly_zero(rop); } }
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 fmpr_get_fmpq(fmpq_t y, const fmpr_t x) { if (fmpr_is_zero(x)) { fmpq_zero(y); } else if (fmpr_is_special(x) || COEFF_IS_MPZ(*fmpr_expref(x))) { printf("exception: fmpr_get_fmpq: cannot convert to rational\n"); abort(); } else { long exp = *fmpr_expref(x); fmpz_set_ui(fmpq_denref(y), 1UL); if (exp >= 0) { fmpz_mul_2exp(fmpq_numref(y), fmpr_manref(x), exp); } else { fmpz_set(fmpq_numref(y), fmpr_manref(x)); fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), -exp); } } }
void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, slong len, ulong c) { fmpz_t gcd; /* GCD( den, c ) */ if (c == 0) { _fmpz_vec_zero(rpoly, len); fmpz_one(rden); return; } fmpz_init(gcd); fmpz_set_ui(gcd, c); fmpz_gcd(gcd, gcd, den); if (*gcd == WORD(1)) { _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c); fmpz_set(rden, den); } else { ulong gcd2 = fmpz_get_ui(gcd); ulong c2 = c / gcd2; _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c2); fmpz_fdiv_q_ui(rden, den, gcd2); } fmpz_clear(gcd); }
void _fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n) { slong i; fmpz *R, *S, *T, *tmp; if (n <= 2) { _fmpz_vec_set(Qinv, Q, n); return; } R = _fmpz_vec_init(n - 1); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); fmpz_zero(Qinv); fmpz_set(Qinv + 1, Q + 1); _fmpz_poly_inv_series(R, Q + 1, n - 1); _fmpz_vec_set(S, R, n - 1); for (i = 2; i < n; i++) { _fmpz_poly_mullow(T, S, n - 1, R, n - 1, n - 1); fmpz_divexact_ui(Qinv + i, T + i - 1, i); tmp = S; S = T; T = tmp; } _fmpz_vec_clear(R, n - 1); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); }
void _fmpz_mat_inv_2x2(fmpz ** b, fmpz_t den, fmpz ** const a) { fmpz_t tmp; _fmpz_mat_det_cofactor_2x2(den, a); fmpz_neg(&b[0][1], &a[0][1]); fmpz_neg(&b[1][0], &a[1][0]); fmpz_init(tmp); fmpz_set(tmp, &a[0][0]); fmpz_set(&b[0][0], &a[1][1]); fmpz_set(&b[1][1], tmp); fmpz_clear(tmp); }
int fmpz_mat_inv(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A) { long dim = A->r; if (dim == 0) { fmpz_one(den); return 1; } else if (dim == 1) { fmpz_set(den, A->entries); fmpz_one(B->entries); return !fmpz_is_zero(den); } else if (dim == 2) { _fmpz_mat_inv_2x2(B->rows, den, A->rows); return !fmpz_is_zero(den); } else { fmpz_mat_t I; long i; int success; fmpz_mat_init(I, dim, dim); for (i = 0; i < dim; i++) fmpz_one(fmpz_mat_entry(I, i, i)); success = fmpz_mat_solve_fflu(B, den, A, I); fmpz_mat_clear(I); return success; } }
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 padic_ctx_init(padic_ctx_t ctx, const fmpz_t p, long N, enum padic_print_mode mode) { fmpz_init(ctx->p); fmpz_set(ctx->p, p); ctx->N = N; ctx->pinv = (!COEFF_IS_MPZ(*p)) ? n_precompute_inverse(fmpz_get_ui(p)) : 0; if (N > 0) { long i, len; ctx->min = FLINT_MAX(1, N - 10); ctx->max = N + 10; len = ctx->max - ctx->min; ctx->pow = _fmpz_vec_init(len); fmpz_pow_ui(ctx->pow, p, ctx->min); for (i = 1; i < len; i++) fmpz_mul(ctx->pow + i, ctx->pow + (i - 1), p); } else { ctx->min = 0; ctx->max = 0; ctx->pow = NULL; } ctx->mode = mode; }