Exemplo n.º 1
0
def sqf_part(f, var=None, order=None):
    """Returns the square-free part of f.

    Usage:
    ======
        Computes the square-free part of f.

        The input is assumed to be a univariate polynomial, either as
        a SymPy expression or an instance of Polynomial. In the first
        case, you can optionally specify the variables and monomial
        order with the arguments 'var' and 'order'.

        The result is returned as an instance of Polynomial.
    
    Examples:
    =========
        >>> x = Symbol('x')
        >>> print sqf_part(2*x**3 + 2*x**2)
        2*x + 2*x**2

    References:
    ===========
        Gathen, Gerhard: Modern Computer Algebra,
        Cambridge University Press, 1. edition, p. 370

    Also see L{sqf}.

    """

    if not isinstance(f, Polynomial):
        f = Polynomial(f, var=var, order=order)

    # The gcd of f with its derivative is the multiple part.
    ff = div_.gcd(f, f.diff(f.var[0]))
    return div_.div(f, ff)[0]
Exemplo n.º 2
0
def gcd(f, g, var=None, order=None, coeff=None):
    """Greatest common divisor of two polynomials.

    A thin wrapper returning a SymPy expression from L{div_.gcd}'s
    result after checking the coefficients' type.

    """

    # First check if the polynomials have integer coefficients.
    if coeff is None:
        coeff_f = coeff_ring(get_numbers(f))
        coeff_g = coeff_ring(get_numbers(g))
        if coeff_f == 'int' and coeff_g == 'int':
            coeff = 'int'
        if var is not None:
            if isinstance(var, Symbol):
                var = [var]
            if [v for v in f.atoms(type=Symbol).union(g.atoms(type=Symbol))
                if v not in var]:
                coeff = 'sym'

    return div_.gcd(f, g, var, order, coeff).sympy_expr
Exemplo n.º 3
0
def sqf(f, var=None, order=None, coeff=None):
    """Square-free decomposition.

    Usage:
    ======
        Computes a decomposition of f in a1 * a2**2 * ... * an**n,
        where the ai are pairwise prime and square-free polynomials.

        The input is assumed to be a univariate polynomial, either as
        a SymPy expression or an instance of Polynomial. In the first
        case, you can optionally specify the variables and monomial
        order with the arguments 'var' and 'order'.

        If the argument 'coeff' is set to 'int', the constant factors
        are redistributed to the different ai, so that they have
        integer coefficients. Otherwise, they are made monic.

        A list is returned, with an instance of Polynomial at each
        index, which represents the multiplicity (except beginning
        with 1 instead of 0).
    
    Examples:
    =========
        >>> x = Symbol('x')
        >>> a = sqf(3 - 12*x - 4*x**3 + 4*x**4 + 13*x**2)
        >>> for i, f in enumerate(a): print (i + 1), f
        1 12 + 4*x**2
        2 (-1/2) + x
        >>> b = sqf(3 - 12*x - 4*x**3 + 4*x**4 + 13*x**2, coeff='int')
        >>> for i, f in enumerate(b): print (i + 1), f
        1 3 + x**2
        2 (-1) + 2*x
        
    References:
    ===========
        Gathen, Gerhard: Modern Computer Algebra,
        Cambridge University Press, 1. edition, p. 371

    Also see L{sqf_part}, L{factor}.

    """

    if not isinstance(f, Polynomial):
        f = Polynomial(f, var=var, order=order)

    # Check for constant polynomials:
    if f.var == [] or f.coeffs[0][1] is S.Zero:
        return [f]

    f = [f]
    while f[-1].coeffs[0][1] is not S.Zero:
        f.append(div_.gcd(f[-1], f[-1].diff(f[-1].var[0])))
    g = []
    for i in range(1, len(f)):
        g.append(div_.div(f[i - 1], f[i])[0])
    a = []
    for i in range(0, len(g) - 1):
        a.append(div_.div(g[i], g[i + 1])[0])
    a.append(g[-1])

    if coeff == "int":  # Redistribute the constants.
        ca = int(a[0].content())
        c = ca
        for i, p in enumerate(a[1:]):
            # Compute lcm of denominators in coeffs:
            l, a[i + 1] = p.as_integer()
            c /= int(l) ** (i + 2)
        ca = Integer(ca / c)
        a[0] = Polynomial(coeffs=tuple([(t[0] / ca,) + t[1:] for t in a[0].coeffs]), var=a[0].var, order=a[0].order)
    return a