def poly_reduce(f, g, *symbols): """Removes common content from a pair of polynomials. >>> from sympy import * >>> x = Symbol('x') >>> f = Poly(2930944*x**6 + 2198208*x**4 + 549552*x**2 + 45796, x) >>> g = Poly(17585664*x**5 + 8792832*x**3 + 1099104*x, x) >>> F, G = poly_reduce(f, g) >>> F Poly(64*x**6 + 48*x**4 + 12*x**2 + 1, x) >>> G Poly(384*x**5 + 192*x**3 + 24*x, x) """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) fc = int(f.content) gc = int(g.content) cont = igcd(fc, gc) if cont != 1: f = f.div_term(cont) g = g.div_term(cont) return f, g
def poly_reduce(f, g, *symbols): """Removes common content from a pair of polynomials. >>> from sympy import * >>> x = Symbol('x') >>> f = Poly(2930944*x**6 + 2198208*x**4 + 549552*x**2 + 45796, x) >>> g = Poly(17585664*x**5 + 8792832*x**3 + 1099104*x, x) >>> F, G = poly_reduce(f, g) >>> F Poly(64*x**6 + 48*x**4 + 12*x**2 + 1, x) >>> G Poly(384*x**5 + 192*x**3 + 24*x, x) """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) fc = int(f.content) gc = int(g.content) cont = igcd(fc, gc) if cont != 1: f = f.div_term(cont) g = g.div_term(cont) return f, g
def poly_half_gcdex(f, g, *symbols): """Half extended Euclidean algorithm. Efficiently computes gcd(f, g) and one of the coefficients in extended Euclidean algorithm. Formally, given univariate polynomials f and g over an Euclidean domain, computes s and h, such that h = gcd(f, g) and s*f = h (mod g). For more information on the implemented algorithm refer to: [1] M. Bronstein, Symbolic Integration I: Transcendental Functions, Second Edition, Springer-Verlang, 2005 """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) if f.is_multivariate: raise MultivariatePolyError(f) symbols, flags = f.symbols, f.flags a = Poly(S.One, *symbols, **flags) b = Poly((), *symbols, **flags) while not g.is_zero: q, r = poly_div(f, g) f, g = g, r c = a - q * b a, b = b, c return a.div_term(f.LC), f.as_monic()
def poly_half_gcdex(f, g, *symbols): """Half extended Euclidean algorithm. Efficiently computes gcd(f, g) and one of the coefficients in extended Euclidean algorithm. Formally, given univariate polynomials f and g over an Euclidean domain, computes s and h, such that h = gcd(f, g) and s*f = h (mod g). For more information on the implemented algorithm refer to: [1] M. Bronstein, Symbolic Integration I: Transcendental Functions, Second Edition, Springer-Verlang, 2005 """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) if f.is_multivariate: raise MultivariatePolyError(f) symbols, flags = f.symbols, f.flags a = Poly(S.One, *symbols, **flags) b = Poly((), *symbols, **flags) while not g.is_zero: q, r = poly_div(f, g) f, g = g, r c = a - q*b a, b = b, c return a.div_term(f.LC), f.as_monic()
def poly_div(f, g, *symbols): """Generalized polynomial division with remainder. Given polynomial f and a set of polynomials g = (g_1, ..., g_n) compute a set of quotients q = (q_1, ..., q_n) and remainder r such that f = q_1*f_1 + ... + q_n*f_n + r, where r = 0 or r is a completely reduced polynomial with respect to g. In particular g can be a tuple, list or a singleton. All g_i and f can be given as Poly class instances or as expressions. For more information on the implemented algorithm refer to: [1] D. Cox, J. Little, D. O'Shea, Ideals, Varieties and Algorithms, Springer, Second Edition, 1997, pp. 62 [2] I.A. Ajwa, Z. Liu, P.S. Wang, Groebner Bases Algorithm, http://citeseer.ist.psu.edu/ajwa95grbner.html, 1995 """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) symbols, flags = f.symbols, f.flags r = Poly((), *symbols, **flags) if isinstance(g, Basic): if g.is_constant: if g.is_zero: raise ZeroDivisionError elif g.is_one: return f, r else: return f.div_term(g.LC), r if g.is_monomial: LC, LM = g.lead_term q_coeffs, q_monoms = [], [] r_coeffs, r_monoms = [], [] for coeff, monom in f.iter_terms(): quotient = monomial_div(monom, LM) if quotient is not None: coeff /= LC q_coeffs.append(Poly.cancel(coeff)) q_monoms.append(quotient) else: r_coeffs.append(coeff) r_monoms.append(monom) return (Poly((q_coeffs, q_monoms), *symbols, **flags), Poly((r_coeffs, r_monoms), *symbols, **flags)) g, q = [g], [r] else: q = [r] * len(g) while not f.is_zero: for i, h in enumerate(g): monom = monomial_div(f.LM, h.LM) if monom is not None: coeff = Poly.cancel(f.LC / h.LC) q[i] = q[i].add_term(coeff, monom) f -= h.mul_term(coeff, monom) break else: r = r.add_term(*f.LT) f = f.kill_lead_term() if len(q) != 1: return q, r else: return q[0], r
def poly_div(f, g, *symbols): """Generalized polynomial division with remainder. Given polynomial f and a set of polynomials g = (g_1, ..., g_n) compute a set of quotients q = (q_1, ..., q_n) and remainder r such that f = q_1*f_1 + ... + q_n*f_n + r, where r = 0 or r is a completely reduced polynomial with respect to g. In particular g can be a tuple, list or a singleton. All g_i and f can be given as Poly class instances or as expressions. For more information on the implemented algorithm refer to: [1] D. Cox, J. Little, D. O'Shea, Ideals, Varieties and Algorithms, Springer, Second Edition, 1997, pp. 62 [2] I.A. Ajwa, Z. Liu, P.S. Wang, Groebner Bases Algorithm, http://citeseer.ist.psu.edu/ajwa95grbner.html, 1995 """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) symbols, flags = f.symbols, f.flags r = Poly((), *symbols, **flags) if isinstance(g, Basic): if g.is_constant: if g.is_zero: raise ZeroDivisionError elif g.is_one: return f, r else: return f.div_term(g.LC), r if g.is_monomial: LC, LM = g.lead_term q_coeffs, q_monoms = [], [] r_coeffs, r_monoms = [], [] for coeff, monom in f.iter_terms(): quotient = monomial_div(monom, LM) if quotient is not None: coeff /= LC q_coeffs.append(Poly.cancel(coeff)) q_monoms.append(quotient) else: r_coeffs.append(coeff) r_monoms.append(monom) return (Poly((q_coeffs, q_monoms), *symbols, **flags), Poly((r_coeffs, r_monoms), *symbols, **flags)) g, q = [g], [r] else: q = [r] * len(g) while not f.is_zero: for i, h in enumerate(g): monom = monomial_div(f.LM, h.LM) if monom is not None: coeff = Poly.cancel(f.LC / h.LC) q[i] = q[i].add_term(coeff, monom) f -= h.mul_term(coeff, monom) break else: r = r.add_term(*f.LT) f = f.kill_lead_term() if len(q) != 1: return q, r else: return q[0], r