def dup_factor_list(f, K0): """Factor univariate 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.is_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.dom) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) else: # pragma: no cover raise DomainError('factorization not supported over %s' % K0) if K0.is_Field: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K, K0), k) coeff = K0.convert(coeff, K) coeff = K0.quo(coeff, denom) if K0_inexact: for i, (f, k) in enumerate(factors): max_norm = dup_max_norm(f, K0) f = dup_quo_ground(f, max_norm, K0) f = dup_convert(f, K0, K0_inexact) factors[i] = (f, k) coeff = K0.mul(coeff, K0.pow(max_norm, k)) coeff = K0_inexact.convert(coeff, K0) K0 = K0_inexact if j: factors.insert(0, ([K0.one, K0.zero], j)) return coeff*cont, _sort_factors(factors)
def dup_factor_list(f, K0): """Factor univariate 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.is_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.dom) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) else: # pragma: no cover raise DomainError('factorization not supported over %s' % K0) if K0.is_Field: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K, K0), k) coeff = K0.convert(coeff, K) coeff = K0.quo(coeff, denom) if K0_inexact: for i, (f, k) in enumerate(factors): max_norm = dup_max_norm(f, K0) f = dup_quo_ground(f, max_norm, K0) f = dup_convert(f, K0, K0_inexact) factors[i] = (f, k) coeff = K0.mul(coeff, K0.pow(max_norm, k)) coeff = K0_inexact.convert(coeff, K0) K0 = K0_inexact if j: factors.insert(0, ([K0.one, K0.zero], j)) return coeff*cont, _sort_factors(factors)
def dup_factor_list(f, K0, **args): """Factor polynomials into irreducibles in `K[x]`. """ if not K0.has_CharacteristicZero: # pragma: no cover raise DomainError('only characteristic zero allowed') if 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_ground_to_ring(f, K0, K) f = dup_convert(f, K0, K) else: K = K0 if K.is_ZZ: coeff, factors = dup_zz_factor(f, K, **args) elif K.is_Poly: f, u = dmp_inject(f, 0, K) coeff, factors = dmp_factor_list(f, u, K.dom, **args) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) 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) denom = K0.convert(denom, K) coeff = K0.quo(coeff, denom) if K0_inexact is not None: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K0, K0_inexact), k) coeff = K0_inexact.convert(coeff, K0) if not args.get('include', False): return coeff, factors else: if not factors: return [(dup_strip([coeff]), 1)] else: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, factors[0][1])] + factors[1:]
def dup_factor_list(f, K0, **args): """Factor polynomials into irreducibles in `K[x]`. """ if not K0.has_CharacteristicZero: # pragma: no cover raise DomainError('only characteristic zero allowed') if 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_ground_to_ring(f, K0, K) f = dup_convert(f, K0, K) else: K = K0 if K.is_ZZ: coeff, factors = dup_zz_factor(f, K, **args) elif K.is_Poly: f, u = dmp_inject(f, 0, K) coeff, factors = dmp_factor_list(f, u, K.dom, **args) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) 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) denom = K0.convert(denom, K) coeff = K0.quo(coeff, denom) if K0_inexact is not None: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K0, K0_inexact), k) coeff = K0_inexact.convert(coeff, K0) if not args.get('include', False): return coeff, factors else: if not factors: return [(dup_strip([coeff]), 1)] else: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, factors[0][1])] + factors[1:]
def dup_qq_i_factor(f, K0): """Factor univariate polynomials into irreducibles in `QQ_I[x]`. """ # Factor in QQ<I> K1 = K0.as_AlgebraicField() f = dup_convert(f, K0, K1) coeff, factors = dup_factor_list(f, K1) factors = [(dup_convert(fac, K1, K0), i) for fac, i in factors] coeff = K0.convert(coeff, K1) return coeff, factors
def dup_factor_list(f, K0): """Factor polynomials into irreducibles in `K[x]`. """ j, f = dup_terms_gcd(f, K0) if not K0.has_CharacteristicZero: 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.dom) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) 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) denom = K0.convert(denom, K) coeff = K0.quo(coeff, denom) if K0_inexact is not None: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K0, K0_inexact), k) coeff = K0_inexact.convert(coeff, K0) if j: factors.insert(0, ([K0.one, K0.zero], j)) return coeff, _sort_factors(factors)
def dup_factor_list(f, K0): """Factor polynomials into irreducibles in `K[x]`. """ j, f = dup_terms_gcd(f, K0) if not K0.has_CharacteristicZero: 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.dom) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) 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) denom = K0.convert(denom, K) coeff = K0.quo(coeff, denom) if K0_inexact is not None: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K0, K0_inexact), k) coeff = K0_inexact.convert(coeff, K0) if j: factors.insert(0, ([K0.one, K0.zero], j)) return coeff, _sort_factors(factors)
def dup_gf_sqf_list(f, K, all=False): """Compute square-free decomposition of ``f`` in ``GF(p)[x]``. """ f = dup_convert(f, K, K.dom) coeff, factors = gf_sqf_list(f, K.mod, K.dom, all=all) for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K.dom, K), k) return K.convert(coeff, K.dom), factors
def dup_gf_factor(f, K): """Factor univariate polynomials over finite fields. """ f = dup_convert(f, K, K.dom) coeff, factors = gf_factor(f, K.mod, K.dom) for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K.dom, K), k) return K.convert(coeff, K.dom), factors
def dup_gf_sqf_list(f, K, all=False): """Compute square-free decomposition of ``f`` in ``GF(p)[x]``. """ f = dup_convert(f, K, K.dom) coeff, factors = gf_sqf_list(f, K.mod, K.dom, all=all) for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K.dom, K), k) return K.convert(coeff, K.dom), factors
def dup_gf_factor(f, K): """Factor univariate polynomials over finite fields. """ f = dup_convert(f, K, K.dom) coeff, factors = gf_factor(f, K.mod, K.dom) for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K.dom, K), k) return K.convert(coeff, K.dom), factors
def dup_inner_gcd(f, g, K): """ Computes polynomial GCD and cofactors of `f` and `g` in `K[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, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_inner_gcd(x**2 - 1, x**2 - 3*x + 2) (x - 1, x + 1, x - 2) """ if not K.is_Exact: try: exact = K.get_exact() except DomainError: return [K.one], f, g f = dup_convert(f, K, exact) g = dup_convert(g, K, exact) h, cff, cfg = dup_inner_gcd(f, g, exact) h = dup_convert(h, exact, K) cff = dup_convert(cff, exact, K) cfg = dup_convert(cfg, exact, K) return h, cff, cfg elif K.has_Field: if K.is_QQ and query('USE_HEU_GCD'): try: return dup_qq_heu_gcd(f, g, K) except HeuristicGCDFailed: pass return dup_ff_prs_gcd(f, g, K) else: if K.is_ZZ and query('USE_HEU_GCD'): try: return dup_zz_heu_gcd(f, g, K) except HeuristicGCDFailed: pass return dup_rr_prs_gcd(f, g, K)
def dup_inner_gcd(f, g, K): """ Computes polynomial GCD and cofactors of `f` and `g` in `K[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, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_inner_gcd(x**2 - 1, x**2 - 3*x + 2) (x - 1, x + 1, x - 2) """ if not K.is_Exact: try: exact = K.get_exact() except DomainError: return [K.one], f, g f = dup_convert(f, K, exact) g = dup_convert(g, K, exact) h, cff, cfg = dup_inner_gcd(f, g, exact) h = dup_convert(h, exact, K) cff = dup_convert(cff, exact, K) cfg = dup_convert(cfg, exact, K) return h, cff, cfg elif K.has_Field: if K.is_QQ and query('USE_HEU_GCD'): try: return dup_qq_heu_gcd(f, g, K) except HeuristicGCDFailed: pass return dup_ff_prs_gcd(f, g, K) else: if K.is_ZZ and query('USE_HEU_GCD'): try: return dup_zz_heu_gcd(f, g, K) except HeuristicGCDFailed: pass return dup_rr_prs_gcd(f, g, K)
def dup_ext_factor(f, K): """Factor univariate polynomials over algebraic number fields. """ n, lc = dup_degree(f), dup_LC(f, K) f = dup_monic(f, K) if n <= 0: return lc, [] if n == 1: return lc, [(f, 1)] f, F = dup_sqf_part(f, K), f s, g, r = dup_sqf_norm(f, K) factors = dup_factor_list_include(r, K.dom) if len(factors) == 1: return lc, [(f, n // dup_degree(f))] H = s * K.unit for i, (factor, _) in enumerate(factors): h = dup_convert(factor, K.dom, K) h, _, g = dup_inner_gcd(h, g, K) h = dup_shift(h, H, K) factors[i] = h factors = dup_trial_division(F, factors, K) return lc, factors
def test_dup_convert(): K0, K1 = ZZ['x'], ZZ f = [K0(1), K0(2), K0(0), K0(3)] assert dup_convert(f, K0, K1) == \ [ZZ(1), ZZ(2), ZZ(0), ZZ(3)]
def dup_ext_factor(f, K): """Factor univariate polynomials over algebraic number fields. """ n, lc = dup_degree(f), dup_LC(f, K) f = dup_monic(f, K) if n <= 0: return lc, [] if n == 1: return lc, [(f, 1)] f, F = dup_sqf_part(f, K), f s, g, r = dup_sqf_norm(f, K) factors = dup_factor_list_include(r, K.dom) if len(factors) == 1: return lc, [(f, n//dup_degree(f))] H = s*K.unit for i, (factor, _) in enumerate(factors): h = dup_convert(factor, K.dom, K) h, _, g = dup_inner_gcd(h, g, K) h = dup_shift(h, H, K) factors[i] = h factors = dup_trial_division(F, factors, K) return lc, factors
def dup_clear_denoms(f, K0, K1=None, convert=False): """ Clear denominators, i.e. transform ``K_0`` to ``K_1``. Examples ======== >>> from sympy.polys.domains import QQ, ZZ >>> from sympy.polys.densetools import dup_clear_denoms >>> f = [QQ(1,2), QQ(1,3)] >>> dup_clear_denoms(f, QQ, convert=False) (6, [3/1, 2/1]) >>> f = [QQ(1,2), QQ(1,3)] >>> dup_clear_denoms(f, QQ, convert=True) (6, [3, 2]) """ if K1 is None: K1 = K0.get_ring() common = K1.one for c in f: common = K1.lcm(common, K0.denom(c)) if not K1.is_one(common): f = dup_mul_ground(f, common, K0) if not convert: return common, f else: return common, dup_convert(f, K0, K1)
def test_dup_convert(): K0, K1 = ZZ['x'], ZZ f = [K0(1), K0(2), K0(0), K0(3)] assert dup_convert(f, K0, K1) == \ [ZZ(1), ZZ(2), ZZ(0), ZZ(3)]
def test_dup_convert(): K0, K1 = ZZ['x'], ZZ f = [DMP([1], ZZ),DMP([2], ZZ),DMP([], ZZ),DMP([3], ZZ)] assert dup_convert(f, K0, K1) == \ [ZZ(1),ZZ(2),ZZ(0),ZZ(3)]
def dup_clear_denoms(f, K0, K1=None, convert=False): """ Clear denominators, i.e. transform ``K_0`` to ``K_1``. Examples ======== >>> from sympy.polys.domains import QQ, ZZ >>> from sympy.polys.densetools import dup_clear_denoms >>> f = [QQ(1,2), QQ(1,3)] >>> dup_clear_denoms(f, QQ, convert=False) (6, [3/1, 2/1]) >>> f = [QQ(1,2), QQ(1,3)] >>> dup_clear_denoms(f, QQ, convert=True) (6, [3, 2]) """ if K1 is None: K1 = K0.get_ring() common = K1.one for c in f: common = K1.lcm(common, K0.denom(c)) if not K1.is_one(common): f = dup_mul_ground(f, common, K0) if not convert: return common, f else: return common, dup_convert(f, K0, K1)
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 sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dup_qq_heu_gcd >>> f = [QQ(1,2), QQ(7,4), QQ(3,2)] >>> g = [QQ(1,2), QQ(1), QQ(0)] >>> dup_qq_heu_gcd(f, g, QQ) ([1/1, 2/1], [1/2, 3/4], [1/2, 0/1]) """ 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_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 sympy.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_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 sympy.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_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 sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dup_qq_heu_gcd >>> f = [QQ(1,2), QQ(7,4), QQ(3,2)] >>> g = [QQ(1,2), QQ(1), QQ(0)] >>> dup_qq_heu_gcd(f, g, QQ) ([1/1, 2/1], [1/2, 3/4], [1/2, 0/1]) """ 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_zz_i_factor(f, K0): """Factor univariate polynomials into irreducibles in `ZZ_I[x]`. """ # First factor in QQ_I K1 = K0.get_field() f = dup_convert(f, K0, K1) coeff, factors = dup_qq_i_factor(f, K1) new_factors = [] for fac, i in factors: # Extract content fac_denom, fac_num = dup_clear_denoms(fac, K1) fac_num_ZZ_I = dup_convert(fac_num, K1, K0) content, fac_prim = dmp_ground_primitive(fac_num_ZZ_I, 0, K1) coeff = (coeff * content**i) // fac_denom**i new_factors.append((fac_prim, i)) factors = new_factors coeff = K0.convert(coeff, K1) return coeff, factors
def unify(f, g): """Unify representations of two algebraic numbers. """ if not isinstance(g, ANP) or f.mod != g.mod: raise UnificationFailed("can't unify %s with %s" % (f, g)) if f.dom == g.dom: return f.dom, f.per, f.rep, g.rep, f.mod else: dom = f.dom.unify(g.dom) F = dup_convert(f.rep, f.dom, dom) G = dup_convert(g.rep, g.dom, dom) if dom != f.dom and dom != g.dom: mod = dup_convert(f.mod, f.dom, dom) else: if dom == f.dom: H = f.mod else: H = g.mod per = lambda rep: ANP(rep, mod, dom) return dom, per, F, G, mod
def unify(f, g): """Unify representations of two algebraic numbers. """ if not isinstance(g, ANP) or f.mod != g.mod: raise UnificationFailed("can't unify %s with %s" % (f, g)) if f.dom == g.dom: return f.dom, f.per, f.rep, g.rep, f.mod else: dom = f.dom.unify(g.dom) F = dup_convert(f.rep, f.dom, dom) G = dup_convert(g.rep, g.dom, dom) if dom != f.dom and dom != g.dom: mod = dup_convert(f.mod, f.dom, dom) else: if dom == f.dom: H = f.mod else: H = g.mod per = lambda rep: ANP(rep, mod, dom) return dom, per, F, G, mod
def dup_clear_denoms(f, K0, K1=None, convert=False): """ Clear denominators, i.e. transform ``K_0`` to ``K_1``. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x = ring("x", QQ) >>> f = QQ(1,2)*x + QQ(1,3) >>> R.dup_clear_denoms(f, convert=False) (6, 3*x + 2) >>> R.dup_clear_denoms(f, convert=True) (6, 3*x + 2) """ if K1 is None: if K0.has_assoc_Ring: K1 = K0.get_ring() else: K1 = K0 common = K1.one for c in f: common = K1.lcm(common, K0.denom(c)) if not K1.is_one(common): f = dup_mul_ground(f, common, K0) if not convert: return common, f else: return common, dup_convert(f, K0, K1)
def dup_clear_denoms(f, K0, K1=None, convert=False): """ Clear denominators, i.e. transform ``K_0`` to ``K_1``. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x = ring("x", QQ) >>> f = QQ(1,2)*x + QQ(1,3) >>> R.dup_clear_denoms(f, convert=False) (6, 3*x + 2) >>> R.dup_clear_denoms(f, convert=True) (6, 3*x + 2) """ if K1 is None: if K0.has_assoc_Ring: K1 = K0.get_ring() else: K1 = K0 common = K1.one for c in f: common = K1.lcm(common, K0.denom(c)) if not K1.is_one(common): f = dup_mul_ground(f, common, K0) if not convert: return common, f else: return common, dup_convert(f, K0, K1)
def dup_cyclotomic_p(f, K, irreducible=False): """ Efficiently test if ``f`` is a cyclotomic polnomial. Examples ======== >>> from sympy.polys.factortools import dup_cyclotomic_p >>> from sympy.polys.domains import ZZ >>> f = [1, 0, 1, 0, 0, 0,-1, 0, 1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_cyclotomic_p(f, ZZ) False >>> g = [1, 0, 1, 0, 0, 0,-1, 0,-1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_cyclotomic_p(g, ZZ) True """ if K.is_QQ: try: K0, K = K, K.get_ring() f = dup_convert(f, K0, K) except CoercionFailed: return False elif not K.is_ZZ: return False lc = dup_LC(f, K) tc = dup_TC(f, K) if lc != 1 or (tc != -1 and tc != 1): return False if not irreducible: coeff, factors = dup_factor_list(f, K) if coeff != K.one or factors != [(f, 1)]: return False n = dup_degree(f) g, h = [], [] for i in xrange(n, -1, -2): g.insert(0, f[i]) for i in xrange(n - 1, -1, -2): h.insert(0, f[i]) g = dup_sqr(dup_strip(g), K) h = dup_sqr(dup_strip(h), K) F = dup_sub(g, dup_lshift(h, 1, K), K) if K.is_negative(dup_LC(F, K)): F = dup_neg(F, K) if F == f: return True g = dup_mirror(f, K) if K.is_negative(dup_LC(g, K)): g = dup_neg(g, K) if F == g and dup_cyclotomic_p(g, K): return True G = dup_sqf_part(F, K) if dup_sqr(G, K) == F and dup_cyclotomic_p(G, K): return True return False
def dup_gf_sqf_part(f, K): """Compute square-free part of ``f`` in ``GF(p)[x]``. """ f = dup_convert(f, K, K.dom) g = gf_sqf_part(f, K.mod, K.dom) return dup_convert(g, K.dom, K)
def dup_zz_cyclotomic_p(f, K, irreducible=False): """ Efficiently test if ``f`` is a cyclotomic polnomial. **Examples** >>> from sympy.polys.factortools import dup_zz_cyclotomic_p >>> from sympy.polys.domains import ZZ >>> f = [1, 0, 1, 0, 0, 0,-1, 0, 1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_zz_cyclotomic_p(f, ZZ) False >>> g = [1, 0, 1, 0, 0, 0,-1, 0,-1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_zz_cyclotomic_p(g, ZZ) True """ if K.is_QQ: try: K0, K = K, K.get_ring() f = dup_convert(f, K0, K) except CoercionFailed: return False elif not K.is_ZZ: return False lc = dup_LC(f, K) tc = dup_TC(f, K) if lc != 1 or (tc != -1 and tc != 1): return False if not irreducible: coeff, factors = dup_factor_list(f, K) if coeff != K.one or factors != [(f, 1)]: return False n = dup_degree(f) g, h = [], [] for i in xrange(n, -1, -2): g.insert(0, f[i]) for i in xrange(n-1, -1, -2): h.insert(0, f[i]) g = dup_sqr(dup_strip(g), K) h = dup_sqr(dup_strip(h), K) F = dup_sub(g, dup_lshift(h, 1, K), K) if K.is_negative(dup_LC(F, K)): F = dup_neg(F, K) if F == f: return True g = dup_mirror(f, K) if K.is_negative(dup_LC(g, K)): g = dup_neg(g, K) if F == g and dup_zz_cyclotomic_p(g, K): return True G = dup_sqf_part(F, K) if dup_sqr(G, K) == F and dup_zz_cyclotomic_p(G, K): return True return False
def dup_gf_sqf_part(f, K): """Compute square-free part of ``f`` in ``GF(p)[x]``. """ f = dup_convert(f, K, K.dom) g = gf_sqf_part(f, K.mod, K.dom) return dup_convert(g, K.dom, K)