def dmp_mul_term(f, c, i, u, K): """ Multiply ``f`` by ``c(x_2..x_u)*x_0**i`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dmp_mul_term(x**2*y + x, 3*y, 2) 3*x**4*y**2 + 3*x**3*y """ if not u: return dup_mul_term(f, c, i, K) v = u - 1 if dmp_zero_p(f, u): return f if dmp_zero_p(c, v): return dmp_zero(u) else: return [ dmp_mul(cf, c, v, K) for cf in f ] + dmp_zeros(i, v, K)
def dmp_mul_term(f, c, i, u, K): """ Multiply ``f`` by ``c(x_2..x_u)*x_0**i`` in ``K[X]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dmp_mul_term >>> f = ZZ.map([[1, 0], [1], []]) >>> c = ZZ.map([3, 0]) >>> dmp_mul_term(f, c, 2, 1, ZZ) [[3, 0, 0], [3, 0], [], [], []] """ if not u: return dup_mul_term(f, c, i, K) v = u-1 if dmp_zero_p(f, u): return f if dmp_zero_p(c, v): return dmp_zero(u) else: return [ dmp_mul(cf, c, v, K) for cf in f ] + dmp_zeros(i, v, K)
def dmp_cancel(f, g, u, K, multout=True): """ Cancel common factors in a rational function ``f/g``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_cancel >>> f = ZZ.map([[2], [0], [-2]]) >>> g = ZZ.map([[1], [-2], [1]]) >>> dmp_cancel(f, g, 1, ZZ) ([[2], [2]], [[1], [-1]]) """ if dmp_zero_p(f, u) or dmp_zero_p(g, u): if multout: return f, g else: return K.one, K.one, f, g K0 = None if K.has_Field and K.has_assoc_Ring: K0, K = K, K.get_ring() cq, f = dmp_clear_denoms(f, u, K0, K, convert=True) cp, g = dmp_clear_denoms(g, u, K0, K, convert=True) else: cp, cq = K.one, K.one _, p, q = dmp_inner_gcd(f, g, u, K) if K0 is not None: p = dmp_convert(p, u, K, K0) q = dmp_convert(q, u, K, K0) K = K0 p_neg = K.is_negative(dmp_ground_LC(p, u, K)) q_neg = K.is_negative(dmp_ground_LC(q, u, K)) if p_neg and q_neg: p, q = dmp_neg(p, u, K), dmp_neg(q, u, K) elif p_neg: cp, p = -cp, dmp_neg(p, u, K) elif q_neg: cp, q = -cp, dmp_neg(q, u, K) if not multout: return cp, cq, p, q p = dmp_mul_ground(p, cp, u, K) q = dmp_mul_ground(q, cq, u, K) return p, q
def dmp_mul_term(f, c, i, u, K): """Multiply `f` by `c(x_2..x_u)*x_0**i` in `K[X]`. """ if not u: return dup_mul_term(f, c, i, K) v = u-1 if dmp_zero_p(f, u): return f if dmp_zero_p(c, v): return dmp_zero(u) else: return [ dmp_mul(cf, c, v, K) for cf in f ] + dmp_zeros(i, v, K)
def dmp_zz_wang_hensel_lifting(f, H, LC, A, p, u, K): """Wang/EEZ: Parallel Hensel lifting algorithm. """ S, n, v = [f], len(A), u-1 H = list(H) for i, a in enumerate(reversed(A[1:])): s = dmp_eval_in(S[0], a, n-i, u-i, K) S.insert(0, dmp_ground_trunc(s, p, v-i, K)) d = max(dmp_degree_list(f, u)[1:]) for j, s, a in zip(xrange(2, n+2), S, A): G, w = list(H), j-1 I, J = A[:j-2], A[j-1:] for i, (h, lc) in enumerate(zip(H, LC)): lc = dmp_ground_trunc(dmp_eval_tail(lc, J, v, K), p, w-1, K) H[i] = [lc] + dmp_raise(h[1:], 1, w-1, K) m = dmp_nest([K.one, -a], w, K) M = dmp_one(w, K) c = dmp_sub(s, dmp_expand(H, w, K), w, K) dj = dmp_degree_in(s, w, w) for k in xrange(0, dj): if dmp_zero_p(c, w): break M = dmp_mul(M, m, w, K) C = dmp_diff_eval_in(c, k+1, a, w, w, K) if not dmp_zero_p(C, w-1): C = dmp_quo_ground(C, K.factorial(k+1), w-1, K) T = dmp_zz_diophantine(G, C, I, d, p, w-1, K) for i, (h, t) in enumerate(zip(H, T)): h = dmp_add_mul(h, dmp_raise(t, 1, w-1, K), M, w, K) H[i] = dmp_ground_trunc(h, p, w, K) h = dmp_sub(s, dmp_expand(H, w, K), w, K) c = dmp_ground_trunc(h, p, w, K) if dmp_expand(H, u, K) != f: raise ExtraneousFactors # pragma: no cover else: return H
def dmp_zz_wang_hensel_lifting(f, H, LC, A, p, u, K): """Wang/EEZ: Parallel Hensel lifting algorithm. """ S, n, v = [f], len(A), u - 1 H = list(H) for i, a in enumerate(reversed(A[1:])): s = dmp_eval_in(S[0], a, n - i, u - i, K) S.insert(0, dmp_ground_trunc(s, p, v - i, K)) d = max(dmp_degree_list(f, u)[1:]) for j, s, a in zip(range(2, n + 2), S, A): G, w = list(H), j - 1 I, J = A[:j - 2], A[j - 1:] for i, (h, lc) in enumerate(zip(H, LC)): lc = dmp_ground_trunc(dmp_eval_tail(lc, J, v, K), p, w - 1, K) H[i] = [lc] + dmp_raise(h[1:], 1, w - 1, K) m = dmp_nest([K.one, -a], w, K) M = dmp_one(w, K) c = dmp_sub(s, dmp_expand(H, w, K), w, K) dj = dmp_degree_in(s, w, w) for k in K.map(range(0, dj)): if dmp_zero_p(c, w): break M = dmp_mul(M, m, w, K) C = dmp_diff_eval_in(c, k + 1, a, w, w, K) if not dmp_zero_p(C, w - 1): C = dmp_quo_ground(C, K.factorial(k + 1), w - 1, K) T = dmp_zz_diophantine(G, C, I, d, p, w - 1, K) for i, (h, t) in enumerate(zip(H, T)): h = dmp_add_mul(h, dmp_raise(t, 1, w - 1, K), M, w, K) H[i] = dmp_ground_trunc(h, p, w, K) h = dmp_sub(s, dmp_expand(H, w, K), w, K) c = dmp_ground_trunc(h, p, w, K) if dmp_expand(H, u, K) != f: raise ExtraneousFactors # pragma: no cover else: return H
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_ground_content(f, u, K): """ Compute the GCD of coefficients of ``f`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ, QQ >>> from sympy.polys.densetools import dmp_ground_content >>> f = ZZ.map([[2, 6], [4, 12]]) >>> g = QQ.map([[2, 6], [4, 12]]) >>> dmp_ground_content(f, 1, ZZ) 2 >>> dmp_ground_content(g, 1, QQ) 2/1 """ if not u: return dup_content(f, K) if dmp_zero_p(f, u): return K.zero cont, v = K.zero, u - 1 for c in f: cont = K.gcd(cont, dmp_ground_content(c, v, K)) if K.is_one(cont): break return cont
def dmp_ground_monic(f, u, K): """ Divides all coefficients by ``LC(f)`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ, QQ >>> from sympy.polys.densetools import dmp_ground_monic >>> f = ZZ.map([[3, 6], [3, 0], [9, 3]]) >>> g = QQ.map([[3, 8], [5, 6], [2, 3]]) >>> dmp_ground_monic(f, 1, ZZ) [[1, 2], [1, 0], [3, 1]] >>> dmp_ground_monic(g, 1, QQ) [[1/1, 8/3], [5/3, 2/1], [2/3, 1/1]] """ if not u: return dup_monic(f, K) if dmp_zero_p(f, u): return f lc = dmp_ground_LC(f, u, K) if K.is_one(lc): return f else: return dmp_exquo_ground(f, lc, u, K)
def dmp_eval_tail(f, A, u, K): """ Evaluate a polynomial at ``x_j = a_j, ...`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dmp_eval_tail >>> f = ZZ.map([[2, 3], [1, 2]]) >>> dmp_eval_tail(f, (2, 2), 1, ZZ) 18 >>> dmp_eval_tail(f, (2,), 1, ZZ) [7, 4] """ if not A: return f if dmp_zero_p(f, u): return dmp_zero(u - len(A)) e = _rec_eval_tail(f, 0, A, u, K) if u == len(A) - 1: return e else: return dmp_strip(e, u - len(A))
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_compose(f, g, u, K): """ Evaluate functional composition ``f(g)`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dmp_compose >>> f = ZZ.map([[1, 2], [1, 0]]) >>> g = ZZ.map([[1, 0]]) >>> dmp_compose(f, g, 1, ZZ) [[1, 3, 0]] """ if not u: return dup_compose(f, g, K) if dmp_zero_p(f, u): return f h = [f[0]] for c in f[1:]: h = dmp_mul(h, g, u, K) h = dmp_add_term(h, c, 0, u, K) return h
def dmp_add_term(f, c, i, u, K): """ Add ``c(x_2..x_u)*x_0**i`` to ``f`` in ``K[X]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dmp_add_term >>> f = ZZ.map([[1, 0], [1]]) >>> c = ZZ.map([2]) >>> dmp_add_term(f, c, 2, 1, ZZ) [[2], [1, 0], [1]] """ if not u: return dup_add_term(f, c, i, K) v = u-1 if dmp_zero_p(c, v): return f n = len(f) m = n-i-1 if i == n-1: return dmp_strip([dmp_add(f[0], c, v, K)] + f[1:], u) else: if i >= n: return [c] + dmp_zeros(i-n, v, K) + f else: return f[:m] + [dmp_add(f[m], c, v, K)] + f[m+1:]
def dmp_exquo(f, g, u, K): """ Returns polynomial quotient in ``K[X]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dmp_exquo >>> f = ZZ.map([[1], [1, 0], []]) >>> g = ZZ.map([[1], [1, 0]]) >>> h = ZZ.map([[2], [2]]) >>> dmp_exquo(f, g, 1, ZZ) [[1], []] >>> dmp_exquo(f, h, 1, ZZ) Traceback (most recent call last): ... ExactQuotientFailed: [[2], [2]] does not divide [[1], [1, 0], []] """ q, r = dmp_div(f, g, u, K) if dmp_zero_p(r, u): return q else: raise ExactQuotientFailed(f, g)
def dmp_content(f, u, K): """ Returns GCD of multivariate coefficients. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_content >>> f = ZZ.map([[2, 6], [4, 12]]) >>> dmp_content(f, 1, ZZ) [2, 6] """ cont, v = dmp_LC(f, K), u - 1 if dmp_zero_p(f, u): return cont for c in f[1:]: cont = dmp_gcd(cont, c, v, K) if dmp_one_p(cont, v, K): break if K.is_negative(dmp_ground_LC(cont, v, K)): return dmp_neg(cont, v, K) else: return cont
def dmp_integrate(f, m, u, K): """ Computes indefinite integral of ``f`` in ``x_0`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import QQ >>> from sympy.polys.densetools import dmp_integrate >>> dmp_integrate([[QQ(1)], [QQ(2), QQ(0)]], 1, 1, QQ) [[1/2], [2/1, 0/1], []] >>> dmp_integrate([[QQ(1)], [QQ(2), QQ(0)]], 2, 1, QQ) [[1/6], [1/1, 0/1], [], []] """ if not u: return dup_integrate(f, m, K) if m <= 0 or dmp_zero_p(f, u): return f g, v = dmp_zeros(m, u - 1, K), u - 1 for i, c in enumerate(reversed(f)): n = i + 1 for j in xrange(1, m): n *= i + j + 1 g.insert(0, dmp_quo_ground(c, K(n), v, K)) return g
def dmp_ground_primitive(f, u, K): """ Compute content and the primitive form of ``f`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ, QQ >>> from sympy.polys.densetools import dmp_ground_primitive >>> f = ZZ.map([[2, 6], [4, 12]]) >>> g = QQ.map([[2, 6], [4, 12]]) >>> dmp_ground_primitive(f, 1, ZZ) (2, [[1, 3], [2, 6]]) >>> dmp_ground_primitive(g, 1, QQ) (2/1, [[1/1, 3/1], [2/1, 6/1]]) """ if not u: return dup_primitive(f, K) if dmp_zero_p(f, u): return K.zero, f cont = dmp_ground_content(f, u, K) if K.is_one(cont): return cont, f else: return cont, dmp_quo_ground(f, cont, u, K)
def dmp_ground_content(f, u, K): """ Compute the GCD of coefficients of ``f`` in ``K[X]``. Examples ======== >>> from sympy.polys.domains import ZZ, QQ >>> from sympy.polys.densetools import dmp_ground_content >>> f = ZZ.map([[2, 6], [4, 12]]) >>> g = QQ.map([[2, 6], [4, 12]]) >>> dmp_ground_content(f, 1, ZZ) 2 >>> dmp_ground_content(g, 1, QQ) 2/1 """ if not u: return dup_content(f, K) if dmp_zero_p(f, u): return K.zero cont, v = K.zero, u-1 for c in f: cont = K.gcd(cont, dmp_ground_content(c, v, K)) if K.is_one(cont): break return cont
def dmp_add_term(f, c, i, u, K): """ Add ``c(x_2..x_u)*x_0**i`` to ``f`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dmp_add_term(x*y + 1, 2, 2) 2*x**2 + x*y + 1 """ if not u: return dup_add_term(f, c, i, K) v = u - 1 if dmp_zero_p(c, v): return f n = len(f) m = n - i - 1 if i == n - 1: return dmp_strip([dmp_add(f[0], c, v, K)] + f[1:], u) else: if i >= n: return [c] + dmp_zeros(i - n, v, K) + f else: return f[:m] + [dmp_add(f[m], c, v, K)] + f[m + 1:]
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_content(f, u, K): """ Returns GCD of multivariate coefficients. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_content >>> f = ZZ.map([[2, 6], [4, 12]]) >>> dmp_content(f, 1, ZZ) [2, 6] """ cont, v = dmp_LC(f, K), u-1 if dmp_zero_p(f, u): return cont for c in f[1:]: cont = dmp_gcd(cont, c, v, K) if dmp_one_p(cont, v, K): break if K.is_negative(dmp_ground_LC(cont, v, K)): return dmp_neg(cont, v, K) else: return cont
def dmp_compose(f, g, u, K): """ Evaluate functional composition ``f(g)`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dmp_compose(x*y + 2*x + y, y) y**2 + 3*y """ if not u: return dup_compose(f, g, K) if dmp_zero_p(f, u): return f h = [f[0]] for c in f[1:]: h = dmp_mul(h, g, u, K) h = dmp_add_term(h, c, 0, u, K) return h
def dmp_exquo(f, g, u, K): """ Returns polynomial quotient in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = x**2 + x*y >>> g = x + y >>> h = 2*x + 2 >>> R.dmp_exquo(f, g) x >>> R.dmp_exquo(f, h) Traceback (most recent call last): ... ExactQuotientFailed: [[2], [2]] does not divide [[1], [1, 0], []] """ q, r = dmp_div(f, g, u, K) if dmp_zero_p(r, u): return q else: raise ExactQuotientFailed(f, g)
def dmp_pow(f, n, u, K): """Raise f to the n-th power in `K[X]`. """ if not u: return dup_pow(f, n, K) if not n: return dmp_one(u, K) if n < 0: raise ValueError("can't raise polynomial to a negative power") if n == 1 or dmp_zero_p(f, u) or dmp_one_p(f, u, K): return f g = dmp_one(u, K) while True: n, m = n // 2, n if m & 1: g = dmp_mul(g, f, u, K) if not n: break f = dmp_sqr(f, u, K) return g
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_content(f, u, K): """ Returns GCD of multivariate coefficients. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y, = ring("x,y", ZZ) >>> R.dmp_content(2*x*y + 6*x + 4*y + 12) 2*y + 6 """ cont, v = dmp_LC(f, K), u - 1 if dmp_zero_p(f, u): return cont for c in f[1:]: cont = dmp_gcd(cont, c, v, K) if dmp_one_p(cont, v, K): break if K.is_negative(dmp_ground_LC(cont, v, K)): return dmp_neg(cont, v, K) else: return cont
def dmp_ground_monic(f, u, K): """ Divide all coefficients by ``LC(f)`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ, QQ >>> R, x,y = ring("x,y", ZZ) >>> f = 3*x**2*y + 6*x**2 + 3*x*y + 9*y + 3 >>> R.dmp_ground_monic(f) x**2*y + 2*x**2 + x*y + 3*y + 1 >>> R, x,y = ring("x,y", QQ) >>> f = 3*x**2*y + 8*x**2 + 5*x*y + 6*x + 2*y + 3 >>> R.dmp_ground_monic(f) x**2*y + 8/3*x**2 + 5/3*x*y + 2*x + 2/3*y + 1 """ if not u: return dup_monic(f, K) if dmp_zero_p(f, u): return f lc = dmp_ground_LC(f, u, K) if K.is_one(lc): return f else: return dmp_exquo_ground(f, lc, u, K)
def dmp_add_term(f, c, i, u, K): """ Add ``c(x_2..x_u)*x_0**i`` to ``f`` in ``K[X]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dmp_add_term >>> f = ZZ.map([[1, 0], [1]]) >>> c = ZZ.map([2]) >>> dmp_add_term(f, c, 2, 1, ZZ) [[2], [1, 0], [1]] """ if not u: return dup_add_term(f, c, i, K) v = u - 1 if dmp_zero_p(c, v): return f n = len(f) m = n - i - 1 if i == n - 1: return dmp_strip([dmp_add(f[0], c, v, K)] + f[1:], u) else: if i >= n: return [c] + dmp_zeros(i - n, v, K) + f else: return f[:m] + [dmp_add(f[m], c, v, K)] + f[m + 1:]
def dmp_integrate(f, m, u, K): """ Computes the indefinite integral of ``f`` in ``x_0`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x,y = ring("x,y", QQ) >>> R.dmp_integrate(x + 2*y, 1) 1/2*x**2 + 2*x*y >>> R.dmp_integrate(x + 2*y, 2) 1/6*x**3 + x**2*y """ if not u: return dup_integrate(f, m, K) if m <= 0 or dmp_zero_p(f, u): return f g, v = dmp_zeros(m, u - 1, K), u - 1 for i, c in enumerate(reversed(f)): n = i + 1 for j in range(1, m): n *= i + j + 1 g.insert(0, dmp_quo_ground(c, K(n), v, K)) return g
def dmp_eval_tail(f, A, u, K): """ Evaluate a polynomial at ``x_j = a_j, ...`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = 2*x*y + 3*x + y + 2 >>> R.dmp_eval_tail(f, [2]) 7*x + 4 >>> R.dmp_eval_tail(f, [2, 2]) 18 """ if not A: return f if dmp_zero_p(f, u): return dmp_zero(u - len(A)) e = _rec_eval_tail(f, 0, A, u, K) if u == len(A) - 1: return e else: return dmp_strip(e, u - len(A))
def dmp_ground_primitive(f, u, K): """ Compute content and the primitive form of ``f`` in ``K[X]``. Examples ======== >>> from sympy.polys import ring, ZZ, QQ >>> R, x,y = ring("x,y", ZZ) >>> f = 2*x*y + 6*x + 4*y + 12 >>> R.dmp_ground_primitive(f) (2, x*y + 3*x + 2*y + 6) >>> R, x,y = ring("x,y", QQ) >>> f = 2*x*y + 6*x + 4*y + 12 >>> R.dmp_ground_primitive(f) (2, x*y + 3*x + 2*y + 6) """ if not u: return dup_primitive(f, K) if dmp_zero_p(f, u): return K.zero, f cont = dmp_ground_content(f, u, K) if K.is_one(cont): return cont, f else: return cont, dmp_quo_ground(f, cont, u, K)
def dmp_pow(f, n, u, K): """Raise f to the n-th power in `K[X]`. """ if not u: return dup_pow(f, n, K) if not n: return dmp_one(u, K) if n < 0: raise ValueError("can't raise polynomial to a negative power") if n == 1 or dmp_zero_p(f, u) or dmp_one_p(f, u, K): return f g = dmp_one(u, K) while True: n, m = n//2, n if m & 1: g = dmp_mul(g, f, u, K) if not n: break f = dmp_sqr(f, u, K) return g
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_quo(f, g, u, K): """Returns polynomial quotient in `K[X]`. """ q, r = dmp_div(f, g, u, K) if dmp_zero_p(r, u): return q else: raise ExactQuotientFailed('%s does not divide %s' % (g, f))
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 _parse(cls, rep, dom, lev=None): if type(rep) is tuple: num, den = rep if lev is not None: if type(num) is dict: num = dmp_from_dict(num, lev, dom) if type(den) is dict: den = dmp_from_dict(den, lev, dom) else: num, num_lev = dmp_validate(num) den, den_lev = dmp_validate(den) if num_lev == den_lev: lev = num_lev else: raise ValueError('inconsistent number of levels') if dmp_zero_p(den, lev): raise ZeroDivisionError('fraction denominator') if dmp_zero_p(num, lev): den = dmp_one(lev, dom) else: if dmp_negative_p(den, lev, dom): num = dmp_neg(num, lev, dom) den = dmp_neg(den, lev, dom) else: num = rep if lev is not None: if type(num) is dict: num = dmp_from_dict(num, lev, dom) elif type(num) is not list: num = dmp_ground(dom.convert(num), lev) else: num, lev = dmp_validate(num) den = dmp_one(lev, dom) return num, den, lev
def dmp_ff_div(f, g, u, K): """ Polynomial division with remainder over a field. Examples ======== >>> from sympy.polys.domains import QQ >>> from sympy.polys.densearith import dmp_ff_div >>> f = QQ.map([[1], [1, 0], []]) >>> g = QQ.map([[2], [2]]) >>> dmp_ff_div(f, g, 1, QQ) ([[1/2], [1/2, -1/2]], [[-1/1, 1/1]]) """ if not u: return dup_ff_div(f, g, K) df = dmp_degree(f, u) dg = dmp_degree(g, u) if dg < 0: raise ZeroDivisionError("polynomial division") q, r = dmp_zero(u), f if df < dg: return q, r lc_g, v = dmp_LC(g, K), u - 1 while True: dr = dmp_degree(r, u) if dr < dg: break lc_r = dmp_LC(r, K) c, R = dmp_ff_div(lc_r, lc_g, v, K) if not dmp_zero_p(R, v): break j = dr - dg q = dmp_add_term(q, c, j, u, K) h = dmp_mul_term(g, c, j, u, K) r = dmp_sub(r, h, u, K) return q, r
def _dmp_rr_trivial_gcd(f, g, u, K): """Handle trivial cases in GCD algorithm over a ring. """ 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: if K.is_nonnegative(dmp_ground_LC(g, u, K)): return g, dmp_zero(u), dmp_one(u, K) else: return dmp_neg(g, u, K), dmp_zero(u), dmp_ground(-K.one, u) elif zero_g: if K.is_nonnegative(dmp_ground_LC(f, u, K)): return f, dmp_one(u, K), dmp_zero(u) else: return dmp_neg(f, u, K), dmp_ground(-K.one, u), dmp_zero(u) elif query('USE_SIMPLIFY_GCD'): return _dmp_simplify_gcd(f, g, u, K) else: return None
def dmp_rr_div(f, g, u, K): """ Multivariate division with remainder over a ring. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dmp_rr_div >>> f = ZZ.map([[1], [1, 0], []]) >>> g = ZZ.map([[2], [2]]) >>> dmp_rr_div(f, g, 1, ZZ) ([[]], [[1], [1, 0], []]) """ if not u: return dup_rr_div(f, g, K) df = dmp_degree(f, u) dg = dmp_degree(g, u) if dg < 0: raise ZeroDivisionError("polynomial division") q, r = dmp_zero(u), f if df < dg: return q, r lc_g, v = dmp_LC(g, K), u - 1 while True: dr = dmp_degree(r, u) if dr < dg: break lc_r = dmp_LC(r, K) c, R = dmp_rr_div(lc_r, lc_g, v, K) if not dmp_zero_p(R, v): break j = dr - dg q = dmp_add_term(q, c, j, u, K) h = dmp_mul_term(g, c, j, u, K) r = dmp_sub(r, h, u, K) return q, r
def dmp_ff_div(f, g, u, K): """ Polynomial division with remainder over a field. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x,y = ring("x,y", QQ) >>> R.dmp_ff_div(x**2 + x*y, 2*x + 2) (1/2*x + 1/2*y - 1/2, -y + 1) """ if not u: return dup_ff_div(f, g, K) df = dmp_degree(f, u) dg = dmp_degree(g, u) if dg < 0: raise ZeroDivisionError("polynomial division") q, r, dr = dmp_zero(u), f, df if df < dg: return q, r lc_g, v = dmp_LC(g, K), u - 1 while True: lc_r = dmp_LC(r, K) c, R = dmp_ff_div(lc_r, lc_g, v, K) if not dmp_zero_p(R, v): break j = dr - dg q = dmp_add_term(q, c, j, u, K) h = dmp_mul_term(g, c, j, u, K) r = dmp_sub(r, h, u, K) _dr, dr = dr, dmp_degree(r, u) if dr < dg: break elif not (dr < _dr): raise PolynomialDivisionFailed(f, g, K) return q, r