Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
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))
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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()