def dup_qq_heu_gcd(f, g, K0): """ Heuristic polynomial GCD in `Q[x]`. Returns ``(h, cff, cfg)`` such that ``a = gcd(f, g)``, ``cff = quo(f, h)``, and ``cfg = quo(g, h)``. Examples ======== >>> from diofant.polys import ring, QQ >>> R, x = ring("x", QQ) >>> f = QQ(1,2)*x**2 + QQ(7,4)*x + QQ(3,2) >>> g = QQ(1,2)*x**2 + x >>> R.dup_qq_heu_gcd(f, g) (x + 2, 1/2*x + 3/4, 1/2*x) """ result = _dup_ff_trivial_gcd(f, g, K0) if result is not None: return result K1 = K0.get_ring() cf, f = dup_clear_denoms(f, K0, K1) cg, g = dup_clear_denoms(g, K0, K1) f = dup_convert(f, K0, K1) g = dup_convert(g, K0, K1) h, cff, cfg = dup_zz_heu_gcd(f, g, K1) h = dup_convert(h, K1, K0) c = dup_LC(h, K0) h = dup_monic(h, K0) cff = dup_convert(cff, K1, K0) cfg = dup_convert(cfg, K1, K0) cff = dup_mul_ground(cff, K0.quo(c, cf), K0) cfg = dup_mul_ground(cfg, K0.quo(c, cg), K0) return h, cff, cfg
def dup_factor_list(f, K0): """Factor polynomials into irreducibles in `K[x]`. """ j, f = dup_terms_gcd(f, K0) cont, f = dup_primitive(f, K0) if K0.is_FiniteField: coeff, factors = dup_gf_factor(f, K0) elif K0.is_Algebraic: coeff, factors = dup_ext_factor(f, K0) else: if not K0.is_Exact: K0_inexact, K0 = K0, K0.get_exact() f = dup_convert(f, K0_inexact, K0) else: K0_inexact = None if K0.has_Field: K = K0.get_ring() denom, f = dup_clear_denoms(f, K0, K) f = dup_convert(f, K0, K) else: K = K0 if K.is_ZZ: coeff, factors = dup_zz_factor(f, K) elif K.is_Poly: f, u = dmp_inject(f, 0, K) coeff, factors = dmp_factor_list(f, u, K.domain) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.domain) else: # pragma: no cover raise DomainError('factorization not supported over %s' % K0) if K0.has_Field: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K, K0), k) coeff = K0.convert(coeff, K) if K0_inexact is None: coeff = coeff / denom else: for i, (f, k) in enumerate(factors): f = dup_quo_ground(f, denom, K0) f = dup_convert(f, K0, K0_inexact) factors[i] = (f, k) coeff = K0_inexact.convert(coeff * denom**i, K0) K0 = K0_inexact if j: factors.insert(0, ([K0.one, K0.zero], j)) return coeff * cont, _sort_factors(factors)
def test_dup_clear_denoms(): assert dup_clear_denoms([], QQ, ZZ) == (ZZ(1), []) assert dup_clear_denoms([QQ(1)], QQ, ZZ) == (ZZ(1), [QQ(1)]) assert dup_clear_denoms([QQ(7)], QQ, ZZ) == (ZZ(1), [QQ(7)]) assert dup_clear_denoms([QQ(7, 3)], QQ) == (ZZ(3), [QQ(7)]) assert dup_clear_denoms([QQ(7, 3)], QQ, ZZ) == (ZZ(3), [QQ(7)]) assert dup_clear_denoms( [QQ(3), QQ(1), QQ(0)], QQ, ZZ) == (ZZ(1), [QQ(3), QQ(1), QQ(0)]) assert dup_clear_denoms( [QQ(1), QQ(1, 2), QQ(0)], QQ, ZZ) == (ZZ(2), [QQ(2), QQ(1), QQ(0)]) assert dup_clear_denoms([QQ(3), QQ( 1), QQ(0)], QQ, ZZ, convert=True) == (ZZ(1), [ZZ(3), ZZ(1), ZZ(0)]) assert dup_clear_denoms([QQ(1), QQ( 1, 2), QQ(0)], QQ, ZZ, convert=True) == (ZZ(2), [ZZ(2), ZZ(1), ZZ(0)]) assert dup_clear_denoms( [EX(Rational(3, 2)), EX(Rational(9, 4))], EX) == (EX(4), [EX(6), EX(9)]) assert dup_clear_denoms([EX(7)], EX) == (EX(1), [EX(7)]) assert dup_clear_denoms([EX(sin(x)/x), EX(0)], EX) == (EX(x), [EX(sin(x)), EX(0)])