def dmp_fateman_poly_F_1(n, K): """Fateman's GCD benchmark: trivial GCD """ u = [K(1), K(0)] for i in xrange(0, n): u = [dmp_one(i, K), u] v = [K(1), K(0), K(0)] for i in xrange(0, n): v = [dmp_one(i, K), dmp_zero(i), v] m = n - 1 U = dmp_add_term(u, dmp_ground(K(1), m), 0, n, K) V = dmp_add_term(u, dmp_ground(K(2), m), 0, n, K) f = [[-K(3), K(0)], [], [K(1), K(0), -K(1)]] W = dmp_add_term(v, dmp_ground(K(1), m), 0, n, K) Y = dmp_raise(f, m, 1, K) F = dmp_mul(U, V, n, K) G = dmp_mul(W, Y, n, K) H = dmp_one(n, K) return F, G, H
def dmp_fateman_poly_F_1(n, K): """Fateman's GCD benchmark: trivial GCD """ u = [K(1), K(0)] for i in range(0, n): u = [dmp_one(i, K), u] v = [K(1), K(0), K(0)] for i in range(0, n): v = [dmp_one(i, K), dmp_zero(i), v] m = n - 1 U = dmp_add_term(u, dmp_ground(K(1), m), 0, n, K) V = dmp_add_term(u, dmp_ground(K(2), m), 0, n, K) f = [[-K(3), K(0)], [], [K(1), K(0), -K(1)]] W = dmp_add_term(v, dmp_ground(K(1), m), 0, n, K) Y = dmp_raise(f, m, 1, K) F = dmp_mul(U, V, n, K) G = dmp_mul(W, Y, n, K) H = dmp_one(n, K) return F, G, H
def quo(f, g): """Computes quotient of fractions `f` and `g`. """ if isinstance(g, DMP): lev, dom, per, (F_num, F_den), G = f.poly_unify(g) num, den = F_num, dmp_mul(F_den, G, lev, dom) else: lev, dom, per, F, G = f.frac_unify(g) (F_num, F_den), (G_num, G_den) = F, G num = dmp_mul(F_num, G_den, lev, dom) den = dmp_mul(F_den, G_num, lev, dom) return per(num, den)
def mul(f, g): """Multiply two multivariate fractions `f` and `g`. """ if isinstance(g, DMP): lev, dom, per, (F_num, F_den), G = f.poly_unify(g) num, den = dmp_mul(F_num, G, lev, dom), F_den else: lev, dom, per, F, G = f.frac_unify(g) (F_num, F_den), (G_num, G_den) = F, G num = dmp_mul(F_num, G_num, lev, dom) den = dmp_mul(F_den, G_den, lev, dom) return per(num, den)
def sub(f, g): """Subtract two multivariate fractions ``f`` and ``g``. """ if isinstance(g, DMP): lev, dom, per, (F_num, F_den), G = f.poly_unify(g) num, den = dmp_sub_mul(F_num, F_den, G, lev, dom), F_den else: lev, dom, per, F, G = f.frac_unify(g) (F_num, F_den), (G_num, G_den) = F, G num = dmp_sub(dmp_mul(F_num, G_den, lev, dom), dmp_mul(F_den, G_num, lev, dom), lev, dom) den = dmp_mul(F_den, G_den, lev, dom) return per(num, den)
def dmp_rr_lcm(f, g, u, K): """ Computes polynomial LCM over a ring in `K[X]`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y, = ring("x,y", ZZ) >>> f = x**2 + 2*x*y + y**2 >>> g = x**2 + x*y >>> R.dmp_rr_lcm(f, g) x**3 + 2*x**2*y + x*y**2 """ fc, f = dmp_ground_primitive(f, u, K) gc, g = dmp_ground_primitive(g, u, K) c = K.lcm(fc, gc) h = dmp_quo(dmp_mul(f, g, u, K), dmp_gcd(f, g, u, K), u, K) return dmp_mul_ground(h, c, u, K)
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_rr_lcm(f, g, u, K): """ Computes polynomial LCM over a ring in `K[X]`. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_rr_lcm >>> f = ZZ.map([[1], [2, 0], [1, 0, 0]]) >>> g = ZZ.map([[1], [1, 0], []]) >>> dmp_rr_lcm(f, g, 1, ZZ) [[1], [2, 0], [1, 0, 0], []] """ fc, f = dmp_ground_primitive(f, u, K) gc, g = dmp_ground_primitive(g, u, K) c = K.lcm(fc, gc) h = dmp_quo(dmp_mul(f, g, u, K), dmp_gcd(f, g, u, K), u, K) return dmp_mul_ground(h, c, u, K)
def dmp_rr_lcm(f, g, u, K): """ Computes polynomial LCM over a ring in ``K[X]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_rr_lcm >>> f = ZZ.map([[1], [2, 0], [1, 0, 0]]) >>> g = ZZ.map([[1], [1, 0], []]) >>> dmp_rr_lcm(f, g, 1, ZZ) [[1], [2, 0], [1, 0, 0], []] """ fc, f = dmp_ground_primitive(f, u, K) gc, g = dmp_ground_primitive(g, u, K) c = K.lcm(fc, gc) h = dmp_exquo(dmp_mul(f, g, u, K), dmp_gcd(f, g, u, K), u, K) return dmp_mul_ground(h, c, u, K)
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_fateman_poly_F_3(n, K): """Fateman's GCD benchmark: sparse inputs (deg f ~ vars f) """ u = dup_from_raw_dict({n+1: K.one}, K) for i in xrange(0, n-1): u = dmp_add_term([u], dmp_one(i, K), n+1, i+1, K) v = dmp_add_term(u, dmp_ground(K(2), n-2), 0, n, K) f = dmp_sqr(dmp_add_term([dmp_neg(v, n-1, K)], dmp_one(n-1, K), n+1, n, K), n, K) g = dmp_sqr(dmp_add_term([v], dmp_one(n-1, K), n+1, n, K), n, K) v = dmp_add_term(u, dmp_one(n-2, K), 0, n-1, K) h = dmp_sqr(dmp_add_term([v], dmp_one(n-1, K), n+1, n, K), n, K) return dmp_mul(f, h, n, K), dmp_mul(g, h, n, K), h
def quo(f, g): """Computes quotient of fractions ``f`` and ``g``. """ if isinstance(g, DMP): lev, dom, per, (F_num, F_den), G = f.poly_unify(g) num, den = F_num, dmp_mul(F_den, G, lev, dom) else: lev, dom, per, F, G = f.frac_unify(g) (F_num, F_den), (G_num, G_den) = F, G num = dmp_mul(F_num, G_den, lev, dom) den = dmp_mul(F_den, G_num, lev, dom) res = per(num, den) if f.ring is not None and res not in f.ring: from sympy.polys.polyerrors import ExactQuotientFailed raise ExactQuotientFailed(f, g, f.ring) return res
def dmp_fateman_poly_F_2(n, K): """Fateman's GCD benchmark: linearly dense quartic inputs """ u = [K(1), K(0)] for i in xrange(0, n - 1): u = [dmp_one(i, K), u] m = n - 1 v = dmp_add_term(u, dmp_ground(K(2), m - 1), 0, n, K) f = dmp_sqr([dmp_one(m, K), dmp_neg(v, m, K)], n, K) g = dmp_sqr([dmp_one(m, K), v], n, K) v = dmp_add_term(u, dmp_one(m - 1, K), 0, n, K) h = dmp_sqr([dmp_one(m, K), v], n, K) return dmp_mul(f, h, n, K), dmp_mul(g, h, n, K), h
def dmp_fateman_poly_F_2(n, K): """Fateman's GCD benchmark: linearly dense quartic inputs """ u = [K(1), K(0)] for i in range(0, n - 1): u = [dmp_one(i, K), u] m = n - 1 v = dmp_add_term(u, dmp_ground(K(2), m - 1), 0, n, K) f = dmp_sqr([dmp_one(m, K), dmp_neg(v, m, K)], n, K) g = dmp_sqr([dmp_one(m, K), v], n, K) v = dmp_add_term(u, dmp_one(m - 1, K), 0, n, K) h = dmp_sqr([dmp_one(m, K), v], n, K) return dmp_mul(f, h, n, K), dmp_mul(g, h, n, K), h
def dmp_zz_wang_lead_coeffs(f, T, cs, E, H, A, u, K): """Wang/EEZ: Compute correct leading coefficients. """ C, J, v = [], [0] * len(E), u - 1 for h in H: c = dmp_one(v, K) d = dup_LC(h, K) * cs for i in reversed(xrange(len(E))): k, e, (t, _) = 0, E[i], T[i] while not (d % e): d, k = d // e, k + 1 if k != 0: c, J[i] = dmp_mul(c, dmp_pow(t, k, v, K), v, K), 1 C.append(c) if any(not j for j in J): raise ExtraneousFactors # pragma: no cover CC, HH = [], [] for c, h in zip(C, H): d = dmp_eval_tail(c, A, v, K) lc = dup_LC(h, K) if K.is_one(cs): cc = lc // d else: g = K.gcd(lc, d) d, cc = d // g, lc // g h, cs = dup_mul_ground(h, d, K), cs // d c = dmp_mul_ground(c, cc, v, K) CC.append(c) HH.append(h) if K.is_one(cs): return f, HH, CC CCC, HHH = [], [] for c, h in zip(CC, HH): CCC.append(dmp_mul_ground(c, cs, v, K)) HHH.append(dmp_mul_ground(h, cs, 0, K)) f = dmp_mul_ground(f, cs**(len(H) - 1), u, K) return f, HHH, CCC
def dmp_zz_wang_lead_coeffs(f, T, cs, E, H, A, u, K): """Wang/EEZ: Compute correct leading coefficients. """ C, J, v = [], [0]*len(E), u-1 for h in H: c = dmp_one(v, K) d = dup_LC(h, K)*cs for i in reversed(xrange(len(E))): k, e, (t, _) = 0, E[i], T[i] while not (d % e): d, k = d//e, k+1 if k != 0: c, J[i] = dmp_mul(c, dmp_pow(t, k, v, K), v, K), 1 C.append(c) if any([ not j for j in J ]): raise ExtraneousFactors # pragma: no cover CC, HH = [], [] for c, h in zip(C, H): d = dmp_eval_tail(c, A, v, K) lc = dup_LC(h, K) if K.is_one(cs): cc = lc//d else: g = K.gcd(lc, d) d, cc = d//g, lc//g h, cs = dup_mul_ground(h, d, K), cs//d c = dmp_mul_ground(c, cc, v, K) CC.append(c) HH.append(h) if K.is_one(cs): return f, HH, CC CCC, HHH = [], [] for c, h in zip(CC, HH): CCC.append(dmp_mul_ground(c, cs, v, K)) HHH.append(dmp_mul_ground(h, cs, 0, K)) f = dmp_mul_ground(f, cs**(len(H)-1), u, K) return f, HHH, CCC
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(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 dup_real_imag(f, K): """ Return bivariate polynomials ``f1`` and ``f2``, such that ``f = f1 + f2*I``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dup_real_imag >>> dup_real_imag([ZZ(1), ZZ(1), ZZ(1), ZZ(1)], ZZ) ([[1], [1], [-3, 0, 1], [-1, 0, 1]], [[3, 0], [2, 0], [-1, 0, 1, 0]]) """ if not K.is_ZZ and not K.is_QQ: raise DomainError( "computing real and imaginary parts is not supported over %s" % K) f1 = dmp_zero(1) f2 = dmp_zero(1) if not f: return f1, f2 g = [[[K.one, K.zero]], [[K.one], []]] h = dmp_ground(f[0], 2) for c in f[1:]: h = dmp_mul(h, g, 2, K) h = dmp_add_term(h, dmp_ground(c, 1), 0, 2, K) H = dup_to_raw_dict(h) for k, h in H.iteritems(): m = k % 4 if not m: f1 = dmp_add(f1, h, 1, K) elif m == 1: f2 = dmp_add(f2, h, 1, K) elif m == 2: f1 = dmp_sub(f1, h, 1, K) else: f2 = dmp_sub(f2, h, 1, K) return f1, f2
def dup_real_imag(f, K): """ Return bivariate polynomials ``f1`` and ``f2``, such that ``f = f1 + f2*I``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dup_real_imag(x**3 + x**2 + x + 1) (x**3 + x**2 - 3*x*y**2 + x - y**2 + 1, 3*x**2*y + 2*x*y - y**3 + y) """ if not K.is_ZZ and not K.is_QQ: raise DomainError( "computing real and imaginary parts is not supported over %s" % K) f1 = dmp_zero(1) f2 = dmp_zero(1) if not f: return f1, f2 g = [[[K.one, K.zero]], [[K.one], []]] h = dmp_ground(f[0], 2) for c in f[1:]: h = dmp_mul(h, g, 2, K) h = dmp_add_term(h, dmp_ground(c, 1), 0, 2, K) H = dup_to_raw_dict(h) for k, h in H.items(): m = k % 4 if not m: f1 = dmp_add(f1, h, 1, K) elif m == 1: f2 = dmp_add(f2, h, 1, K) elif m == 2: f1 = dmp_sub(f1, h, 1, K) else: f2 = dmp_sub(f2, h, 1, K) return f1, f2
def dup_real_imag(f, K): """ Return bivariate polynomials ``f1`` and ``f2``, such that ``f = f1 + f2*I``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dup_real_imag(x**3 + x**2 + x + 1) (x**3 + x**2 - 3*x*y**2 + x - y**2 + 1, 3*x**2*y + 2*x*y - y**3 + y) """ if not K.is_ZZ and not K.is_QQ: raise DomainError("computing real and imaginary parts is not supported over %s" % K) f1 = dmp_zero(1) f2 = dmp_zero(1) if not f: return f1, f2 g = [[[K.one, K.zero]], [[K.one], []]] h = dmp_ground(f[0], 2) for c in f[1:]: h = dmp_mul(h, g, 2, K) h = dmp_add_term(h, dmp_ground(c, 1), 0, 2, K) H = dup_to_raw_dict(h) for k, h in H.items(): m = k % 4 if not m: f1 = dmp_add(f1, h, 1, K) elif m == 1: f2 = dmp_add(f2, h, 1, K) elif m == 2: f1 = dmp_sub(f1, h, 1, K) else: f2 = dmp_sub(f2, h, 1, K) return f1, f2
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_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 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_zz_modular_resultant(f, g, p, u, K): """ Compute resultant of `f` and `g` modulo a prime `p`. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_zz_modular_resultant >>> f = ZZ.map([[1], [1, 2]]) >>> g = ZZ.map([[2, 1], [3]]) >>> dmp_zz_modular_resultant(f, g, ZZ(5), 1, ZZ) [-2, 0, 1] """ if not u: return gf_int(dup_prs_resultant(f, g, K)[0] % p, p) v = u - 1 n = dmp_degree(f, u) m = dmp_degree(g, u) N = dmp_degree_in(f, 1, u) M = dmp_degree_in(g, 1, u) B = n * M + m * N D, a = [K.one], -K.one r = dmp_zero(v) while dup_degree(D) <= B: while True: a += K.one if a == p: raise HomomorphismFailed('no luck') F = dmp_eval_in(f, gf_int(a, p), 1, u, K) if dmp_degree(F, v) == n: G = dmp_eval_in(g, gf_int(a, p), 1, u, K) if dmp_degree(G, v) == m: break R = dmp_zz_modular_resultant(F, G, p, v, K) e = dmp_eval(r, a, v, K) if not v: R = dup_strip([R]) e = dup_strip([e]) else: R = [R] e = [e] d = K.invert(dup_eval(D, a, K), p) d = dup_mul_ground(D, d, K) d = dmp_raise(d, v, 0, K) c = dmp_mul(d, dmp_sub(R, e, v, K), v, K) r = dmp_add(r, c, v, K) r = dmp_ground_trunc(r, p, v, K) D = dup_mul(D, [K.one, -a], K) D = dup_trunc(D, p, K) return r
def test_dup_sqf(): assert dup_sqf_part([], ZZ) == [] assert dup_sqf_p([], ZZ) == True assert dup_sqf_part([7], ZZ) == [1] assert dup_sqf_p([7], ZZ) == True assert dup_sqf_part([2,2], ZZ) == [1,1] assert dup_sqf_p([2,2], ZZ) == True assert dup_sqf_part([1,0,1,1], ZZ) == [1,0,1,1] assert dup_sqf_p([1,0,1,1], ZZ) == True assert dup_sqf_part([-1,0,1,1], ZZ) == [1,0,-1,-1] assert dup_sqf_p([-1,0,1,1], ZZ) == True assert dup_sqf_part([2,3,0,0], ZZ) == [2,3,0] assert dup_sqf_p([2,3,0,0], ZZ) == False assert dup_sqf_part([-2,3,0,0], ZZ) == [2,-3,0] assert dup_sqf_p([-2,3,0,0], ZZ) == False assert dup_sqf_list([], ZZ) == (0, []) assert dup_sqf_list([1], ZZ) == (1, []) assert dup_sqf_list([1,0], ZZ) == (1, [([1,0], 1)]) assert dup_sqf_list([2,0,0], ZZ) == (2, [([1,0], 2)]) assert dup_sqf_list([3,0,0,0], ZZ) == (3, [([1,0], 3)]) assert dup_sqf_list([ZZ(2),ZZ(4),ZZ(2)], ZZ) == \ (ZZ(2), [([ZZ(1),ZZ(1)], 2)]) assert dup_sqf_list([QQ(2),QQ(4),QQ(2)], QQ) == \ (QQ(2), [([QQ(1),QQ(1)], 2)]) assert dup_sqf_list([-1,1,0,0,1,-1], ZZ) == \ (-1, [([1,1,1,1], 1), ([1,-1], 2)]) assert dup_sqf_list([1,0,6,0,12,0,8,0,0], ZZ) == \ (1, [([1,0], 2), ([1,0,2], 3)]) K = FF(2) f = map(K, [1,0,1]) assert dup_sqf_list(f, K) == \ (K(1), [([K(1),K(1)], 2)]) K = FF(3) f = map(K, [1,0,0,2,0,0,2,0,0,1,0]) assert dup_sqf_list(f, K) == \ (K(1), [([K(1), K(0)], 1), ([K(1), K(1)], 3), ([K(1), K(2)], 6)]) f = [1,0,0,1] g = map(K, f) assert dup_sqf_part(f, ZZ) == f assert dup_sqf_part(g, K) == [K(1), K(1)] assert dup_sqf_p(f, ZZ) == True assert dup_sqf_p(g, K) == False A = [[1],[],[-3],[],[6]] D = [[1],[],[-5],[],[5],[],[4]] f, g = D, dmp_sub(A, dmp_mul(dmp_diff(D, 1, 1, ZZ), [[1,0]], 1, ZZ), 1, ZZ) res = dmp_resultant(f, g, 1, ZZ) assert dup_sqf_list(res, ZZ) == (45796, [([4,0,1], 3)]) assert dup_sqf_list_include([DMP([1, 0, 0, 0], ZZ), DMP([], ZZ), DMP([], ZZ)], ZZ[x]) == \ [([DMP([1, 0, 0, 0], ZZ)], 1), ([DMP([1], ZZ), DMP([], ZZ)], 2)]
def test_dmp_mul(): assert dmp_mul([ZZ(5)], [ZZ(7)], 0, ZZ) == \ dup_mul([ZZ(5)], [ZZ(7)], ZZ) assert dmp_mul([QQ(5,7)], [QQ(3,7)], 0, QQ) == \ dup_mul([QQ(5,7)], [QQ(3,7)], QQ) assert dmp_mul([[[]]], [[[]]], 2, ZZ) == [[[]]] assert dmp_mul([[[ZZ(1)]]], [[[]]], 2, ZZ) == [[[]]] assert dmp_mul([[[]]], [[[ZZ(1)]]], 2, ZZ) == [[[]]] assert dmp_mul([[[ZZ(2)]]], [[[ZZ(1)]]], 2, ZZ) == [[[ZZ(2)]]] assert dmp_mul([[[ZZ(1)]]], [[[ZZ(2)]]], 2, ZZ) == [[[ZZ(2)]]] assert dmp_mul([[[]]], [[[]]], 2, QQ) == [[[]]] assert dmp_mul([[[QQ(1,2)]]], [[[]]], 2, QQ) == [[[]]] assert dmp_mul([[[]]], [[[QQ(1,2)]]], 2, QQ) == [[[]]] assert dmp_mul([[[QQ(2,7)]]], [[[QQ(1,3)]]], 2, QQ) == [[[QQ(2,21)]]] assert dmp_mul([[[QQ(1,7)]]], [[[QQ(2,3)]]], 2, QQ) == [[[QQ(2,21)]]] K = FF(6) assert dmp_mul([[K(2)],[K(1)]], [[K(3)],[K(4)]], 1, K) == [[K(5)],[K(4)]]
def dmp_inner_subresultants(f, g, u, K): """ Subresultant PRS algorithm in `K[X]`. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_inner_subresultants >>> f = ZZ.map([[3, 0], [], [-1, 0, 0, -4]]) >>> g = ZZ.map([[1], [1, 0, 0, 0], [-9]]) >>> a = [[3, 0, 0, 0, 0], [1, 0, -27, 4]] >>> b = [[-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]] >>> R = ZZ.map([f, g, a, b]) >>> B = ZZ.map([[-1], [1], [9, 0, 0, 0, 0, 0, 0, 0, 0]]) >>> D = ZZ.map([0, 1, 1]) >>> dmp_inner_subresultants(f, g, 1, ZZ) == (R, B, D) True """ if not u: return dup_inner_subresultants(f, g, K) n = dmp_degree(f, u) m = dmp_degree(g, u) if n < m: f, g = g, f n, m = m, n R = [f, g] d = n - m v = u - 1 b = dmp_pow(dmp_ground(-K.one, v), d + 1, v, K) c = dmp_ground(-K.one, v) B, D = [b], [d] if dmp_zero_p(f, u) or dmp_zero_p(g, u): return R, B, D h = dmp_prem(f, g, u, K) h = dmp_mul_term(h, b, 0, u, K) while not dmp_zero_p(h, u): k = dmp_degree(h, u) R.append(h) lc = dmp_LC(g, K) p = dmp_pow(dmp_neg(lc, v, K), d, v, K) if not d: q = c else: q = dmp_pow(c, d - 1, v, K) c = dmp_quo(p, q, v, K) b = dmp_mul(dmp_neg(lc, v, K), dmp_pow(c, m - k, v, K), v, K) f, g, m, d = g, h, k, m - k B.append(b) D.append(d) h = dmp_prem(f, g, u, K) h = [dmp_quo(ch, b, v, K) for ch in h] return R, B, D
def dmp_prs_resultant(f, g, u, K): """ Resultant algorithm in `K[X]` using subresultant PRS. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_prs_resultant >>> f = ZZ.map([[3, 0], [], [-1, 0, 0, -4]]) >>> g = ZZ.map([[1], [1, 0, 0, 0], [-9]]) >>> a = ZZ.map([[3, 0, 0, 0, 0], [1, 0, -27, 4]]) >>> b = ZZ.map([[-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]]) >>> dmp_prs_resultant(f, g, 1, ZZ) == (b[0], [f, g, a, b]) True """ if not u: return dup_prs_resultant(f, g, K) if dmp_zero_p(f, u) or dmp_zero_p(g, u): return (dmp_zero(u - 1), []) R, B, D = dmp_inner_subresultants(f, g, u, K) if dmp_degree(R[-1], u) > 0: return (dmp_zero(u - 1), R) if dmp_one_p(R[-2], u, K): return (dmp_LC(R[-1], K), R) s, i, v = 1, 1, u - 1 p = dmp_one(v, K) q = dmp_one(v, K) for b, d in list(zip(B, D))[:-1]: du = dmp_degree(R[i - 1], u) dv = dmp_degree(R[i], u) dw = dmp_degree(R[i + 1], u) if du % 2 and dv % 2: s = -s lc, i = dmp_LC(R[i], K), i + 1 p = dmp_mul(dmp_mul(p, dmp_pow(b, dv, v, K), v, K), dmp_pow(lc, du - dw, v, K), v, K) q = dmp_mul(q, dmp_pow(lc, dv * (1 + d), v, K), v, K) _, p, q = dmp_inner_gcd(p, q, v, K) if s < 0: p = dmp_neg(p, v, K) i = dmp_degree(R[-2], u) res = dmp_pow(dmp_LC(R[-1], K), i, v, K) res = dmp_quo(dmp_mul(res, p, v, K), q, v, K) return res, R
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 dmp_inner_subresultants(f, g, u, K): """ Subresultant PRS algorithm in `K[X]`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = 3*x**2*y - y**3 - 4 >>> g = x**2 + x*y**3 - 9 >>> a = 3*x*y**4 + y**3 - 27*y + 4 >>> b = -3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16 >>> prs = [f, g, a, b] >>> sres = [[1], [1], [3, 0, 0, 0, 0], [-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]] >>> R.dmp_inner_subresultants(f, g) == (prs, sres) True """ if not u: return dup_inner_subresultants(f, g, K) n = dmp_degree(f, u) m = dmp_degree(g, u) if n < m: f, g = g, f n, m = m, n if dmp_zero_p(f, u): return [], [] v = u - 1 if dmp_zero_p(g, u): return [f], [dmp_ground(K.one, v)] R = [f, g] d = n - m b = dmp_pow(dmp_ground(-K.one, v), d + 1, v, K) h = dmp_prem(f, g, u, K) h = dmp_mul_term(h, b, 0, u, K) lc = dmp_LC(g, K) c = dmp_pow(lc, d, v, K) S = [dmp_ground(K.one, v), c] c = dmp_neg(c, v, K) while not dmp_zero_p(h, u): k = dmp_degree(h, u) R.append(h) f, g, m, d = g, h, k, m - k b = dmp_mul(dmp_neg(lc, v, K), dmp_pow(c, d, v, K), v, K) h = dmp_prem(f, g, u, K) h = [ dmp_quo(ch, b, v, K) for ch in h ] lc = dmp_LC(g, K) if d > 1: p = dmp_pow(dmp_neg(lc, v, K), d, v, K) q = dmp_pow(c, d - 1, v, K) c = dmp_quo(p, q, v, K) else: c = dmp_neg(lc, v, K) S.append(dmp_neg(c, v, K)) return R, S
def mul(f, g): """Multiply two multivariate polynomials `f` and `g`. """ lev, dom, per, F, G = f.unify(g) return per(dmp_mul(F, G, lev, dom))
def dmp_zz_modular_resultant(f, g, p, u, K): """ Compute resultant of `f` and `g` modulo a prime `p`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = x + y + 2 >>> g = 2*x*y + x + 3 >>> R.dmp_zz_modular_resultant(f, g, 5) -2*y**2 + 1 """ if not u: return gf_int(dup_prs_resultant(f, g, K)[0] % p, p) v = u - 1 n = dmp_degree(f, u) m = dmp_degree(g, u) N = dmp_degree_in(f, 1, u) M = dmp_degree_in(g, 1, u) B = n*M + m*N D, a = [K.one], -K.one r = dmp_zero(v) while dup_degree(D) <= B: while True: a += K.one if a == p: raise HomomorphismFailed('no luck') F = dmp_eval_in(f, gf_int(a, p), 1, u, K) if dmp_degree(F, v) == n: G = dmp_eval_in(g, gf_int(a, p), 1, u, K) if dmp_degree(G, v) == m: break R = dmp_zz_modular_resultant(F, G, p, v, K) e = dmp_eval(r, a, v, K) if not v: R = dup_strip([R]) e = dup_strip([e]) else: R = [R] e = [e] d = K.invert(dup_eval(D, a, K), p) d = dup_mul_ground(D, d, K) d = dmp_raise(d, v, 0, K) c = dmp_mul(d, dmp_sub(R, e, v, K), v, K) r = dmp_add(r, c, v, K) r = dmp_ground_trunc(r, p, v, K) D = dup_mul(D, [K.one, -a], K) D = dup_trunc(D, p, K) return r
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 dmp_inner_subresultants(f, g, u, K): """ Subresultant PRS algorithm in `K[X]`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = 3*x**2*y - y**3 - 4 >>> g = x**2 + x*y**3 - 9 >>> a = 3*x*y**4 + y**3 - 27*y + 4 >>> b = -3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16 >>> prs = [f, g, a, b] >>> beta = [[-1], [1], [9, 0, 0, 0, 0, 0, 0, 0, 0]] >>> delta = [0, 1, 1] >>> R.dmp_inner_subresultants(f, g) == (prs, beta, delta) True """ if not u: return dup_inner_subresultants(f, g, K) n = dmp_degree(f, u) m = dmp_degree(g, u) if n < m: f, g = g, f n, m = m, n R = [f, g] d = n - m v = u - 1 b = dmp_pow(dmp_ground(-K.one, v), d + 1, v, K) c = dmp_ground(-K.one, v) B, D = [b], [d] if dmp_zero_p(f, u) or dmp_zero_p(g, u): return R, B, D h = dmp_prem(f, g, u, K) h = dmp_mul_term(h, b, 0, u, K) while not dmp_zero_p(h, u): k = dmp_degree(h, u) R.append(h) lc = dmp_LC(g, K) p = dmp_pow(dmp_neg(lc, v, K), d, v, K) if not d: q = c else: q = dmp_pow(c, d - 1, v, K) c = dmp_quo(p, q, v, K) b = dmp_mul(dmp_neg(lc, v, K), dmp_pow(c, m - k, v, K), v, K) f, g, m, d = g, h, k, m - k B.append(b) D.append(d) h = dmp_prem(f, g, u, K) h = [ dmp_quo(ch, b, v, K) for ch in h ] return R, B, D
def dmp_zz_diophantine(F, c, A, d, p, u, K): """Wang/EEZ: Solve multivariate Diophantine equations. """ if not A: S = [ [] for _ in F ] n = dup_degree(c) for i, coeff in enumerate(c): if not coeff: continue T = dup_zz_diophantine(F, n-i, p, K) for j, (s, t) in enumerate(zip(S, T)): t = dup_mul_ground(t, coeff, K) S[j] = dup_trunc(dup_add(s, t, K), p, K) else: n = len(A) e = dmp_expand(F, u, K) a, A = A[-1], A[:-1] B, G = [], [] for f in F: B.append(dmp_quo(e, f, u, K)) G.append(dmp_eval_in(f, a, n, u, K)) C = dmp_eval_in(c, a, n, u, K) v = u - 1 S = dmp_zz_diophantine(G, C, A, d, p, v, K) S = [ dmp_raise(s, 1, v, K) for s in S ] for s, b in zip(S, B): c = dmp_sub_mul(c, s, b, u, K) c = dmp_ground_trunc(c, p, u, K) m = dmp_nest([K.one, -a], n, K) M = dmp_one(n, K) for k in xrange(0, d): if dmp_zero_p(c, u): break M = dmp_mul(M, m, u, K) C = dmp_diff_eval_in(c, k+1, a, n, u, K) if not dmp_zero_p(C, v): C = dmp_quo_ground(C, K.factorial(k+1), v, K) T = dmp_zz_diophantine(G, C, A, d, p, v, K) for i, t in enumerate(T): T[i] = dmp_mul(dmp_raise(t, 1, v, K), M, u, K) for i, (s, t) in enumerate(zip(S, T)): S[i] = dmp_add(s, t, u, K) for t, b in zip(T, B): c = dmp_sub_mul(c, t, b, u, K) c = dmp_ground_trunc(c, p, u, K) S = [ dmp_ground_trunc(s, p, u, K) for s in S ] return S
def dmp_zz_diophantine(F, c, A, d, p, u, K): """Wang/EEZ: Solve multivariate Diophantine equations. """ if not A: S = [[] for _ in F] n = dup_degree(c) for i, coeff in enumerate(c): if not coeff: continue T = dup_zz_diophantine(F, n - i, p, K) for j, (s, t) in enumerate(zip(S, T)): t = dup_mul_ground(t, coeff, K) S[j] = dup_trunc(dup_add(s, t, K), p, K) else: n = len(A) e = dmp_expand(F, u, K) a, A = A[-1], A[:-1] B, G = [], [] for f in F: B.append(dmp_quo(e, f, u, K)) G.append(dmp_eval_in(f, a, n, u, K)) C = dmp_eval_in(c, a, n, u, K) v = u - 1 S = dmp_zz_diophantine(G, C, A, d, p, v, K) S = [dmp_raise(s, 1, v, K) for s in S] for s, b in zip(S, B): c = dmp_sub_mul(c, s, b, u, K) c = dmp_ground_trunc(c, p, u, K) m = dmp_nest([K.one, -a], n, K) M = dmp_one(n, K) for k in xrange(0, d): if dmp_zero_p(c, u): break M = dmp_mul(M, m, u, K) C = dmp_diff_eval_in(c, k + 1, a, n, u, K) if not dmp_zero_p(C, v): C = dmp_quo_ground(C, K.factorial(k + 1), v, K) T = dmp_zz_diophantine(G, C, A, d, p, v, K) for i, t in enumerate(T): T[i] = dmp_mul(dmp_raise(t, 1, v, K), M, u, K) for i, (s, t) in enumerate(zip(S, T)): S[i] = dmp_add(s, t, u, K) for t, b in zip(T, B): c = dmp_sub_mul(c, t, b, u, K) c = dmp_ground_trunc(c, p, u, K) S = [dmp_ground_trunc(s, p, u, K) for s in S] return S
def dmp_prs_resultant(f, g, u, K): """ Resultant algorithm in `K[X]` using subresultant PRS. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = 3*x**2*y - y**3 - 4 >>> g = x**2 + x*y**3 - 9 >>> a = 3*x*y**4 + y**3 - 27*y + 4 >>> b = -3*y**10 - 12*y**7 + y**6 - 54*y**4 + 8*y**3 + 729*y**2 - 216*y + 16 >>> res, prs = R.dmp_prs_resultant(f, g) >>> res == b # resultant has n-1 variables False >>> res == b.drop(x) True >>> prs == [f, g, a, b] True """ if not u: return dup_prs_resultant(f, g, K) if dmp_zero_p(f, u) or dmp_zero_p(g, u): return (dmp_zero(u - 1), []) R, B, D = dmp_inner_subresultants(f, g, u, K) if dmp_degree(R[-1], u) > 0: return (dmp_zero(u - 1), R) if dmp_one_p(R[-2], u, K): return (dmp_LC(R[-1], K), R) s, i, v = 1, 1, u - 1 p = dmp_one(v, K) q = dmp_one(v, K) for b, d in list(zip(B, D))[:-1]: du = dmp_degree(R[i - 1], u) dv = dmp_degree(R[i ], u) dw = dmp_degree(R[i + 1], u) if du % 2 and dv % 2: s = -s lc, i = dmp_LC(R[i], K), i + 1 p = dmp_mul(dmp_mul(p, dmp_pow(b, dv, v, K), v, K), dmp_pow(lc, du - dw, v, K), v, K) q = dmp_mul(q, dmp_pow(lc, dv*(1 + d), v, K), v, K) _, p, q = dmp_inner_gcd(p, q, v, K) if s < 0: p = dmp_neg(p, v, K) i = dmp_degree(R[-2], u) res = dmp_pow(dmp_LC(R[-1], K), i, v, K) res = dmp_quo(dmp_mul(res, p, v, K), q, v, K) return res, R
def dmp_prs_resultant(f, g, u, K): """ Resultant algorithm in ``K[X]`` using subresultant PRS. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_prs_resultant >>> f = ZZ.map([[3, 0], [], [-1, 0, 0, -4]]) >>> g = ZZ.map([[1], [1, 0, 0, 0], [-9]]) >>> a = ZZ.map([[3, 0, 0, 0, 0], [1, 0, -27, 4]]) >>> b = ZZ.map([[-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]]) >>> dmp_prs_resultant(f, g, 1, ZZ) == (b[0], [f, g, a, b]) True """ if not u: return dup_prs_resultant(f, g, K) if dmp_zero_p(f, u) or dmp_zero_p(g, u): return (dmp_zero(u-1), []) R, B, D = dmp_inner_subresultants(f, g, u, K) if dmp_degree(R[-1], u) > 0: return (dmp_zero(u-1), R) if dmp_one_p(R[-2], u, K): return (dmp_LC(R[-1], K), R) s, i, v = 1, 1, u-1 p = dmp_one(v, K) q = dmp_one(v, K) for b, d in zip(B, D)[:-1]: du = dmp_degree(R[i-1], u) dv = dmp_degree(R[i ], u) dw = dmp_degree(R[i+1], u) if du % 2 and dv % 2: s = -s lc, i = dmp_LC(R[i], K), i+1 p = dmp_mul(dmp_mul(p, dmp_pow(b, dv, v, K), v, K), dmp_pow(lc, du-dw, v, K), v, K) q = dmp_mul(q, dmp_pow(lc, dv*(1+d), v, K), v, K) _, p, q = dmp_inner_gcd(p, q, v, K) if s < 0: p = dmp_neg(p, v, K) i = dmp_degree(R[-2], u) res = dmp_pow(dmp_LC(R[-1], K), i, v, K) res = dmp_exquo(dmp_mul(res, p, v, K), q, v, K) return res, R
def dmp_zz_modular_resultant(f, g, p, u, K): """ Compute resultant of ``f`` and ``g`` modulo a prime ``p``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_zz_modular_resultant >>> f = ZZ.map([[1], [1, 2]]) >>> g = ZZ.map([[2, 1], [3]]) >>> dmp_zz_modular_resultant(f, g, ZZ(5), 1, ZZ) [-2, 0, 1] """ if not u: return gf_int(dup_prs_resultant(f, g, K)[0] % p, p) v = u - 1 n = dmp_degree(f, u) m = dmp_degree(g, u) N = dmp_degree_in(f, 1, u) M = dmp_degree_in(g, 1, u) B = n*M + m*N D, a = [K.one], -K.one r = dmp_zero(v) while dup_degree(D) <= B: while True: a += K.one if a == p: raise HomomorphismFailed('no luck') F = dmp_eval_in(f, gf_int(a, p), 1, u, K) if dmp_degree(F, v) == n: G = dmp_eval_in(g, gf_int(a, p), 1, u, K) if dmp_degree(G, v) == m: break R = dmp_zz_modular_resultant(F, G, p, v, K) e = dmp_eval(r, a, v, K) if not v: R = dup_strip([R]) e = dup_strip([e]) else: R = [R] e = [e] d = K.invert(dup_eval(D, a, K), p) d = dup_mul_ground(D, d, K) d = dmp_raise(d, v, 0, K) c = dmp_mul(d, dmp_sub(R, e, v, K), v, K) r = dmp_add(r, c, v, K) r = dmp_ground_trunc(r, p, v, K) D = dup_mul(D, [K.one, -a], K) D = dup_trunc(D, p, K) return r
def test_dmp_expand(): assert dmp_expand((), 1, ZZ) == [[1]] assert dmp_expand(([[1],[2],[3]], [[1],[2]], [[7],[5],[4],[3]]), 1, ZZ) == \ dmp_mul([[1],[2],[3]], dmp_mul([[1],[2]], [[7],[5],[4],[3]], 1, ZZ), 1, ZZ)
def dmp_inner_subresultants(f, g, u, K): """ Subresultant PRS algorithm in ``K[X]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dmp_inner_subresultants >>> f = ZZ.map([[3, 0], [], [-1, 0, 0, -4]]) >>> g = ZZ.map([[1], [1, 0, 0, 0], [-9]]) >>> a = [[3, 0, 0, 0, 0], [1, 0, -27, 4]] >>> b = [[-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]] >>> R = ZZ.map([f, g, a, b]) >>> B = ZZ.map([[-1], [1], [9, 0, 0, 0, 0, 0, 0, 0, 0]]) >>> D = ZZ.map([0, 1, 1]) >>> dmp_inner_subresultants(f, g, 1, ZZ) == (R, B, D) True """ if not u: return dup_inner_subresultants(f, g, K) n = dmp_degree(f, u) m = dmp_degree(g, u) if n < m: f, g = g, f n, m = m, n R = [f, g] d = n - m v = u - 1 b = dmp_pow(dmp_ground(-K.one, v), d+1, v, K) c = dmp_ground(-K.one, v) B, D = [b], [d] if dmp_zero_p(f, u) or dmp_zero_p(g, u): return R, B, D h = dmp_prem(f, g, u, K) h = dmp_mul_term(h, b, 0, u, K) while not dmp_zero_p(h, u): k = dmp_degree(h, u) R.append(h) lc = dmp_LC(g, K) p = dmp_pow(dmp_neg(lc, v, K), d, v, K) if not d: q = c else: q = dmp_pow(c, d-1, v, K) c = dmp_exquo(p, q, v, K) b = dmp_mul(dmp_neg(lc, v, K), dmp_pow(c, m-k, v, K), v, K) f, g, m, d = g, h, k, m-k B.append(b) D.append(d) h = dmp_prem(f, g, u, K) h = [ dmp_exquo(ch, b, v, K) for ch in h ] return R, B, D