def dup_primitive_prs(f, g, K): """ Primitive polynomial remainder sequence (PRS) in `K[x]`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> f = x**8 + x**6 - 3*x**4 - 3*x**3 + 8*x**2 + 2*x - 5 >>> g = 3*x**6 + 5*x**4 - 4*x**2 - 9*x + 21 >>> prs = R.dup_primitive_prs(f, g) >>> prs[0] x**8 + x**6 - 3*x**4 - 3*x**3 + 8*x**2 + 2*x - 5 >>> prs[1] 3*x**6 + 5*x**4 - 4*x**2 - 9*x + 21 >>> prs[2] -5*x**4 + x**2 - 3 >>> prs[3] 13*x**2 + 25*x - 49 >>> prs[4] 4663*x - 6150 >>> prs[5] 1 """ prs = [f, g] _, h = dup_primitive(dup_prem(f, g, K), K) while h: prs.append(h) f, g = g, h _, h = dup_primitive(dup_prem(f, g, K), K) return prs
def dup_primitive_prs(f, g, K): """ Primitive polynomial remainder sequence (PRS) in `K[x]`. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dup_primitive_prs >>> f = ZZ.map([1, 0, 1, 0, -3, -3, 8, 2, -5]) >>> g = ZZ.map([3, 0, 5, 0, -4, -9, 21]) >>> prs = dup_primitive_prs(f, g, ZZ) >>> prs[0] [1, 0, 1, 0, -3, -3, 8, 2, -5] >>> prs[1] [3, 0, 5, 0, -4, -9, 21] >>> prs[2] [-5, 0, 1, 0, -3] >>> prs[3] [13, 25, -49] >>> prs[4] [4663, -6150] >>> prs[5] [1] """ prs = [f, g] _, h = dup_primitive(dup_prem(f, g, K), K) while h: prs.append(h) f, g = g, h _, h = dup_primitive(dup_prem(f, g, K), K) return prs
def test_dup_pdiv(): f = dup_normal([3,1,1,5], ZZ) g = dup_normal([5,-3,1], ZZ) q = dup_normal([15, 14], ZZ) r = dup_normal([52, 111], ZZ) assert dup_pdiv(f, g, ZZ) == (q, r) assert dup_pquo(f, g, ZZ) == q assert dup_prem(f, g, ZZ) == r raises(ExactQuotientFailed, lambda: dup_pexquo(f, g, ZZ)) f = dup_normal([3,1,1,5], QQ) g = dup_normal([5,-3,1], QQ) q = dup_normal([15, 14], QQ) r = dup_normal([52, 111], QQ) assert dup_pdiv(f, g, QQ) == (q, r) assert dup_pquo(f, g, QQ) == q assert dup_prem(f, g, QQ) == r raises(ExactQuotientFailed, lambda: dup_pexquo(f, g, QQ))
def dup_inner_subresultants(f, g, K): """ Subresultant PRS algorithm in ``K[x]``. Computes the subresultant polynomial remainder sequence (PRS) of ``f`` and ``g``, and the values for $\\beta_i$ and $\\delta_i$. The last two sequences of values are necessary for computing the resultant in :func:`dup_prs_resultant`. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dup_inner_subresultants >>> f = ZZ.map([1, 0, 1]) >>> g = ZZ.map([1, 0, -1]) >>> dup_inner_subresultants(f, g, ZZ) ([[1, 0, 1], [1, 0, -1], [-2]], [-1, -1], [0, 2]) """ n = dup_degree(f) m = dup_degree(g) if n < m: f, g = g, f n, m = m, n R = [f, g] d = n - m b = (-K.one)**(d+1) c = -K.one B, D = [b], [d] if not f or not g: return R, B, D h = dup_prem(f, g, K) h = dup_mul_ground(h, b, K) while h: k = dup_degree(h) R.append(h) lc = dup_LC(g, K) if not d: q = c else: q = c**(d-1) c = K.exquo((-lc)**d, q) b = -lc * c**(m-k) f, g, m, d = g, h, k, m-k B.append(b) D.append(d) h = dup_prem(f, g, K) h = dup_exquo_ground(h, b, K) return R, B, D
def dup_inner_subresultants(f, g, K): """ Subresultant PRS algorithm in `K[x]`. Computes the subresultant polynomial remainder sequence (PRS) and the non-zero scalar subresultants of `f` and `g`. By [1] Thm. 3, these are the constants '-c' (- to optimize computation of sign). The first subdeterminant is set to 1 by convention to match the polynomial and the scalar subdeterminants. If 'deg(f) < deg(g)', the subresultants of '(g,f)' are computed. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_inner_subresultants(x**2 + 1, x**2 - 1) ([x**2 + 1, x**2 - 1, -2], [1, 1, 4]) References ========== [1] W.S. Brown, The Subresultant PRS Algorithm. ACM Transaction of Mathematical Software 4 (1978) 237-249 """ n = dup_degree(f) m = dup_degree(g) if n < m: f, g = g, f n, m = m, n if not f: return [], [] if not g: return [f], [K.one] R = [f, g] d = n - m b = (-K.one)**(d + 1) h = dup_prem(f, g, K) h = dup_mul_ground(h, b, K) lc = dup_LC(g, K) c = lc**d # Conventional first scalar subdeterminant is 1 S = [K.one, c] c = -c while h: k = dup_degree(h) R.append(h) f, g, m, d = g, h, k, m - k b = -lc * c**d h = dup_prem(f, g, K) h = dup_quo_ground(h, b, K) lc = dup_LC(g, K) if d > 1: # abnormal case q = c**(d - 1) c = K.quo((-lc)**d, q) else: c = -lc S.append(-c) return R, S
def dup_inner_subresultants(f, g, K): """ Subresultant PRS algorithm in `K[x]`. Computes the subresultant polynomial remainder sequence (PRS) of `f` and `g`, and the values for `\beta_i` and `\delta_i`. The last two sequences of values are necessary for computing the resultant in :func:`dup_prs_resultant`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_inner_subresultants(x**2 + 1, x**2 - 1) ([x**2 + 1, x**2 - 1, -2], [-1, -1], [0, 2]) """ n = dup_degree(f) m = dup_degree(g) if n < m: f, g = g, f n, m = m, n R = [f, g] d = n - m b = (-K.one)**(d + 1) c = -K.one B, D = [b], [d] if not f or not g: return R, B, D h = dup_prem(f, g, K) h = dup_mul_ground(h, b, K) while h: k = dup_degree(h) R.append(h) lc = dup_LC(g, K) if not d: q = c else: q = c**(d - 1) c = K.quo((-lc)**d, q) b = -lc * c**(m - k) f, g, m, d = g, h, k, m - k B.append(b) D.append(d) h = dup_prem(f, g, K) h = dup_quo_ground(h, b, K) return R, B, D
def dup_inner_subresultants(f, g, K): """ Subresultant PRS algorithm in ``K[x]``. Computes the subresultant polynomial remainder sequence (PRS) of ``f`` and ``g``, and the values for $\\beta_i$ and $\\delta_i$. The last two sequences of values are necessary for computing the resultant in :func:`dup_prs_resultant`. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.euclidtools import dup_inner_subresultants >>> f = ZZ.map([1, 0, 1]) >>> g = ZZ.map([1, 0, -1]) >>> dup_inner_subresultants(f, g, ZZ) ([[1, 0, 1], [1, 0, -1], [-2]], [-1, -1], [0, 2]) """ n = dup_degree(f) m = dup_degree(g) if n < m: f, g = g, f n, m = m, n R = [f, g] d = n - m b = (-K.one)**(d + 1) c = -K.one B, D = [b], [d] if not f or not g: return R, B, D h = dup_prem(f, g, K) h = dup_mul_ground(h, b, K) while h: k = dup_degree(h) R.append(h) lc = dup_LC(g, K) if not d: q = c else: q = c**(d - 1) c = K.quo((-lc)**d, q) b = -lc * c**(m - k) f, g, m, d = g, h, k, m - k B.append(b) D.append(d) h = dup_prem(f, g, K) h = dup_quo_ground(h, b, K) return R, B, D