def dup_ff_prs_gcd(f, g, 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 dup_ff_prs_gcd >>> f = QQ.map([1, 0, -1]) >>> g = QQ.map([1, -3, 2]) >>> dup_ff_prs_gcd(f, g, QQ) ([1/1, -1/1], [1/1, 1/1], [1/1, -2/1]) """ result = _dup_ff_trivial_gcd(f, g, K) if result is not None: return result h = dup_subresultants(f, g, K)[-1] h = dup_monic(h, K) cff = dup_exquo(f, h, K) cfg = dup_exquo(g, h, K) return h, cff, cfg
def dup_rr_lcm(f, g, K): """ Computes polynomial LCM over a ring in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dup_rr_lcm >>> f = ZZ.map([1, 0, -1]) >>> g = ZZ.map([1, -3, 2]) >>> dup_rr_lcm(f, g, ZZ) [1, -2, -1, 2] """ fc, f = dup_primitive(f, K) gc, g = dup_primitive(g, K) c = K.lcm(fc, gc) h = dup_exquo(dup_mul(f, g, K), dup_gcd(f, g, K), K) return dup_mul_ground(h, c, K)
def test_dup_div(): f, g, q, r = [5,4,3,2,1], [1,2,3], [5,-6,0], [20,1] assert dup_div(f, g, ZZ) == (q, r) assert dup_quo(f, g, ZZ) == q assert dup_rem(f, g, ZZ) == r raises(ExactQuotientFailed, lambda: dup_exquo(f, g, ZZ)) f, g, q, r = [5,4,3,2,1,0], [1,2,0,0,9], [5,-6], [15,2,-44,54] assert dup_div(f, g, ZZ) == (q, r) assert dup_quo(f, g, ZZ) == q assert dup_rem(f, g, ZZ) == r raises(ExactQuotientFailed, lambda: dup_exquo(f, g, ZZ))
def dup_sqf_part(f, K): """ Returns square-free part of a polynomial in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dup_sqf_part >>> dup_sqf_part([ZZ(1), ZZ(0), -ZZ(3), -ZZ(2)], ZZ) [1, -1, -2] """ if not K.has_CharacteristicZero: return dup_gf_sqf_part(f, K) if not f: return f if K.is_negative(dup_LC(f, K)): f = dup_neg(f, K) gcd = dup_gcd(f, dup_diff(f, 1, K), K) sqf = dup_exquo(f, gcd, K) if K.has_Field or not K.is_Exact: return dup_monic(sqf, K) else: return dup_primitive(sqf, K)[1]
def dup_zz_cyclotomic_poly(n, K): """Efficiently generate n-th cyclotomic polnomial. """ h = [K.one, -K.one] for p, k in factorint(n).iteritems(): h = dup_exquo(dup_inflate(h, p, K), h, K) h = dup_inflate(h, p**(k - 1), K) return h
def dup_zz_cyclotomic_poly(n, K): """Efficiently generate n-th cyclotomic polnomial. """ h = [K.one,-K.one] for p, k in factorint(n).iteritems(): h = dup_exquo(dup_inflate(h, p, K), h, K) h = dup_inflate(h, p**(k-1), K) return h
def dup_rr_prs_gcd(f, g, K): """ Computes polynomial GCD using subresultants over a ring. 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 ZZ >>> from sympy.polys.euclidtools import dup_rr_prs_gcd >>> f = ZZ.map([1, 0, -1]) >>> g = ZZ.map([1, -3, 2]) >>> dup_rr_prs_gcd(f, g, ZZ) ([1, -1], [1, 1], [1, -2]) """ result = _dup_rr_trivial_gcd(f, g, K) if result is not None: return result fc, F = dup_primitive(f, K) gc, G = dup_primitive(g, K) c = K.gcd(fc, gc) h = dup_subresultants(F, G, K)[-1] _, h = dup_primitive(h, K) if K.is_negative(dup_LC(h, K)): c = -c h = dup_mul_ground(h, c, K) cff = dup_exquo(f, h, K) cfg = dup_exquo(g, h, K) return h, cff, cfg
def _dup_cyclotomic_decompose(n, K): H = [[K.one, -K.one]] for p, k in factorint(n).iteritems(): Q = [dup_exquo(dup_inflate(h, p, K), h, K) for h in H] H.extend(Q) for i in xrange(1, k): Q = [dup_inflate(q, p, K) for q in Q] H.extend(Q) return H
def _dup_cyclotomic_decompose(n, K): H = [[K.one,-K.one]] for p, k in factorint(n).iteritems(): Q = [ dup_exquo(dup_inflate(h, p, K), h, K) for h in H ] H.extend(Q) for i in xrange(1, k): Q = [ dup_inflate(q, p, K) for q in Q ] H.extend(Q) return H
def test_dmp_primitive(): assert dmp_primitive([[]], 1, ZZ) == ([], [[]]) assert dmp_primitive([[1]], 1, ZZ) == ([1], [[1]]) f, g, F = [ZZ(3), ZZ(2), ZZ(1)], [ZZ(1)], [] for i in xrange(0, 5): g = dup_mul(g, f, ZZ) F.insert(0, g) assert dmp_primitive(F, 1, ZZ) == (f, [dup_exquo(c, f, ZZ) for c in F]) cont, f = dmp_primitive(f_4, 2, ZZ) assert dmp_one_p(cont, 1, ZZ) and f == f_4 cont, f = dmp_primitive(f_5, 2, ZZ) assert dmp_one_p(cont, 1, ZZ) and f == f_5 cont, f = dmp_primitive(f_6, 3, ZZ) assert dmp_one_p(cont, 2, ZZ) and f == f_6
def dup_ff_lcm(f, g, K): """ Computes polynomial LCM over a field in ``K[x]``. **Examples** >>> from sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dup_ff_lcm >>> f = [QQ(1,2), QQ(7,4), QQ(3,2)] >>> g = [QQ(1,2), QQ(1), QQ(0)] >>> dup_ff_lcm(f, g, QQ) [1/1, 7/2, 3/1, 0/1] """ h = dup_exquo(dup_mul(f, g, K), dup_gcd(f, g, K), K) return dup_monic(h, K)
def test_dmp_primitive(): assert dmp_primitive([[]], 1, ZZ) == ([], [[]]) assert dmp_primitive([[1]], 1, ZZ) == ([1], [[1]]) f, g, F = [ZZ(3),ZZ(2),ZZ(1)], [ZZ(1)], [] for i in xrange(0, 5): g = dup_mul(g, f, ZZ) F.insert(0, g) assert dmp_primitive(F, 1, ZZ) == (f, [ dup_exquo(c, f, ZZ) for c in F ]) cont, f = dmp_primitive(f_4, 2, ZZ) assert dmp_one_p(cont, 1, ZZ) and f == f_4 cont, f = dmp_primitive(f_5, 2, ZZ) assert dmp_one_p(cont, 1, ZZ) and f == f_5 cont, f = dmp_primitive(f_6, 3, ZZ) assert dmp_one_p(cont, 2, ZZ) and f == f_6
def dup_gcdex(f, g, K): """ Extended Euclidean algorithm in ``F[x]``. Returns ``(s, t, h)`` such that ``h = gcd(f, g)`` and ``s*f + t*g = h``. **Examples** >>> from sympy.polys.domains import QQ >>> from sympy.polys.euclidtools import dup_gcdex >>> f = QQ.map([1, -2, -6, 12, 15]) >>> g = QQ.map([1, 1, -4, -4]) >>> dup_gcdex(f, g, QQ) ([-1/5, 3/5], [1/5, -6/5, 2/1], [1/1, 1/1]) """ s, h = dup_half_gcdex(f, g, K) F = dup_sub_mul(h, s, f, K) t = dup_exquo(F, g, K) return s, t, h
def dup_gff_list(f, K): """ Compute greatest factorial factorization of ``f`` in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dup_gff_list >>> f = ZZ.map([1, 2, -1, -2, 0, 0]) >>> dup_gff_list(f, ZZ) [([1, 0], 1), ([1, 2], 4)] """ if not f: raise ValueError("greatest factorial factorization doesn't exist for a zero polynomial") f = dup_monic(f, K) if not dup_degree(f): return [] else: g = dup_gcd(f, dup_shift(f, K.one, K), K) H = dup_gff_list(g, K) for i, (h, k) in enumerate(H): g = dup_mul(g, dup_shift(h, -K(k), K), K) H[i] = (h, k + 1) f = dup_exquo(f, g, K) if not dup_degree(f): return H else: return [(f, 1)] + H