int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("content...."); fflush(stdout); /* Check that content(a f) = abs(a) content(f) */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz_t a, c, d; fmpz *f; slong len = n_randint(state, 100); fmpz_init(a); fmpz_init(c); fmpz_init(d); f = _fmpz_vec_init(len); _fmpz_vec_randtest(f, state, len, 200); fmpz_randtest(a, state, 100); _fmpz_vec_content(c, f, len); _fmpz_vec_scalar_mul_fmpz(f, f, len, a); fmpz_abs(a, a); fmpz_mul(c, a, c); _fmpz_vec_content(d, f, len); result = (fmpz_equal(c, d)); if (!result) { flint_printf("FAIL:\n"); fmpz_print(c), flint_printf("\n\n"); fmpz_print(d), flint_printf("\n\n"); abort(); } fmpz_clear(a); fmpz_clear(c); fmpz_clear(d); _fmpz_vec_clear(f, len); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void _fmpq_poly_canonicalise(fmpz * poly, fmpz_t den, slong len) { if (*den == WORD(1)) return; if (*den == WORD(-1)) { _fmpz_vec_neg(poly, poly, len); fmpz_one(den); } else if (len == 0) { fmpz_one(den); } else { fmpz_t gcd; fmpz_init(gcd); _fmpz_vec_content(gcd, poly, len); if (*gcd != WORD(1)) fmpz_gcd(gcd, gcd, den); if (fmpz_sgn(den) < 0) fmpz_neg(gcd, gcd); if (*gcd != WORD(1)) { _fmpz_vec_scalar_divexact_fmpz(poly, poly, len, gcd); fmpz_divexact(den, den, gcd); } fmpz_clear(gcd); } }
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 _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_scalar_div_mpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, const fmpz_t r, const fmpz_t s) { fmpz_t gcd1; /* GCD( poly, r ) */ fmpz_t gcd2; /* GCD( s, den ) */ fmpz_init(gcd1); fmpz_init(gcd2); fmpz_set_ui(gcd1, 1); fmpz_set_ui(gcd2, 1); if (*r != 1L) { _fmpz_vec_content(gcd1, poly, len); if (*gcd1 != 1L) fmpz_gcd(gcd1, gcd1, r); } if (*den != 1L && *s != 1L) fmpz_gcd(gcd2, s, den); if (*gcd1 == 1L) { if (*gcd2 == 1L) { _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s); fmpz_mul(rden, den, r); } else { fmpz_t s2; fmpz_init(s2); fmpz_divexact(s2, s, gcd2); _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s2); fmpz_divexact(rden, den, gcd2); fmpz_mul(rden, rden, r); fmpz_clear(s2); } } else { fmpz_t r2; fmpz_init(r2); fmpz_divexact(r2, r, gcd1); if (*gcd2 == 1L) { _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s); fmpz_mul(rden, den, r2); } else { fmpz_t s2; fmpz_init(s2); fmpz_divexact(s2, s, gcd2); _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s2); fmpz_divexact(rden, den, gcd2); fmpz_mul(rden, rden, r2); fmpz_clear(s2); } fmpz_clear(r2); } if (_fmpz_vec_is_zero(rpoly, len)) fmpz_set_ui(rden, 1); if (fmpz_sgn(rden) < 0) { _fmpz_vec_neg(rpoly, rpoly, len); fmpz_neg(rden, rden); } fmpz_clear(gcd1); fmpz_clear(gcd2); }
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); } }