def dmp_sqf_list(f, u, K, all=False): """ Return square-free decomposition of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dmp_sqf_list >>> f = ZZ.map([[1], [2, 0], [1, 0, 0], [], [], []]) >>> dmp_sqf_list(f, 1, ZZ) (1, [([[1], [1, 0]], 2), ([[1], []], 3)]) >>> dmp_sqf_list(f, 1, ZZ, all=True) (1, [([[1]], 1), ([[1], [1, 0]], 2), ([[1], []], 3)]) """ if not u: return dup_sqf_list(f, K, all=all) if not K.has_CharacteristicZero: return dmp_gf_sqf_list(f, u, K, all=all) if K.has_Field or not K.is_Exact: coeff = dmp_ground_LC(f, u, K) f = dmp_ground_monic(f, u, K) else: coeff, f = dmp_ground_primitive(f, u, K) if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) coeff = -coeff if dmp_degree(f, u) <= 0: return coeff, [] result, i = [], 1 h = dmp_diff(f, 1, u, K) g, p, q = dmp_inner_gcd(f, h, u, K) while True: d = dmp_diff(p, 1, u, K) h = dmp_sub(q, d, u, K) if dmp_zero_p(h, u): result.append((p, i)) break g, p, q = dmp_inner_gcd(p, h, u, K) if all or dmp_degree(g, u) > 0: result.append((g, i)) i += 1 return coeff, result
def dmp_sqf_list(f, u, K, all=False): """ Return square-free decomposition of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dmp_sqf_list >>> f = ZZ.map([[1], [2, 0], [1, 0, 0], [], [], []]) >>> dmp_sqf_list(f, 1, ZZ) (1, [([[1], [1, 0]], 2), ([[1], []], 3)]) >>> dmp_sqf_list(f, 1, ZZ, all=True) (1, [([[1]], 1), ([[1], [1, 0]], 2), ([[1], []], 3)]) """ if not u: return dup_sqf_list(f, K, all=all) if not K.has_CharacteristicZero: return dmp_gf_sqf_list(f, u, K, all=all) if K.has_Field or not K.is_Exact: coeff = dmp_ground_LC(f, u, K) f = dmp_ground_monic(f, u, K) else: coeff, f = dmp_ground_primitive(f, u, K) if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) coeff = -coeff if dmp_degree(f, u) <= 0: return coeff, [] result, i = [], 1 h = dmp_diff(f, 1, u, K) g, p, q = dmp_inner_gcd(f, h, u, K) while True: d = dmp_diff(p, 1, u, K) h = dmp_sub(q, d, u, K) if dmp_zero_p(h, u): result.append((p, i)) break g, p, q = dmp_inner_gcd(p, h, u, K) if all or dmp_degree(g, u) > 0: result.append((g, i)) i += 1 return coeff, result
def dmp_sqf_list(f, u, K, all=False): """ Return square-free decomposition of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = x**5 + 2*x**4*y + x**3*y**2 >>> R.dmp_sqf_list(f) (1, [(x + y, 2), (x, 3)]) >>> R.dmp_sqf_list(f, all=True) (1, [(1, 1), (x + y, 2), (x, 3)]) """ if not u: return dup_sqf_list(f, K, all=all) if K.is_FiniteField: return dmp_gf_sqf_list(f, u, K, all=all) if K.has_Field: coeff = dmp_ground_LC(f, u, K) f = dmp_ground_monic(f, u, K) else: coeff, f = dmp_ground_primitive(f, u, K) if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) coeff = -coeff if dmp_degree(f, u) <= 0: return coeff, [] result, i = [], 1 h = dmp_diff(f, 1, u, K) g, p, q = dmp_inner_gcd(f, h, u, K) while True: d = dmp_diff(p, 1, u, K) h = dmp_sub(q, d, u, K) if dmp_zero_p(h, u): result.append((p, i)) break g, p, q = dmp_inner_gcd(p, h, u, K) if all or dmp_degree(g, u) > 0: result.append((g, i)) i += 1 return coeff, result
def dmp_sqf_list(f, u, K, all=False): """ Return square-free decomposition of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = x**5 + 2*x**4*y + x**3*y**2 >>> R.dmp_sqf_list(f) (1, [(x + y, 2), (x, 3)]) >>> R.dmp_sqf_list(f, all=True) (1, [(1, 1), (x + y, 2), (x, 3)]) """ if not u: return dup_sqf_list(f, K, all=all) if K.is_FiniteField: return dmp_gf_sqf_list(f, u, K, all=all) if K.is_Field: coeff = dmp_ground_LC(f, u, K) f = dmp_ground_monic(f, u, K) else: coeff, f = dmp_ground_primitive(f, u, K) if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) coeff = -coeff if dmp_degree(f, u) <= 0: return coeff, [] result, i = [], 1 h = dmp_diff(f, 1, u, K) g, p, q = dmp_inner_gcd(f, h, u, K) while True: d = dmp_diff(p, 1, u, K) h = dmp_sub(q, d, u, K) if dmp_zero_p(h, u): result.append((p, i)) break g, p, q = dmp_inner_gcd(p, h, u, K) if all or dmp_degree(g, u) > 0: result.append((g, i)) i += 1 return coeff, result
def dmp_ext_factor(f, u, K): """Factor multivariate polynomials over algebraic number fields. """ if not u: return dup_ext_factor(f, K) lc = dmp_ground_LC(f, u, K) f = dmp_ground_monic(f, u, K) if all(d <= 0 for d in dmp_degree_list(f, u)): return lc, [] f, F = dmp_sqf_part(f, u, K), f s, g, r = dmp_sqf_norm(f, u, K) factors = dmp_factor_list_include(r, u, K.dom) if len(factors) == 1: coeff, factors = lc, [f] else: H = dmp_raise([K.one, s * K.unit], u, 0, K) for i, (factor, _) in enumerate(factors): h = dmp_convert(factor, u, K.dom, K) h, _, g = dmp_inner_gcd(h, g, u, K) h = dmp_compose(h, H, u, K) factors[i] = h return lc, dmp_trial_division(F, factors, u, K)
def dmp_ext_factor(f, u, K): """Factor multivariate polynomials over algebraic number fields. """ if not u: return dup_ext_factor(f, K) lc = dmp_ground_LC(f, u, K) f = dmp_ground_monic(f, u, K) if all([ d <= 0 for d in dmp_degree_list(f, u) ]): return lc, [] f, F = dmp_sqf_part(f, u, K), f s, g, r = dmp_sqf_norm(f, u, K) factors = dmp_factor_list_include(r, u, K.dom) if len(factors) == 1: coeff, factors = lc, [f] else: H = dmp_raise([K.one, s*K.unit], u, 0, K) for i, (factor, _) in enumerate(factors): h = dmp_convert(factor, u, K.dom, K) h, _, g = dmp_inner_gcd(h, g, u, K) h = dmp_compose(h, H, u, K) factors[i] = h return lc, dmp_trial_division(F, factors, u, K)
def test_dmp_gcd(): assert dmp_zz_heu_gcd([[]], [[]], 1, ZZ) == ([[]], [[]], [[]]) assert dmp_rr_prs_gcd([[]], [[]], 1, ZZ) == ([[]], [[]], [[]]) assert dmp_zz_heu_gcd([[2]], [[]], 1, ZZ) == ([[2]], [[1]], [[]]) assert dmp_rr_prs_gcd([[2]], [[]], 1, ZZ) == ([[2]], [[1]], [[]]) assert dmp_zz_heu_gcd([[-2]], [[]], 1, ZZ) == ([[2]], [[-1]], [[]]) assert dmp_rr_prs_gcd([[-2]], [[]], 1, ZZ) == ([[2]], [[-1]], [[]]) assert dmp_zz_heu_gcd([[]], [[-2]], 1, ZZ) == ([[2]], [[]], [[-1]]) assert dmp_rr_prs_gcd([[]], [[-2]], 1, ZZ) == ([[2]], [[]], [[-1]]) assert dmp_zz_heu_gcd([[]], [[2], [4]], 1, ZZ) == ([[2], [4]], [[]], [[1]]) assert dmp_rr_prs_gcd([[]], [[2], [4]], 1, ZZ) == ([[2], [4]], [[]], [[1]]) assert dmp_zz_heu_gcd([[2], [4]], [[]], 1, ZZ) == ([[2], [4]], [[1]], [[]]) assert dmp_rr_prs_gcd([[2], [4]], [[]], 1, ZZ) == ([[2], [4]], [[1]], [[]]) assert dmp_zz_heu_gcd([[2]], [[2]], 1, ZZ) == ([[2]], [[1]], [[1]]) assert dmp_rr_prs_gcd([[2]], [[2]], 1, ZZ) == ([[2]], [[1]], [[1]]) assert dmp_zz_heu_gcd([[-2]], [[2]], 1, ZZ) == ([[2]], [[-1]], [[1]]) assert dmp_rr_prs_gcd([[-2]], [[2]], 1, ZZ) == ([[2]], [[-1]], [[1]]) assert dmp_zz_heu_gcd([[2]], [[-2]], 1, ZZ) == ([[2]], [[1]], [[-1]]) assert dmp_rr_prs_gcd([[2]], [[-2]], 1, ZZ) == ([[2]], [[1]], [[-1]]) assert dmp_zz_heu_gcd([[-2]], [[-2]], 1, ZZ) == ([[2]], [[-1]], [[-1]]) assert dmp_rr_prs_gcd([[-2]], [[-2]], 1, ZZ) == ([[2]], [[-1]], [[-1]]) assert dmp_zz_heu_gcd([[1], [2], [1]], [[1]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[1]]) assert dmp_rr_prs_gcd([[1], [2], [1]], [[1]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[1]]) assert dmp_zz_heu_gcd([[1], [2], [1]], [[2]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[2]]) assert dmp_rr_prs_gcd([[1], [2], [1]], [[2]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[2]]) assert dmp_zz_heu_gcd([[2], [4], [2]], [[2]], 1, ZZ) == ([[2]], [[1], [2], [1]], [[1]]) assert dmp_rr_prs_gcd([[2], [4], [2]], [[2]], 1, ZZ) == ([[2]], [[1], [2], [1]], [[1]]) assert dmp_zz_heu_gcd([[2]], [[2], [4], [2]], 1, ZZ) == ([[2]], [[1]], [[1], [2], [1]]) assert dmp_rr_prs_gcd([[2]], [[2], [4], [2]], 1, ZZ) == ([[2]], [[1]], [[1], [2], [1]]) assert dmp_zz_heu_gcd([[2], [4], [2]], [[1], [1]], 1, ZZ) == ([[1], [1]], [[2], [2]], [[1]]) assert dmp_rr_prs_gcd([[2], [4], [2]], [[1], [1]], 1, ZZ) == ([[1], [1]], [[2], [2]], [[1]]) assert dmp_zz_heu_gcd([[1], [1]], [[2], [4], [2]], 1, ZZ) == ([[1], [1]], [[1]], [[2], [2]]) assert dmp_rr_prs_gcd([[1], [1]], [[2], [4], [2]], 1, ZZ) == ([[1], [1]], [[1]], [[2], [2]]) assert dmp_zz_heu_gcd([[[[1, 2, 1]]]], [[[[2, 2]]]], 3, ZZ) == ([[[[1, 1]]]], [[[[1, 1]]]], [[[[2]]]]) assert dmp_rr_prs_gcd([[[[1, 2, 1]]]], [[[[2, 2]]]], 3, ZZ) == ([[[[1, 1]]]], [[[[1, 1]]]], [[[[2]]]]) f, g = [[[[1, 2, 1], [1, 1], []]]], [[[[1, 2, 1]]]] h, cff, cfg = [[[[1, 1]]]], [[[[1, 1], [1], []]]], [[[[1, 1]]]] assert dmp_zz_heu_gcd(f, g, 3, ZZ) == (h, cff, cfg) assert dmp_rr_prs_gcd(f, g, 3, ZZ) == (h, cff, cfg) assert dmp_zz_heu_gcd(g, f, 3, ZZ) == (h, cfg, cff) assert dmp_rr_prs_gcd(g, f, 3, ZZ) == (h, cfg, cff) f, g, h = dmp_fateman_poly_F_1(2, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g H, cff, cfg = dmp_rr_prs_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g f, g, h = dmp_fateman_poly_F_1(4, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 4, ZZ) assert H == h and dmp_mul(H, cff, 4, ZZ) == f \ and dmp_mul(H, cfg, 4, ZZ) == g f, g, h = dmp_fateman_poly_F_1(6, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 6, ZZ) assert H == h and dmp_mul(H, cff, 6, ZZ) == f \ and dmp_mul(H, cfg, 6, ZZ) == g f, g, h = dmp_fateman_poly_F_1(8, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 8, ZZ) assert H == h and dmp_mul(H, cff, 8, ZZ) == f \ and dmp_mul(H, cfg, 8, ZZ) == g f, g, h = dmp_fateman_poly_F_2(2, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g H, cff, cfg = dmp_rr_prs_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g f, g, h = dmp_fateman_poly_F_3(2, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g H, cff, cfg = dmp_rr_prs_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g f, g, h = dmp_fateman_poly_F_3(4, ZZ) H, cff, cfg = dmp_inner_gcd(f, g, 4, ZZ) assert H == h and dmp_mul(H, cff, 4, ZZ) == f \ and dmp_mul(H, cfg, 4, ZZ) == g f = [[QQ(1, 2)], [QQ(1)], [QQ(1, 2)]] g = [[QQ(1, 2)], [QQ(1, 2)]] h = [[QQ(1)], [QQ(1)]] assert dmp_qq_heu_gcd(f, g, 1, QQ) == (h, g, [[QQ(1, 2)]]) assert dmp_ff_prs_gcd(f, g, 1, QQ) == (h, g, [[QQ(1, 2)]]) f = [[RR(2.1), RR(-2.2), RR(2.1)], []] g = [[RR(1.0)], [], [], []] assert dmp_ff_prs_gcd(f, g, 1, RR) == \ ([[RR(1.0)], []], [[RR(2.1), RR(-2.2), RR(2.1)]], [[RR(1.0)], [], []])
def cofactors(f, g): """Returns GCD of `f` and `g` and their cofactors. """ lev, dom, per, F, G = f.unify(g) h, cff, cfg = dmp_inner_gcd(F, G, lev, dom) return per(h), per(cff), per(cfg)
def test_dmp_gcd(): assert dmp_zz_heu_gcd([[]], [[]], 1, ZZ) == ([[]], [[]], [[]]) assert dmp_rr_prs_gcd([[]], [[]], 1, ZZ) == ([[]], [[]], [[]]) assert dmp_zz_heu_gcd([[2]], [[]], 1, ZZ) == ([[2]], [[1]], [[]]) assert dmp_rr_prs_gcd([[2]], [[]], 1, ZZ) == ([[2]], [[1]], [[]]) assert dmp_zz_heu_gcd([[-2]], [[]], 1, ZZ) == ([[2]], [[-1]], [[]]) assert dmp_rr_prs_gcd([[-2]], [[]], 1, ZZ) == ([[2]], [[-1]], [[]]) assert dmp_zz_heu_gcd([[]], [[-2]], 1, ZZ) == ([[2]], [[]], [[-1]]) assert dmp_rr_prs_gcd([[]], [[-2]], 1, ZZ) == ([[2]], [[]], [[-1]]) assert dmp_zz_heu_gcd([[]], [[2],[4]], 1, ZZ) == ([[2],[4]], [[]], [[1]]) assert dmp_rr_prs_gcd([[]], [[2],[4]], 1, ZZ) == ([[2],[4]], [[]], [[1]]) assert dmp_zz_heu_gcd([[2],[4]], [[]], 1, ZZ) == ([[2],[4]], [[1]], [[]]) assert dmp_rr_prs_gcd([[2],[4]], [[]], 1, ZZ) == ([[2],[4]], [[1]], [[]]) assert dmp_zz_heu_gcd([[2]], [[2]], 1, ZZ) == ([[2]], [[1]], [[1]]) assert dmp_rr_prs_gcd([[2]], [[2]], 1, ZZ) == ([[2]], [[1]], [[1]]) assert dmp_zz_heu_gcd([[-2]], [[2]], 1, ZZ) == ([[2]], [[-1]], [[1]]) assert dmp_rr_prs_gcd([[-2]], [[2]], 1, ZZ) == ([[2]], [[-1]], [[1]]) assert dmp_zz_heu_gcd([[2]], [[-2]], 1, ZZ) == ([[2]], [[1]], [[-1]]) assert dmp_rr_prs_gcd([[2]], [[-2]], 1, ZZ) == ([[2]], [[1]], [[-1]]) assert dmp_zz_heu_gcd([[-2]], [[-2]], 1, ZZ) == ([[2]], [[-1]], [[-1]]) assert dmp_rr_prs_gcd([[-2]], [[-2]], 1, ZZ) == ([[2]], [[-1]], [[-1]]) assert dmp_zz_heu_gcd([[1],[2],[1]], [[1]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[1]]) assert dmp_rr_prs_gcd([[1],[2],[1]], [[1]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[1]]) assert dmp_zz_heu_gcd([[1],[2],[1]], [[2]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[2]]) assert dmp_rr_prs_gcd([[1],[2],[1]], [[2]], 1, ZZ) == ([[1]], [[1], [2], [1]], [[2]]) assert dmp_zz_heu_gcd([[2],[4],[2]], [[2]], 1, ZZ) == ([[2]], [[1], [2], [1]], [[1]]) assert dmp_rr_prs_gcd([[2],[4],[2]], [[2]], 1, ZZ) == ([[2]], [[1], [2], [1]], [[1]]) assert dmp_zz_heu_gcd([[2]], [[2],[4],[2]], 1, ZZ) == ([[2]], [[1]], [[1], [2], [1]]) assert dmp_rr_prs_gcd([[2]], [[2],[4],[2]], 1, ZZ) == ([[2]], [[1]], [[1], [2], [1]]) assert dmp_zz_heu_gcd([[2],[4],[2]], [[1],[1]], 1, ZZ) == ([[1], [1]], [[2], [2]], [[1]]) assert dmp_rr_prs_gcd([[2],[4],[2]], [[1],[1]], 1, ZZ) == ([[1], [1]], [[2], [2]], [[1]]) assert dmp_zz_heu_gcd([[1],[1]], [[2],[4],[2]], 1, ZZ) == ([[1], [1]], [[1]], [[2], [2]]) assert dmp_rr_prs_gcd([[1],[1]], [[2],[4],[2]], 1, ZZ) == ([[1], [1]], [[1]], [[2], [2]]) assert dmp_zz_heu_gcd([[[[1,2,1]]]], [[[[2,2]]]], 3, ZZ) == ([[[[1,1]]]], [[[[1,1]]]], [[[[2]]]]) assert dmp_rr_prs_gcd([[[[1,2,1]]]], [[[[2,2]]]], 3, ZZ) == ([[[[1,1]]]], [[[[1,1]]]], [[[[2]]]]) f, g = [[[[1,2,1],[1,1],[]]]], [[[[1,2,1]]]] h, cff, cfg = [[[[1,1]]]], [[[[1,1],[1],[]]]], [[[[1,1]]]] assert dmp_zz_heu_gcd(f, g, 3, ZZ) == (h, cff, cfg) assert dmp_rr_prs_gcd(f, g, 3, ZZ) == (h, cff, cfg) assert dmp_zz_heu_gcd(g, f, 3, ZZ) == (h, cfg, cff) assert dmp_rr_prs_gcd(g, f, 3, ZZ) == (h, cfg, cff) f, g, h = dmp_fateman_poly_F_1(2, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g H, cff, cfg = dmp_rr_prs_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g f, g, h = dmp_fateman_poly_F_1(4, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 4, ZZ) assert H == h and dmp_mul(H, cff, 4, ZZ) == f \ and dmp_mul(H, cfg, 4, ZZ) == g f, g, h = dmp_fateman_poly_F_1(6, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 6, ZZ) assert H == h and dmp_mul(H, cff, 6, ZZ) == f \ and dmp_mul(H, cfg, 6, ZZ) == g f, g, h = dmp_fateman_poly_F_1(8, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 8, ZZ) assert H == h and dmp_mul(H, cff, 8, ZZ) == f \ and dmp_mul(H, cfg, 8, ZZ) == g f, g, h = dmp_fateman_poly_F_2(2, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g H, cff, cfg = dmp_rr_prs_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g f, g, h = dmp_fateman_poly_F_3(2, ZZ) H, cff, cfg = dmp_zz_heu_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g H, cff, cfg = dmp_rr_prs_gcd(f, g, 2, ZZ) assert H == h and dmp_mul(H, cff, 2, ZZ) == f \ and dmp_mul(H, cfg, 2, ZZ) == g f, g, h = dmp_fateman_poly_F_3(4, ZZ) H, cff, cfg = dmp_inner_gcd(f, g, 4, ZZ) assert H == h and dmp_mul(H, cff, 4, ZZ) == f \ and dmp_mul(H, cfg, 4, ZZ) == g f = [[QQ(1,2)],[QQ(1)],[QQ(1,2)]] g = [[QQ(1,2)],[QQ(1,2)]] h = [[QQ(1)],[QQ(1)]] assert dmp_qq_heu_gcd(f, g, 1, QQ) == (h, g, [[QQ(1,2)]]) assert dmp_ff_prs_gcd(f, g, 1, QQ) == (h, g, [[QQ(1,2)]])
def cofactors(f, g): """Returns GCD of `f` and `g` and their cofactors. """ lev, dom, per, F, G = f.unify(g) h, cff, cfg = dmp_inner_gcd(F, G, lev, dom) return per(h), per(cff), per(cfg)