static void _mpq_harmonic_odd_balanced(fmpz_t num, fmpz_t den, long n) { mpz_t p, q; mp_ptr t, v; mp_size_t ts, vs; long size; if (n <= 0) { fmpz_zero(num); fmpz_one(den); return; } /* TODO: we could avoid the copying/allocation overhead when there is guaranteed to be sufficient space in res already */ size = FLINT_BIT_COUNT(n) * (n+2) + 2*FLINT_BITS; mpz_init2(p, size); mpz_init2(q, size); t = p->_mp_d; v = q->_mp_d; mpn_harmonic_odd_balanced(t, &ts, v, &vs, 1, n+1, n, 1); p->_mp_size = ts; q->_mp_size = vs; fmpz_set_mpz(num, p); fmpz_set_mpz(den, q); mpz_clear(p); mpz_clear(q); _fmpq_canonicalise(num, den); }
void _fmpq_randtest(fmpz_t num, fmpz_t den, flint_rand_t state, mp_bitcnt_t bits) { ulong x = n_randlimb(state); fmpz_randtest(num, state, bits); fmpz_randtest_not_zero(den, state, bits); switch (x % 16) { case 0: fmpz_set_si(num, 1); break; case 1: fmpz_set_si(num, -1); break; case 2: fmpz_set_si(num, 2); break; case 3: fmpz_set_si(num, -2); break; } switch ((x / 16) % 16) { case 0: fmpz_set_si(den, 1); break; case 2: fmpz_set_si(den, 2); break; } _fmpq_canonicalise(num, den); }
void nf_elem_add_si(nf_elem_t a, const nf_elem_t b, slong c, const nf_t nf) { if (nf->flag & NF_LINEAR) { fmpz * den = LNF_ELEM_DENREF(a); fmpz * num = LNF_ELEM_NUMREF(a); nf_elem_set(a, b, nf); if (c >= 0) fmpz_addmul_ui(num, den, c); else fmpz_submul_ui(num, den, -c); _fmpq_canonicalise(num, den); } else if (nf->flag & NF_QUADRATIC) { fmpz * den = QNF_ELEM_DENREF(a); fmpz * num = QNF_ELEM_NUMREF(a); slong len = 2; nf_elem_set(a, b, nf); while (len != 0 && fmpz_is_zero(num + len - 1)) len--; if (c >= 0) fmpz_addmul_ui(num, den, c); else fmpz_submul_ui(num, den, -c); _fmpq_poly_canonicalise(num, den, len); } else { fmpq_poly_add_si(NF_ELEM(a), NF_ELEM(b), c); } }
void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden, const fmpz *poly1, const fmpz_t den1, long len1, const fmpz *poly2, const fmpz_t den2, long len2) { if (len2 == 1) { if (len1 == 1) { fmpz_one(rnum); fmpz_one(rden); } else if (len1 == 2) { fmpz_set(rnum, poly2); fmpz_set(rden, den2); } else { fmpz_pow_ui(rnum, poly2, len1 - 1); if (fmpz_is_one(den2)) { fmpz_one(rden); } else { fmpz_pow_ui(rden, den2, len1 - 1); } } } else /* len1 >= len2 >= 2 */ { fmpz_t c1, c2; fmpz *prim1, *prim2, *g; long lenG = len2; fmpz_init(c1); fmpz_init(c2); _fmpz_vec_content(c1, poly1, len1); _fmpz_vec_content(c2, poly2, len2); prim1 = _fmpz_vec_init(len1); prim2 = _fmpz_vec_init(len2); g = _fmpz_vec_init(len2); _fmpz_vec_scalar_divexact_fmpz(prim1, poly1, len1, c1); _fmpz_vec_scalar_divexact_fmpz(prim2, poly2, len2, c2); _fmpz_poly_gcd(g, prim1, len1, prim2, len2); FMPZ_VEC_NORM(g, lenG); if (lenG > 1) { fmpz_zero(rnum); fmpz_one(rden); } else /* prim1, prim2 are coprime */ { fmpz_t t; fmpz_init(t); _fmpz_poly_resultant(rnum, prim1, len1, prim2, len2); if (!fmpz_is_one(c1)) { fmpz_pow_ui(t, c1, len2 - 1); fmpz_mul(rnum, rnum, t); } if (!fmpz_is_one(c2)) { fmpz_pow_ui(t, c2, len1 - 1); fmpz_mul(rnum, rnum, t); } if (fmpz_is_one(den1)) { if (fmpz_is_one(den2)) fmpz_one(rden); else fmpz_pow_ui(rden, den2, len1 - 1); } else { if (fmpz_is_one(den2)) fmpz_pow_ui(rden, den1, len2 - 1); else { fmpz_pow_ui(rden, den1, len2 - 1); fmpz_pow_ui(t, den2, len1 - 1); fmpz_mul(rden, rden, t); } } _fmpq_canonicalise(rnum, rden); fmpz_clear(t); } fmpz_clear(c1); fmpz_clear(c2); _fmpz_vec_clear(prim1, len1); _fmpz_vec_clear(prim2, len2); _fmpz_vec_clear(g, len2); } }