def test_dmp_ground_monic(): assert dmp_ground_monic([[3], [6], [9]], 1, ZZ) == [[1], [2], [3]] raises(ExactQuotientFailed, "dmp_ground_monic([[3],[4],[5]], 1, ZZ)") assert dmp_ground_monic([[]], 1, QQ) == [[]] assert dmp_ground_monic([[QQ(1)]], 1, QQ) == [[QQ(1)]] assert dmp_ground_monic([[QQ(7)], [QQ(1)], [QQ(21)]], 1, QQ) == [[QQ(1)], [QQ(1, 7)], [QQ(3)]]
def test_dmp_ground_monic(): assert dmp_ground_monic([[3], [6], [9]], 1, ZZ) == [[1], [2], [3]] raises(ExactQuotientFailed, lambda: dmp_ground_monic([[3], [4], [5]], 1, ZZ)) assert dmp_ground_monic([[]], 1, QQ) == [[]] assert dmp_ground_monic([[QQ(1)]], 1, QQ) == [[QQ(1)]] assert dmp_ground_monic([[QQ(7)], [QQ(1)], [QQ(21)]], 1, QQ) == [[QQ(1)], [QQ(1, 7)], [QQ(3)]]
def _dmp_ff_trivial_gcd(f, g, u, K): """Handle trivial cases in GCD algorithm over a field. """ zero_f = dmp_zero_p(f, u) zero_g = dmp_zero_p(g, u) if zero_f and zero_g: return tuple(dmp_zeros(3, u, K)) elif zero_f: return (dmp_ground_monic(g, u, K), dmp_zero(u), dmp_ground(dmp_ground_LC(g, u, K), u)) elif zero_g: return (dmp_ground_monic(f, u, K), dmp_ground(dmp_ground_LC(f, u, K), u), dmp_zero(u)) elif query("USE_SIMPLIFY_GCD"): return _dmp_simplify_gcd(f, g, u, K) else: return None
def dmp_sqf_part(f, u, K): """ Returns square-free part of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dmp_sqf_part(x**3 + 2*x**2*y + x*y**2) x**2 + x*y """ if not u: return dup_sqf_part(f, K) if K.is_FiniteField: return dmp_gf_sqf_part(f, u, K) if dmp_zero_p(f, u): return f if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) gcd = dmp_gcd(f, dmp_diff(f, 1, u, K), u, K) sqf = dmp_quo(f, gcd, u, K) if K.is_Field: return dmp_ground_monic(sqf, u, K) else: return dmp_ground_primitive(sqf, u, K)[1]
def dmp_sqf_part(f, u, K): """ Returns square-free part of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dmp_sqf_part >>> f = ZZ.map([[1], [2, 0], [1, 0, 0], []]) >>> dmp_sqf_part(f, 1, ZZ) [[1], [1, 0], []] """ if not u: return dup_sqf_part(f, K) if not K.has_CharacteristicZero: return dmp_gf_sqf_part(f, u, K) if dmp_zero_p(f, u): return f if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) gcd = dmp_gcd(f, dmp_diff(f, 1, u, K), u, K) sqf = dmp_quo(f, gcd, u, K) if K.has_Field or not K.is_Exact: return dmp_ground_monic(sqf, u, K) else: return dmp_ground_primitive(sqf, u, K)[1]
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_sqf_part(f, u, K): """ Returns square-free part of a polynomial in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dmp_sqf_part(x**3 + 2*x**2*y + x*y**2) x**2 + x*y """ if not u: return dup_sqf_part(f, K) if K.is_FiniteField: return dmp_gf_sqf_part(f, u, K) if dmp_zero_p(f, u): return f if K.is_negative(dmp_ground_LC(f, u, K)): f = dmp_neg(f, u, K) gcd = dmp_gcd(f, dmp_diff(f, 1, u, K), u, K) sqf = dmp_quo(f, gcd, u, K) if K.has_Field: return dmp_ground_monic(sqf, u, K) else: return dmp_ground_primitive(sqf, u, K)[1]
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_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_ff_trivial_gcd(f, g, u, K): """Handle trivial cases in GCD algorithm over a field. """ zero_f = dmp_zero_p(f, u) zero_g = dmp_zero_p(g, u) if zero_f and zero_g: return tuple(dmp_zeros(3, u, K)) elif zero_f: return (dmp_ground_monic(g, u, K), dmp_zero(u), dmp_ground(dmp_ground_LC(g, u, K), u)) elif zero_g: return (dmp_ground_monic(f, u, K), dmp_ground(dmp_ground_LC(f, u, K), u), dmp_zero(u)) elif query('USE_SIMPLIFY_GCD'): return _dmp_simplify_gcd(f, g, u, K) else: return None
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_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_qq_heu_gcd(f, g, u, 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 sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dmp_qq_heu_gcd >>> f = [[QQ(1,4)], [QQ(1), QQ(0)], [QQ(1), QQ(0), QQ(0)]] >>> g = [[QQ(1,2)], [QQ(1), QQ(0)], []] >>> dmp_qq_heu_gcd(f, g, 1, QQ) ([[1/1], [2/1, 0/1]], [[1/4], [1/2, 0/1]], [[1/2], []]) """ result = _dmp_ff_trivial_gcd(f, g, u, K0) if result is not None: return result K1 = K0.get_ring() cf, f = dmp_clear_denoms(f, u, K0, K1) cg, g = dmp_clear_denoms(g, u, K0, K1) f = dmp_convert(f, u, K0, K1) g = dmp_convert(g, u, K0, K1) h, cff, cfg = dmp_zz_heu_gcd(f, g, u, K1) h = dmp_convert(h, u, K1, K0) c = dmp_ground_LC(h, u, K0) h = dmp_ground_monic(h, u, K0) cff = dmp_convert(cff, u, K1, K0) cfg = dmp_convert(cfg, u, K1, K0) cff = dmp_mul_ground(cff, K0.quo(c, cf), u, K0) cfg = dmp_mul_ground(cfg, K0.quo(c, cg), u, K0) return h, cff, cfg
def dmp_qq_heu_gcd(f, g, u, 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 sympy.polys import ring, QQ >>> R, x,y, = ring("x,y", QQ) >>> f = QQ(1,4)*x**2 + x*y + y**2 >>> g = QQ(1,2)*x**2 + x*y >>> R.dmp_qq_heu_gcd(f, g) (x + 2*y, 1/4*x + 1/2*y, 1/2*x) """ result = _dmp_ff_trivial_gcd(f, g, u, K0) if result is not None: return result K1 = K0.get_ring() cf, f = dmp_clear_denoms(f, u, K0, K1) cg, g = dmp_clear_denoms(g, u, K0, K1) f = dmp_convert(f, u, K0, K1) g = dmp_convert(g, u, K0, K1) h, cff, cfg = dmp_zz_heu_gcd(f, g, u, K1) h = dmp_convert(h, u, K1, K0) c = dmp_ground_LC(h, u, K0) h = dmp_ground_monic(h, u, K0) cff = dmp_convert(cff, u, K1, K0) cfg = dmp_convert(cfg, u, K1, K0) cff = dmp_mul_ground(cff, K0.quo(c, cf), u, K0) cfg = dmp_mul_ground(cfg, K0.quo(c, cg), u, K0) return h, cff, cfg
def dmp_ff_lcm(f, g, u, K): """ Computes polynomial LCM over a field in ``K[X]``. **Examples** >>> from sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dmp_ff_lcm >>> f = [[QQ(1,4)], [QQ(1), QQ(0)], [QQ(1), QQ(0), QQ(0)]] >>> g = [[QQ(1,2)], [QQ(1), QQ(0)], []] >>> dmp_ff_lcm(f, g, 1, QQ) [[1/1], [4/1, 0/1], [4/1, 0/1, 0/1], []] """ h = dmp_quo(dmp_mul(f, g, u, K), dmp_gcd(f, g, u, K), u, K) return dmp_ground_monic(h, u, K)
def dmp_ff_prs_gcd(f, g, u, K): """ Computes polynomial GCD using subresultants over a field. Returns ``(h, cff, cfg)`` such that ``a = gcd(f, g)``, ``cff = quo(f, h)``, and ``cfg = quo(g, h)``. Examples ======== >>> from sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dmp_ff_prs_gcd >>> f = [[QQ(1,2)], [QQ(1), QQ(0)], [QQ(1,2), QQ(0), QQ(0)]] >>> g = [[QQ(1)], [QQ(1), QQ(0)], []] >>> dmp_ff_prs_gcd(f, g, 1, QQ) ([[1/1], [1/1, 0/1]], [[1/2], [1/2, 0/1]], [[1/1], []]) """ if not u: return dup_ff_prs_gcd(f, g, K) result = _dmp_ff_trivial_gcd(f, g, u, K) if result is not None: return result fc, F = dmp_primitive(f, u, K) gc, G = dmp_primitive(g, u, K) h = dmp_subresultants(F, G, u, K)[-1] c, _, _ = dmp_ff_prs_gcd(fc, gc, u - 1, K) _, h = dmp_primitive(h, u, K) h = dmp_mul_term(h, c, 0, u, K) h = dmp_ground_monic(h, u, K) cff = dmp_quo(f, h, u, K) cfg = dmp_quo(g, h, u, K) return h, cff, cfg
def dmp_ff_prs_gcd(f, g, u, K): """ Computes polynomial GCD using subresultants over a field. Returns ``(h, cff, cfg)`` such that ``a = gcd(f, g)``, ``cff = quo(f, h)``, and ``cfg = quo(g, h)``. Examples ======== >>> from sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dmp_ff_prs_gcd >>> f = [[QQ(1,2)], [QQ(1), QQ(0)], [QQ(1,2), QQ(0), QQ(0)]] >>> g = [[QQ(1)], [QQ(1), QQ(0)], []] >>> dmp_ff_prs_gcd(f, g, 1, QQ) ([[1/1], [1/1, 0/1]], [[1/2], [1/2, 0/1]], [[1/1], []]) """ if not u: return dup_ff_prs_gcd(f, g, K) result = _dmp_ff_trivial_gcd(f, g, u, K) if result is not None: return result fc, F = dmp_primitive(f, u, K) gc, G = dmp_primitive(g, u, K) h = dmp_subresultants(F, G, u, K)[-1] c, _, _ = dmp_ff_prs_gcd(fc, gc, u-1, K) _, h = dmp_primitive(h, u, K) h = dmp_mul_term(h, c, 0, u, K) h = dmp_ground_monic(h, u, K) cff = dmp_quo(f, h, u, K) cfg = dmp_quo(g, h, u, K) return h, cff, cfg
def dmp_ff_prs_gcd(f, g, u, K): """ Computes polynomial GCD using subresultants over a field. Returns ``(h, cff, cfg)`` such that ``a = gcd(f, g)``, ``cff = quo(f, h)``, and ``cfg = quo(g, h)``. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x,y, = ring("x,y", QQ) >>> f = QQ(1,2)*x**2 + x*y + QQ(1,2)*y**2 >>> g = x**2 + x*y >>> R.dmp_ff_prs_gcd(f, g) (x + y, 1/2*x + 1/2*y, x) """ if not u: return dup_ff_prs_gcd(f, g, K) result = _dmp_ff_trivial_gcd(f, g, u, K) if result is not None: return result fc, F = dmp_primitive(f, u, K) gc, G = dmp_primitive(g, u, K) h = dmp_subresultants(F, G, u, K)[-1] c, _, _ = dmp_ff_prs_gcd(fc, gc, u - 1, K) _, h = dmp_primitive(h, u, K) h = dmp_mul_term(h, c, 0, u, K) h = dmp_ground_monic(h, u, K) cff = dmp_quo(f, h, u, K) cfg = dmp_quo(g, h, u, K) return h, cff, cfg
def dmp_ff_lcm(f, g, u, K): """ Computes polynomial LCM over a field in `K[X]`. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x,y, = ring("x,y", QQ) >>> f = QQ(1,4)*x**2 + x*y + y**2 >>> g = QQ(1,2)*x**2 + x*y >>> R.dmp_ff_lcm(f, g) x**3 + 4*x**2*y + 4*x*y**2 """ h = dmp_quo(dmp_mul(f, g, u, K), dmp_gcd(f, g, u, K), u, K) return dmp_ground_monic(h, u, K)
def dmp_ff_lcm(f, g, u, K): """ Computes polynomial LCM over a field in ``K[X]``. **Examples** >>> from sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dmp_ff_lcm >>> f = [[QQ(1,4)], [QQ(1), QQ(0)], [QQ(1), QQ(0), QQ(0)]] >>> g = [[QQ(1,2)], [QQ(1), QQ(0)], []] >>> dmp_ff_lcm(f, g, 1, QQ) [[1/1], [4/1, 0/1], [4/1, 0/1, 0/1], []] """ h = dmp_exquo(dmp_mul(f, g, u, K), dmp_gcd(f, g, u, K), u, K) return dmp_ground_monic(h, u, K)
def monic(f): """Divides all coefficients by `LC(f)`. """ return f.per(dmp_ground_monic(f.rep, f.lev, f.dom))