def poly_discriminant(p, symbol):
    """
    Returns the discriminant of a polynomial with respect to symbol.

    The discriminant of a univariate polynomial p of degree n is defined as
    n**(n*(n-1)/2)/a_n*resultant(p, p'), where p' is the derivative of p and a_n
    is the leading coefficient of p.  Because the resultant of two polynomials
    vanishes identically whenever the two polynomials share a root, and a
    polynomial shares a root with its derivative if and only if the root is a
    repeated root, it follows that the discriminant of a polynomial vanishes
    identically if and only if the polynomial has a repeated root.

    See also:
    <http://en.wikipedia.org/wiki/Discriminant>

    Example:
    >>> from sympy import discriminant, Poly
    >>> from sympy.abc import a, b, c, x
    >>> discriminant(Poly(a*x**2 + b*x + c, x), x)
    -4*a*c + b**2
    >>> discriminant(Poly(2*x**5 + x**2 + 10, x), x)
    500004320
    >>> discriminant(Poly((x-1)*(x+1), x), x)
    4
    >>> discriminant(Poly((x-1)**2*(x+1), x), x)
    0

    """
    if not isinstance(p, Poly):
        p = Poly(p, symbol)
    if not p.is_univariate:
        # We need to make p univariate for poly_resultant to work
        p = Poly(p.as_basic(), symbol) # Is there a better way to do this?
    if p.degree == 0:
        return S.Zero
    return (S(int((-1)**((p.degree)*(S(p.degree) - 1)/2)))/p.lead_coeff*\
    poly_resultant(p, p.diff(symbol))).expand()
Exemple #2
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
Exemple #3
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