def poly_pdiv(f, g, *symbols): """Univariate polynomial pseudo-division with remainder. Given univariate polynomials f and g over an integral domain D[x] applying classical division algorithm to LC(g)**(d + 1) * f and g where d = max(-1, deg(f) - deg(g)), compute polynomials q and r such that LC(g)**(d + 1)*f = g*q + r and r = 0 or deg(r) < deg(g). Polynomials q and r are called the pseudo-quotient of f by g and the pseudo-remainder of f modulo g respectively. 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 q, r = Poly((), *symbols, **flags), f coeff, N = g.LC, f.degree - g.degree + 1 while not r.is_zero: M = r.degree - g.degree if M < 0: break else: T, N = (r.LC, (M, )), N - 1 q = q.mul_term(coeff).add_term(*T) r = r.mul_term(coeff) - g.mul_term(*T) return (q.mul_term(coeff**N), r.mul_term(coeff**N))
def poly_pdiv(f, g, *symbols): """Univariate polynomial pseudo-division with remainder. Given univariate polynomials f and g over an integral domain D[x] applying classical division algorithm to LC(g)**(d + 1) * f and g where d = max(-1, deg(f) - deg(g)), compute polynomials q and r such that LC(g)**(d + 1)*f = g*q + r and r = 0 or deg(r) < deg(g). Polynomials q and r are called the pseudo-quotient of f by g and the pseudo-remainder of f modulo g respectively. 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 q, r = Poly((), *symbols, **flags), f coeff, N = g.LC, f.degree - g.degree + 1 while not r.is_zero: M = r.degree - g.degree if M < 0: break else: T, N = (r.LC, (M,)), N - 1 q = q.mul_term(coeff).add_term(*T) r = r.mul_term(coeff)-g.mul_term(*T) return (q.mul_term(coeff**N), r.mul_term(coeff**N))
def poly_gcd(f, g, *symbols): """Compute greatest common divisor of two polynomials. Given two univariate polynomials, subresultants are used to compute the GCD. In multivariate case Groebner basis approach is used together with f*g = gcd(f, g)*lcm(f, g) well known formula. 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. 187 """ 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 if f.is_zero and g.is_zero: return f if f.is_constant: if f.is_zero: cont, g = g.as_primitive() return g.mul_term(cont / g.LC) if f.is_one: return f if g.is_constant: if g.is_zero: cont, f = f.as_primitive() return f.mul_term(cont / f.LC) if g.is_one: return g if f.is_monomial and g.is_monomial: monom = monomial_gcd(f.LM, g.LM) fc, gc = f.LC, g.LC if fc.is_Rational and gc.is_Rational: coeff = Integer(igcd(fc.p, gc.p)) else: coeff = S.One return Poly((coeff, monom), *symbols, **flags) cf, f = f.as_primitive() cg, g = g.as_primitive() gcd = igcd(int(cf), int(cg)) if f.is_multivariate: h = poly_div(f * g, poly_lcm(f, g))[0] else: h = poly_subresultants(f, g, res=False)[-1] if gcd != 1: return h.mul_term(gcd / h.LC) else: return h.as_monic()
def poly_gcd(f, g, *symbols): """Compute greatest common divisor of two polynomials. Given two univariate polynomials, subresultants are used to compute the GCD. In multivariate case Groebner basis approach is used together with f*g = gcd(f, g)*lcm(f, g) well known formula. 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. 187 """ 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 if f.is_zero and g.is_zero: return f if f.is_constant: if f.is_zero: cont, g = g.as_primitive() return g.mul_term(cont / g.LC) if f.is_one: return f if g.is_constant: if g.is_zero: cont, f = f.as_primitive() return f.mul_term(cont / f.LC) if g.is_one: return g if f.is_monomial and g.is_monomial: monom = monomial_gcd(f.LM, g.LM) fc, gc = f.LC, g.LC if fc.is_Rational and gc.is_Rational: coeff = Integer(igcd(fc.p, gc.p)) else: coeff = S.One return Poly((coeff, monom), *symbols, **flags) cf, f = f.as_primitive() cg, g = g.as_primitive() gcd = igcd(int(cf), int(cg)) if f.is_multivariate: h = poly_div(f*g, poly_lcm(f, g))[0] else: h = poly_subresultants(f, g)[-1] if gcd != 1: return h.mul_term(gcd / h.LC) else: return h.as_monic()