void __fmpz_mul(fmpz_t res, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = FLINT_ABS(b0); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; mp_limb_t mslimb; fmpz_t temp; if ((sizea == 0) || (sizeb == 0)) { res[0] = 0; } else if (sizea + sizeb < 100) { if (sizea >= sizeb) mslimb = mpn_mul(res+1, a+1, sizea, b+1, sizeb); else mslimb = mpn_mul(res+1, b+1, sizeb, a+1, sizea); res[0] = sizea + sizeb - (mslimb == 0); if ((long) (a[0] ^ b[0]) < 0) res[0] = -res[0]; } else { 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); if ((long) (a[0] ^ b[0]) < 0) 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]; } }
void fmpz_addmul(fmpz_t res, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = FLINT_ABS(b0); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; fmpz_t temp; mp_limb_t mslimb; if (sizea && sizeb) { if (sizea + sizeb < 100) { temp = (fmpz_t) flint_stack_alloc_small(sizea + sizeb + 1); if (sizea >= sizeb) mslimb = mpn_mul(temp+1, a+1, sizea, b+1, sizeb); else mslimb = mpn_mul(temp+1, b+1, sizeb, a+1, sizea); temp[0] = sizea + sizeb - (mslimb == 0); if ((long) (a[0] ^ b[0]) < 0) temp[0] = -temp[0]; fmpz_add(res, res, temp); flint_stack_release_small(); } else { temp = (fmpz_t) flint_stack_alloc(sizea + sizeb + 1); if (sizea >= sizeb) mslimb = F_mpn_mul(temp+1, a+1, sizea, b+1, sizeb); else mslimb = F_mpn_mul(temp+1, b+1, sizeb, a+1, sizea); temp[0] = sizea + sizeb - (mslimb == 0); if ((long) (a[0] ^ b[0]) < 0) temp[0] = -temp[0]; fmpz_add(res, res, temp); flint_stack_release(); } } }
void fmpz_tdiv(fmpz_t res, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = FLINT_ABS(b0); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; mp_limb_t mslimb; fmpz_t temp; if (sizeb == 0) { printf("Error: division by zero!\n"); abort(); } else if (sizea < sizeb) // Todo: make this deal with sizea == sizeb but a < b { res[0] = 0; } else { temp = (fmpz_t) flint_stack_alloc(sizeb); mpn_tdiv_qr(res+1, temp, 0, a+1, sizea, b+1, sizeb); res[0] = sizea - sizeb + 1; if ((long) (a0 ^ b0) < 0) res[0] = -res[0]; flint_stack_release(); } NORM(res); }
ulong z_gcd(long a, long b) { ulong ua = FLINT_ABS(a); ulong ub = FLINT_ABS(b); return (ua >= ub) ? n_gcd(ua, ub) : n_gcd(ub, ua); }
void fmpz_mul(fmpz_t res, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = FLINT_ABS(b0); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; mp_limb_t mslimb; fmpz_t temp; if ((sizea == 0) || (sizeb == 0)) { res[0] = 0; } else if (sizea + sizeb < 100) { temp = (fmpz_t) flint_stack_alloc_small(sizea + sizeb + 1); if (sizea > sizeb) mslimb = mpn_mul(temp+1, a+1, sizea, b+1, sizeb); else if (sizea == sizeb) { mpn_mul_n(temp+1, a+1, b+1, sizeb); mslimb = temp[2*sizeb]; } else mslimb = mpn_mul(temp+1, b+1, sizeb, a+1, sizea); temp[0] = sizea + sizeb - (mslimb == 0); F_mpn_copy(res, temp, temp[0]+1); if ((long) (a0 ^ b0) < 0) res[0] = -res[0]; flint_stack_release_small(); } else if (sizea + sizeb < 2*FLINT_FFT_LIMBS_CROSSOVER) { temp = (fmpz_t) flint_stack_alloc(sizea + sizeb + 1); if (sizea > sizeb) mslimb = mpn_mul(temp+1, a+1, sizea, b+1, sizeb); else if (sizea == sizeb) { mpn_mul_n(temp+1, a+1, b+1, sizeb); mslimb = temp[2*sizeb]; } else mslimb = mpn_mul(temp+1, b+1, sizeb, a+1, sizea); temp[0] = sizea + sizeb - (mslimb == 0); F_mpn_copy(res, temp, temp[0]+1); if ((long) (a0 ^ b0) < 0) res[0] = -res[0]; flint_stack_release(); } else { 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); if ((long) (a0 ^ b0) < 0) res[0] = -res[0]; } }
int n_is_probabprime_fibonacci(mp_limb_t n) { mp_limb_t m; n_pair_t V; if (FLINT_ABS((mp_limb_signed_t) n) <= 3UL) { if (n >= 2UL) return 1; return 0; } m = (n - n_jacobi(5L, n)) / 2; /* cannot overflow as (5/n) = 0 for n = 2^64-1 */ if (FLINT_BIT_COUNT(n) <= FLINT_D_BITS) { double npre = n_precompute_inverse(n); V = fchain_precomp(m, n, npre); return (n_mulmod_precomp(n - 3UL, V.x, n, npre) == n_mulmod_precomp(2UL, V.y, n, npre)); } else { mp_limb_t ninv = n_preinvert_limb(n); V = fchain2_preinv(m, n, ninv); return (n_mulmod2_preinv(n - 3UL, V.x, n, ninv) == n_mulmod2_preinv(2UL, V.y, n, ninv)); } }
int fmpq_get_mpfr(mpfr_t r, const fmpq_t x, mpfr_rnd_t rnd) { __mpq_struct mpq; fmpz p, q; mp_limb_t pp, qq; p = *fmpq_numref(x); q = *fmpq_denref(x); if (p == 0) return mpfr_set_ui(r, 0, rnd); if (COEFF_IS_MPZ(p)) mpq._mp_num = *COEFF_TO_PTR(p); else { pp = FLINT_ABS(p); mpq._mp_num._mp_alloc = 1; mpq._mp_num._mp_size = (p < 0) ? -1 : 1; mpq._mp_num._mp_d = &pp; } if (COEFF_IS_MPZ(q)) mpq._mp_den = *COEFF_TO_PTR(q); else { qq = q; mpq._mp_den._mp_alloc = 1; mpq._mp_den._mp_size = 1; mpq._mp_den._mp_d = &qq; } return mpfr_set_q(r, &mpq, rnd); }
void fmpz_fdiv(fmpz_t res, const fmpz_t a, const fmpz_t b) { long a0 = a[0]; long b0 = b[0]; unsigned long sizea = FLINT_ABS(a0); unsigned long sizeb = FLINT_ABS(b0); while ((!a[sizea]) && (sizea)) sizea--; while ((!b[sizeb]) && (sizeb)) sizeb--; mp_limb_t mslimb; fmpz_t temp; if (sizeb == 0) { printf("Error: division by zero!\n"); abort(); } else if (sizea < sizeb) // Todo: make this deal with sizea == sizeb but a < b { if (((long) (a0 ^ b0) < 0L) && (a0)) { res[0] = -1L; res[1] = 1; } else res[0] = 0; return; } else { temp = (fmpz_t) flint_stack_alloc(sizeb); mpn_tdiv_qr(res+1, temp, 0, a+1, sizea, b+1, sizeb); res[0] = sizea - sizeb + 1; if ((long) (a0 ^ b0) < 0L) res[0] = -res[0]; NORM(res); if ((long) (a0 ^ b0) < 0L) { unsigned long i = 0; for (; i < sizeb; i++) { if (temp[i]) break; } if (i < sizeb) { fmpz_sub_ui_inplace(res, 1UL); } } flint_stack_release(); } }
double fmpz_get_d(fmpz_t x) { mpz_t x_m; x_m->_mp_d = x + 1; x_m->_mp_size = x[0]; x_m->_mp_alloc = FLINT_ABS(x[0]); return mpz_get_d(x_m); }
void fmpz_gcd(fmpz_t f, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(g)) { fmpz_abs(f, h); return; } if (fmpz_is_zero(h)) { fmpz_abs(f, g); return; } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (!COEFF_IS_MPZ(c2)) /* h is also small */ { fmpz_set_si(f, z_gcd(c1, c2)); } else /* h is large, but g is small */ { fmpz c2d = fmpz_fdiv_ui(h, FLINT_ABS(c1)); fmpz_set_si(f, z_gcd(c1, c2d)); } } else { if (!COEFF_IS_MPZ(c2)) /* h is small, but g is large */ { fmpz c1d = fmpz_fdiv_ui(g, FLINT_ABS(c2)); fmpz_set_si(f, z_gcd(c2, c1d)); } else /* g and h are both large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); /* aliasing fine as g, h already large */ mpz_gcd(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); _fmpz_demote_val(f); /* gcd may be small */ } } }
static __inline__ mp_limb_t nmod_set_si(long v, nmod_t mod) { mp_limb_t u = n_mod2_preinv(FLINT_ABS(v), mod.n, mod.ninv); if (v < 0) u = n_negmod(u, mod.n); return u; }
slong fmpr_mul_fmpz(fmpr_t z, const fmpr_t x, const fmpz_t y, slong prec, fmpr_rnd_t rnd) { fmpz xv, yv; fmpz yexp; if (fmpr_is_special(x) || fmpz_is_zero(y)) { if (fmpr_is_zero(x)) { fmpr_zero(z); } else if (fmpz_is_zero(y) && fmpr_is_finite(x)) { fmpr_zero(z); } else if (fmpr_is_inf(x) && !fmpz_is_zero(y)) { if (fmpr_sgn(x) == fmpz_sgn(y)) fmpr_pos_inf(z); else fmpr_neg_inf(z); } else { fmpr_nan(z); } return FMPR_RESULT_EXACT; } xv = *fmpr_manref(x); yv = *y; if (!COEFF_IS_MPZ(xv) && !COEFF_IS_MPZ(yv)) { mp_limb_t ytmp; unsigned int bc; ytmp = FLINT_ABS(yv); count_trailing_zeros(bc, ytmp); ytmp >>= bc; yexp = bc; return _fmpr_mul_1x1(z, FLINT_ABS(xv), fmpr_expref(x), ytmp, &yexp, (xv ^ yv) < 0, prec, rnd); }
void fmpz_tdiv_ui(fmpz_t output, const fmpz_t input, const unsigned long x) { output[0] = input[0]; unsigned long size = FLINT_ABS(input[0]); mpn_divmod_1(output+1, input+1, size, x); NORM(output); }
int main(void) { int i, result; flint_rand_t state; printf("dlog...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 10000; i++) { fmpz_t x; mpz_t z; mpfr_t r; double y, w; fmpz_init(x); mpz_init(z); mpfr_init2(r, 53); fmpz_randtest_not_zero(x, state, 10000); fmpz_abs(x, x); y = fmpz_dlog(x); fmpz_get_mpz(z, x); mpfr_set_z(r, z, MPFR_RNDN); mpfr_log(r, r, MPFR_RNDN); w = mpfr_get_d(r, MPFR_RNDN); result = (FLINT_ABS(y - w) <= w * 1e-13); if (!result) { printf("FAIL:\n"); printf("x = "), fmpz_print(x), printf("\n"); printf("y = %.20g\n", y); printf("w = %.20g\n", w); abort(); } fmpz_clear(x); mpz_clear(z); mpfr_clear(r); } mpfr_free_cache(); flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) { long dim, m, n, k, ab, bb; m = A->r; n = A->c; k = B->c; if (C == A || C == B) { fmpz_mat_t t; fmpz_mat_init(t, m, k); fmpz_mat_mul(t, A, B); fmpz_mat_swap(C, t); fmpz_mat_clear(t); return; } dim = FLINT_MIN(FLINT_MIN(m, n), k); if (dim < 10) { fmpz_mat_mul_classical(C, A, B); return; } ab = fmpz_mat_max_bits(A); bb = fmpz_mat_max_bits(B); ab = FLINT_ABS(ab); bb = FLINT_ABS(bb); if (5*(ab + bb) > dim * dim) { fmpz_mat_mul_classical(C, A, B); } else { _fmpz_mat_mul_multi_mod(C, A, B, ab + bb + FLINT_BIT_COUNT(n) + 1); } }
/* The coefficients in 2^d * \prod_{i=1}^d (x - cos(a_i)) are easily bounded using the binomial theorem. */ static slong magnitude_bound(slong d) { slong res; fmpz_t t; fmpz_init(t); fmpz_bin_uiui(t, d, d / 2); res = fmpz_bits(t); fmpz_clear(t); return FLINT_ABS(res) + d; }
int main(void) { int i, result; flint_rand_t state; flint_randinit(state); printf("sdiv_qrnnd...."); fflush(stdout); for (i = 0; i < 1000000; i++) { mp_limb_signed_t d, nh, nl, q, r, ph, pl; do { d = n_randtest_not_zero(state); nh = n_randtest(state); } while (FLINT_ABS(nh) >= FLINT_ABS(d)/2); nl = n_randtest(state); sdiv_qrnnd(q, r, nh, nl, d); smul_ppmm(ph, pl, d, q); if (r < 0L) sub_ddmmss(ph, pl, ph, pl, 0UL, -r); else add_ssaaaa(ph, pl, ph, pl, 0UL, r); result = ((ph == nh) && (pl == nl)); if (!result) { printf("FAIL:\n"); printf("nh = %lu, nl = %lu, d = %lu\n", nh, nl, d); printf("ph = %lu, pl = %lu\n", ph, pl); abort(); } } flint_randclear(state); printf("PASS\n"); return 0; }
void fmpz_mul_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)); mp_limb_t msl = 0L; if (x[0] == 0) { output[0] = 0L; return; } if (bits) { msl = mpn_lshift(output + limbs + 1, x + 1, FLINT_ABS(x[0]), bits); if (msl) output[limbs + FLINT_ABS(x[0]) + 1] = msl; } else F_mpn_copy(output + limbs + 1, x + 1, FLINT_ABS(x[0])); if (limbs) F_mpn_clear(output + 1, limbs); if ((long) x[0] >= 0L) output[0] = x[0] + limbs + (msl != 0L); else output[0] = x[0] - limbs - (msl != 0L); }
void fmpz_mul_ui(fmpz_t output, const fmpz_t input, const unsigned long x) { if (x == 0) { output[0] = 0; return; } mp_limb_t mslimb; if (output[0] = input[0]) // This isn't a typo { mslimb = mpn_mul_1(output+1, input+1, FLINT_ABS(input[0]), x); if (mslimb) { output[FLINT_ABS(input[0])+1] = mslimb; if ((long) output[0] > 0) output[0]++; else output[0]--; } } }
/* hack: avoid overflow since exp currently uses mpfr */ void fmpq_poly_randtest_small(fmpq_poly_t A, flint_rand_t state, long len, long bits) { fmpq_poly_randtest(A, state, len, bits); if (A->length > 0) { bits = _fmpz_vec_max_bits(A->coeffs, A->length); bits = FLINT_ABS(bits); fmpz_mul_2exp(A->den, A->den, bits); _fmpq_poly_normalise(A); } }
void fmpz_gcd(fmpz_t output, fmpz_t x1, fmpz_t x2) { ulong size1 = FLINT_ABS(x1[0]); ulong size2 = FLINT_ABS(x2[0]); mpz_t m1, m2, m0, m_out; m1->_mp_d = x1 + 1; m2->_mp_d = x2 + 1; m1->_mp_alloc = size1; m1->_mp_size = size1; m2->_mp_alloc = size2; m2->_mp_size = size2; ulong size_out = FLINT_MAX(size1, size2)+1; m0->_mp_d = flint_stack_alloc(size_out); m0->_mp_alloc = size_out; m0->_mp_size = 0; mpz_gcd(m0, m1, m2); size_out = m0->_mp_size; F_mpn_copy(output + 1, m0->_mp_d, size_out); output[0] = size_out; flint_stack_release(); }
int fmpz_cmpabs(const fmpz_t f, const fmpz_t g) { if (f == g) return 0; /* aliased inputs */ if (!COEFF_IS_MPZ(*f)) { if (!COEFF_IS_MPZ(*g)) { mp_limb_t uf = FLINT_ABS(*f); mp_limb_t ug = FLINT_ABS(*g); return (uf < ug ? -1 : (uf > ug)); } else return -1; } else { if (!COEFF_IS_MPZ(*g)) return 1; /* f is large, so if g isn't... */ else return mpz_cmpabs(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g)); } }
static __inline__ int low_bits_are_zero(const fmpz_t u, int bits) { fmpz f = *u; mp_limb_t low; if (!COEFF_IS_MPZ(f)) low = FLINT_ABS(f); else low = COEFF_TO_PTR(f)->_mp_d[0]; return (low & ((UWORD(1) << bits) - 1)) == 0; }
void fmpz_mul_si(fmpz_t f, const fmpz_t g, long x) { fmpz c2 = *g; if (x == 0) { fmpz_zero(f); return; } else if (!COEFF_IS_MPZ(c2)) /* c2 is small */ { mp_limb_t prod[2]; mp_limb_t uc2 = FLINT_ABS(c2); mp_limb_t ux = FLINT_ABS(x); /* unsigned limb by limb multiply (assembly for most CPU's) */ umul_ppmm(prod[1], prod[0], uc2, ux); if (!prod[1]) /* result fits in one limb */ { fmpz_set_ui(f, prod[0]); if ((c2 ^ x) < 0L) fmpz_neg(f, f); } else /* result takes two limbs */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); /* two limbs, least significant first, native endian, no nails, stored in prod */ mpz_import(mpz_ptr, 2, -1, sizeof(mp_limb_t), 0, 0, prod); if ((c2 ^ x) < 0L) mpz_neg(mpz_ptr, mpz_ptr); } } else /* c2 is large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); /* ok without val as if aliased both are large */ mpz_mul_si(mpz_ptr, COEFF_TO_PTR(c2), x); } }
unsigned long fmpz_mod_ui(const fmpz_t input, const unsigned long x) { unsigned long size = FLINT_ABS(input[0]); unsigned long mod; mod = mpn_mod_1(input+1, size, x); if (!mod) return mod; else if ((long) input[0] < 0L) { return x - mod; } else return mod; }
static void bsplit(arb_poly_t pol, const arb_t sqrtD, const slong * qbf, slong a, slong b, slong prec) { if (b - a == 0) { arb_poly_one(pol); } else if (b - a == 1) { acb_t z; acb_init(z); /* j((-b+sqrt(-D))/(2a)) */ arb_set_si(acb_realref(z), -FLINT_ABS(qbf[3 * a + 1])); arb_set(acb_imagref(z), sqrtD); acb_div_si(z, z, 2 * qbf[3 * a], prec); acb_modular_j(z, z, prec); if (qbf[3 * a + 1] < 0) { /* (x^2 - 2re(j) x + |j|^2) */ arb_poly_fit_length(pol, 3); arb_mul(pol->coeffs, acb_realref(z), acb_realref(z), prec); arb_addmul(pol->coeffs, acb_imagref(z), acb_imagref(z), prec); arb_mul_2exp_si(pol->coeffs + 1, acb_realref(z), 1); arb_neg(pol->coeffs + 1, pol->coeffs + 1); arb_one(pol->coeffs + 2); _arb_poly_set_length(pol, 3); } else { /* (x-j) */ arb_poly_fit_length(pol, 2); arb_neg(pol->coeffs, acb_realref(z)); arb_one(pol->coeffs + 1); _arb_poly_set_length(pol, 2); } acb_clear(z); } else { arb_poly_t tmp; arb_poly_init(tmp); bsplit(pol, sqrtD, qbf, a, a + (b - a) / 2, prec); bsplit(tmp, sqrtD, qbf, a + (b - a) / 2, b, prec); arb_poly_mul(pol, pol, tmp, prec); arb_poly_clear(tmp); } }
int main(void) { int i, result; flint_rand_t state; printf("height...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 10000; i++) { fmpz *a; fmpz_t h; long len, bits, bits2; fmpz_init(h); len = n_randint(state, 100); a = _fmpz_vec_init(len); bits = n_randint(state, 200); _fmpz_vec_randtest(a, state, len, bits); bits2 = _fmpz_vec_max_bits(a, len); _fmpz_vec_height(h, a, len); result = (fmpz_bits(h) == FLINT_ABS(bits2)) && (fmpz_sgn(h) >= 0); if (!result) { printf("FAIL:\n"); printf("bits = %ld, bits2 = %ld\n", bits, bits2); printf("Computed height:\n"); fmpz_print(h); printf("\n"); abort(); } fmpz_clear(h); _fmpz_vec_clear(a, len); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("max_bits...."); fflush(stdout); for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz *a; slong len, bits, bits2, bits3; len = n_randint(state, 100); a = _fmpz_vec_init(len); bits = n_randint(state, 200); _fmpz_vec_randtest(a, state, len, bits); bits2 = _fmpz_vec_max_bits(a, len); bits3 = _fmpz_vec_max_bits_ref(a, len); result = (bits >= FLINT_ABS(bits2) && bits2 == bits3); if (!result) { flint_printf("FAIL:\n"); flint_printf("bits = %wd, bits2 = %wd bits3 = %wd\n", bits, bits2, bits3); abort(); } _fmpz_vec_clear(a, len); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void fmprb_mat_det_inplace(fmprb_t det, fmprb_mat_t A, long prec) { long i, n, sign, rank; n = fmprb_mat_nrows(A); rank = fmprb_mat_gauss_partial(A, prec); sign = (rank < 0) ? -1 : 1; rank = FLINT_ABS(rank); fmprb_set_si(det, sign); for (i = 0; i < rank; i++) fmprb_mul(det, det, fmprb_mat_entry(A, i, i), prec); /* bound unreduced part using Hadamard's inequality */ if (rank < n) { fmpr_t t; fmprb_t d; fmpr_init(t); fmprb_init(d); fmpr_one(fmprb_radref(d)); for (i = rank; i < n; i++) { fmprb_vec_get_fmpr_2norm_squared_bound(t, A->rows[i] + rank, n - rank, FMPRB_RAD_PREC); fmpr_mul(fmprb_radref(d), fmprb_radref(d), t, FMPRB_RAD_PREC, FMPR_RND_UP); } fmpr_sqrt(fmprb_radref(d), fmprb_radref(d), FMPRB_RAD_PREC, FMPR_RND_UP); fmprb_mul(det, det, d, prec); fmprb_clear(d); fmpr_clear(t); } }