Ejemplo n.º 1
0
def poly_sqf(f, *symbols):
    """Compute square-free decomposition of an univariate polynomial.

       Given an univariate polynomial f over an unique factorization domain
       returns tuple (f_1, f_2, ..., f_n),  where all  A_i are co-prime and
       square-free polynomials and f = f_1 * f_2**2 * ... * f_n**n.

       >>> from sympy import *
       >>> x,y = symbols('xy')

       >>> p, q = poly_sqf(x*(x+1)**2, x)

       >>> p.as_basic()
       x
       >>> q.as_basic()
       1 + x

       For more information on the implemented algorithm refer to:

       [1] M. Bronstein, Symbolic Integration I: Transcendental
           Functions, Second Edition, Springer-Verlang, 2005

       [2] J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
           Second Edition, Cambridge University Press, 2003

    """
    if not isinstance(f, Poly):
        f = Poly(f, *symbols)
    elif symbols:
        raise SymbolsError("Redundant symbols were given")

    if f.is_multivariate:
        raise MultivariatePolyError(f)

    coeff, f = f.as_primitive()

    sqf = []

    h = f.diff()

    g = poly_gcd(f, h)

    p = poly_div(f, g)[0]
    q = poly_div(h, g)[0]

    p, q = poly_reduce(p, q)

    while True:
        h = q - p.diff()

        if h.is_zero:
            break

        g = poly_gcd(p, h)

        sqf.append(g)

        p = poly_div(p, g)[0]
        q = poly_div(h, g)[0]

        p, q = poly_reduce(p, q)

    sqf.append(p)

    head, tail = sqf[0], sqf[1:]
    head = head.mul_term(coeff)

    return [head] + tail
Ejemplo n.º 2
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.º 3
0
def poly_lcm(f, g, *symbols):
    """Computes least common multiple of two polynomials.

       Given two univariate polynomials,  the LCM is computed  via
       f*g = gcd(f, g)*lcm(f, g) formula. In multivariate case, we
       compute the unique generator of the intersection of the two
       ideals, generated by f and g.  This is done by computing  a
       Groebner basis, with respect to any lexicographic ordering,
       of t*f and (1 - t)*g, where t is an unrelated symbol and
       filtering out solution that does not contain t.

       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_monomial and g.is_monomial:
        monom = monomial_lcm(f.LM, g.LM)

        fc, gc = f.LC, g.LC

        if fc.is_Rational and gc.is_Rational:
            coeff = Integer(ilcm(fc.p, gc.p))
        else:
            coeff = S.One

        return Poly((coeff, monom), *symbols, **flags)

    fc, f = f.as_primitive()
    gc, g = g.as_primitive()

    lcm = ilcm(int(fc), int(gc))

    if f.is_multivariate:
        t = Symbol('t', dummy=True)
        lex = {'order': 'lex'}

        f_monoms = [(1, ) + monom for monom in f.monoms]

        F = Poly((f.coeffs, f_monoms), t, *symbols, **lex)

        g_monoms = [ (0,) + monom for monom in g.monoms ] + \
                   [ (1,) + monom for monom in g.monoms ]

        g_coeffs = list(g.coeffs) + [-coeff for coeff in g.coeffs]
        G = Poly(dict(zip(g_monoms, g_coeffs)), t, *symbols, **lex)

        def independent(h):
            return all(not monom[0] for monom in h.monoms)

        H = [h for h in poly_groebner((F, G)) if independent(h)]

        if lcm != 1:
            h_coeffs = [coeff * lcm for coeff in H[0].coeffs]
        else:
            h_coeffs = H[0].coeffs

        h_monoms = [monom[1:] for monom in H[0].monoms]

        return Poly(dict(zip(h_monoms, h_coeffs)), *symbols, **flags)
    else:
        h = poly_div(f * g, poly_gcd(f, g))[0]

        if lcm != 1:
            return h.mul_term(lcm / h.LC)
        else:
            return h.as_monic()
Ejemplo n.º 4
0
def poly_sqf(f, *symbols):
    """Compute square-free decomposition of an univariate polynomial.

       Given an univariate polynomial f over an unique factorization domain
       returns tuple (f_1, f_2, ..., f_n),  where all  A_i are co-prime and
       square-free polynomials and f = f_1 * f_2**2 * ... * f_n**n.

       >>> from sympy import *
       >>> x,y = symbols('xy')

       >>> p, q = poly_sqf(x*(x+1)**2, x)

       >>> p.as_basic()
       x
       >>> q.as_basic()
       1 + x

       For more information on the implemented algorithm refer to:

       [1] M. Bronstein, Symbolic Integration I: Transcendental
           Functions, Second Edition, Springer-Verlang, 2005

       [2] J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
           Second Edition, Cambridge University Press, 2003

    """
    if not isinstance(f, Poly):
        f = Poly(f, *symbols)
    elif symbols:
        raise SymbolsError("Redundant symbols were given")

    if f.is_multivariate:
        raise MultivariatePolyError(f)

    coeff, f = f.as_primitive()

    sqf = []

    h = f.diff()

    g = poly_gcd(f, h)

    p = poly_div(f, g)[0]
    q = poly_div(h, g)[0]

    p, q = poly_reduce(p, q)

    while True:
        h = q - p.diff()

        if h.is_zero:
            break

        g = poly_gcd(p, h)

        sqf.append(g)

        p = poly_div(p, g)[0]
        q = poly_div(h, g)[0]

        p, q = poly_reduce(p, q)

    sqf.append(p)

    head, tail = sqf[0], sqf[1:]
    head = head.mul_term(coeff)

    return [head] + tail
Ejemplo n.º 5
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()
Ejemplo n.º 6
0
def poly_lcm(f, g, *symbols):
    """Computes least common multiple of two polynomials.

       Given two univariate polynomials,  the LCM is computed  via
       f*g = gcd(f, g)*lcm(f, g) formula. In multivariate case, we
       compute the unique generator of the intersection of the two
       ideals, generated by f and g.  This is done by computing  a
       Groebner basis, with respect to any lexicographic ordering,
       of t*f and (1 - t)*g, where t is an unrelated symbol and
       filtering out solution that does not contain t.

       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_monomial and g.is_monomial:
        monom = monomial_lcm(f.LM, g.LM)

        fc, gc = f.LC, g.LC

        if fc.is_Rational and gc.is_Rational:
            coeff = Integer(ilcm(fc.p, gc.p))
        else:
            coeff = S.One

        return Poly((coeff, monom), *symbols, **flags)

    fc, f = f.as_primitive()
    gc, g = g.as_primitive()

    lcm = ilcm(int(fc), int(gc))

    if f.is_multivariate:
        t = Symbol('t', dummy=True)
        lex = { 'order' : 'lex' }

        f_monoms = [ (1,) + monom for monom in f.monoms ]

        F = Poly((f.coeffs, f_monoms), t, *symbols, **lex)

        g_monoms = [ (0,) + monom for monom in g.monoms ] + \
                   [ (1,) + monom for monom in g.monoms ]

        g_coeffs = list(g.coeffs) + [ -coeff for coeff in g.coeffs ]
        G = Poly(dict(zip(g_monoms, g_coeffs)), t, *symbols, **lex)

        def independent(h):
            return all(not monom[0] for monom in h.monoms)

        H = [ h for h in poly_groebner((F, G)) if independent(h) ]

        if lcm != 1:
            h_coeffs = [ coeff*lcm for coeff in H[0].coeffs ]
        else:
            h_coeffs = H[0].coeffs

        h_monoms = [ monom[1:] for monom in H[0].monoms ]

        return Poly(dict(zip(h_monoms, h_coeffs)), *symbols, **flags)
    else:
        h = poly_div(f * g, poly_gcd(f, g))[0]

        if lcm != 1:
            return h.mul_term(lcm / h.LC)
        else:
            return h.as_monic()