Esempio n. 1
0
def test_factor():
    assert factor(-2) == -2
    assert factor(-x) == -x

    assert factor(Rational(3, 8)*x**2 - Rational(3, 2)) == \
        Rational(3, 8)*((x - 2)*(x + 2))

    assert factor(x**3 - 1) == (x - 1)*(x**2 + x + 1)
    assert factor(x**3 - x) == x*(x - 1)*(x + 1)

    assert factor(x**2 + 2*x + 1) == (x + 1)**2
    assert factor(x**2 +   x - 2) == (x - 1)*(x + 2)

    assert factor(2*x**2 + 5*x + 2) == (x + 2)*(2*x + 1)

    assert factor(x**2 + y**2) == x**2 + y**2
    assert factor(x**5 - y**2) == x**5 - y**2

    assert factor(x*y + x*z + y*z) == x*y + x*z + y*z
    assert factor(x*y + x*z + x**2) == x*(x + y + z)

    assert poly_factors((a*x - b)**5, x) == \
        (1, [(Poly(a*x - b, x), 5)])

    assert poly_factors((a*x - b)**5, x, a) == \
        (1, [(Poly(x*a - b, x, a), 5)])

    assert poly_factors((a*x - b)**5, x, a, b) == \
        (1, [(Poly(x*a - b, x, a, b), 5)])

    assert poly_factors(-2*x**2 + x, x) == \
        (-1, [(Poly(x, x), 1),
              (Poly(2*x - 1, x), 1)])

    assert poly_factors(x**3 - 3*x**2 + 3*x - 1, x) == \
        (1, [(Poly(x - 1, x), 3)])

    assert poly_factors(x**6 - 1, x) == \
        (1, [(Poly(x - 1, x), 1),
             (Poly(x + 1, x), 1),
             (Poly(x**2 - x + 1, x), 1),
             (Poly(x**2 + x + 1, x), 1)])

    assert poly_factors(2*x**3*y - 2*a**2*x*y - 3*a**2*x**2 + 3*a**4, a, x, y) == \
        (1, [(Poly(a - x, a, x, y), 1),
             (Poly(a + x, a, x, y), 1),
             (Poly(3*a**2 - 2*x*y, a, x, y), 1)])

    assert poly_factors(x**20 - z**5*y**20, x, y, z) == \
        (1, [(Poly(-y**4*z + x**4, x, y, z), 1),
             (Poly(y**16*z**4 + x**4*y**12*z**3 + x**8*y**8*z**2 + x**12*y**4*z + x**16, x, y, z) , 1)])
Esempio n. 2
0
def test_factor():
    assert factor(-2) == -2
    assert factor(-x) == -x

    assert factor(Rational(3, 8)*x**2 - Rational(3, 2)) == \
        Rational(3, 8)*((x - 2)*(x + 2))

    assert factor(x**3 - 1) == (x - 1)*(x**2 + x + 1)
    assert factor(x**3 - x) == x*(x - 1)*(x + 1)

    assert factor(x**2 + 2*x + 1) == (x + 1)**2
    assert factor(x**2 +   x - 2) == (x - 1)*(x + 2)

    assert factor(2*x**2 + 5*x + 2) == (x + 2)*(2*x + 1)

    assert factor(x**2 + y**2) == x**2 + y**2
    assert factor(x**5 - y**2) == x**5 - y**2

    assert factor(x*y + x*z + y*z) == x*y + x*z + y*z
    assert factor(x*y + x*z + x**2) == x*(x + y + z)

    assert poly_factors((a*x - b)**5, x) == \
        (1, [(Poly(a*x - b, x), 5)])

    assert poly_factors((a*x - b)**5, x, a) == \
        (1, [(Poly(x*a - b, x, a), 5)])

    assert poly_factors((a*x - b)**5, x, a, b) == \
        (1, [(Poly(x*a - b, x, a, b), 5)])

    assert poly_factors(-2*x**2 + x, x) == \
        (-1, [(Poly(x, x), 1),
              (Poly(2*x - 1, x), 1)])

    assert poly_factors(x**3 - 3*x**2 + 3*x - 1, x) == \
        (1, [(Poly(x - 1, x), 3)])

    assert poly_factors(x**6 - 1, x) == \
        (1, [(Poly(x - 1, x), 1),
             (Poly(x + 1, x), 1),
             (Poly(x**2 - x + 1, x), 1),
             (Poly(x**2 + x + 1, x), 1)])

    assert poly_factors(2*x**3*y - 2*a**2*x*y - 3*a**2*x**2 + 3*a**4, a, x, y) == \
        (1, [(Poly(a - x, a, x, y), 1),
             (Poly(a + x, a, x, y), 1),
             (Poly(3*a**2 - 2*x*y, a, x, y), 1)])

    assert poly_factors(x**20 - z**5*y**20, x, y, z) == \
        (1, [(Poly(-y**4*z + x**4, x, y, z), 1),
             (Poly(y**16*z**4 + x**4*y**12*z**3 + x**8*y**8*z**2 + x**12*y**4*z + x**16, x, y, z) , 1)])
Esempio n. 3
0
def test_factor():
    assert factor(-2) == -2
    assert factor(-x) == -x

    assert factor(Rational(3, 8)*x**2 - Rational(3, 2)) == \
        Rational(3, 8)*((x - 2)*(x + 2))

    assert factor(x**3 - 1) == (x - 1)*(x**2 + x + 1)
    assert factor(x**3 - x) == x*(x - 1)*(x + 1)

    assert factor(x**2 + 2*x + 1) == (x + 1)**2
    assert factor(x**2 +   x - 2) == (x - 1)*(x + 2)

    assert factor(2*x**2 + 5*x + 2) == (x + 2)*(2*x + 1)

    assert factor(x**2 + y**2) == x**2 + y**2
    assert factor(x**5 - y**2) == x**5 - y**2

    assert factor(x*y + x*z + y*z) == x*y + x*z + y*z
    assert factor(x*y + x*z + x**2) == x*(x + y + z)

    assert poly_factors(-2*x**2 + x, x) == \
        (-1, [(Poly(x, x), 1),
              (Poly(2*x - 1, x), 1)])

    assert poly_factors(x**3 - 3*x**2 + 3*x - 1, x) == \
        (1, [(Poly(x - 1, x), 3)])

    assert poly_factors(x**6 - 1, x) == \
        (1, [(Poly(x - 1, x), 1),
             (Poly(x + 1, x), 1),
             (Poly(x**2 - x + 1, x), 1),
             (Poly(x**2 + x + 1, x), 1)])

    assert poly_factors(2*x**3*y - 2*a**2*x*y - 3*a**2*x**2 + 3*a**4, a, x, y) == \
        (1, [(Poly(a - x, a, x, y), 1),
             (Poly(a + x, a, x, y), 1),
             (Poly(3*a**2 - 2*x*y, a, x, y), 1)])
Esempio n. 4
0
def test_factor():
    assert factor(-2) == -2
    assert factor(-x) == -x

    assert factor(Rational(3, 8)*x**2 - Rational(3, 2)) == \
        Rational(3, 8)*((x - 2)*(x + 2))

    assert factor(x**3 - 1) == (x - 1) * (x**2 + x + 1)
    assert factor(x**3 - x) == x * (x - 1) * (x + 1)

    assert factor(x**2 + 2 * x + 1) == (x + 1)**2
    assert factor(x**2 + x - 2) == (x - 1) * (x + 2)

    assert factor(2 * x**2 + 5 * x + 2) == (x + 2) * (2 * x + 1)

    assert factor(x**2 + y**2) == x**2 + y**2
    assert factor(x**5 - y**2) == x**5 - y**2

    assert factor(x * y + x * z + y * z) == x * y + x * z + y * z
    assert factor(x * y + x * z + x**2) == x * (x + y + z)

    assert poly_factors(-2*x**2 + x, x) == \
        (-1, [(Poly(x, x), 1),
              (Poly(2*x - 1, x), 1)])

    assert poly_factors(x**3 - 3*x**2 + 3*x - 1, x) == \
        (1, [(Poly(x - 1, x), 3)])

    assert poly_factors(x**6 - 1, x) == \
        (1, [(Poly(x - 1, x), 1),
             (Poly(x + 1, x), 1),
             (Poly(x**2 - x + 1, x), 1),
             (Poly(x**2 + x + 1, x), 1)])

    assert poly_factors(2*x**3*y - 2*a**2*x*y - 3*a**2*x**2 + 3*a**4, a, x, y) == \
        (1, [(Poly(a - x, a, x, y), 1),
             (Poly(a + x, a, x, y), 1),
             (Poly(3*a**2 - 2*x*y, a, x, y), 1)])
Esempio n. 5
0
    def roots_trivial(g):
        if g.length == 1:
            if g.is_constant:
                return []
            else:
                return [S.Zero] * g.degree

        (k,), g = g.as_reduced()

        if k == 0:
            zeros = []
        else:
            zeros = [S.Zero] * k

        if g.length == 2:
            zeros += roots_binomial(g)
        else:
            x = g.symbols[0]

            for i in [S.NegativeOne, S.One]:
                if g(i).expand() is S.Zero:
                    g = poly_div(g, x - i)[0]
                    zeros.append(i)
                    break

            n = g.degree

            if n == 1:
                zeros += roots_linear(g)
            elif n == 2:
                zeros += roots_quadratic(g)
            elif n == 3:
                if flags.get("cubics", False):
                    # TODO: now we can used factor() not only
                    #       for cubic polynomials. See #1158
                    try:
                        _, factors = poly_factors(g)

                        if len(factors) == 1:
                            raise PolynomialError

                        for factor, k in factors:
                            zeros += roots(factor, multiple=True) * k
                    except PolynomialError:
                        zeros += roots_cubic(g)
            elif n == 4:
                if flags.get("quartics", False):
                    zeros += roots_quartic(g)

        return zeros
Esempio n. 6
0
    def roots_trivial(g):
        if g.length == 1:
            if g.is_constant:
                return []
            else:
                return [S.Zero] * g.degree

        (k, ), g = g.as_reduced()

        if k == 0:
            zeros = []
        else:
            zeros = [S.Zero] * k

        if g.length == 2:
            zeros += roots_binomial(g)
        else:
            x = g.symbols[0]

            for i in [S.NegativeOne, S.One]:
                if g(i).expand() is S.Zero:
                    g = poly_div(g, x - i)[0]
                    zeros.append(i)
                    break

            n = g.degree

            if n == 1:
                zeros += roots_linear(g)
            elif n == 2:
                zeros += roots_quadratic(g)
            elif n == 3:
                if flags.get('cubics', False):
                    # TODO: now we can used factor() not only
                    #       for cubic polynomials. See #1158
                    try:
                        _, factors = poly_factors(g)

                        if len(factors) == 1:
                            raise PolynomialError

                        for factor, k in factors:
                            zeros += roots(factor, multiple=True) * k
                    except PolynomialError:
                        zeros += roots_cubic(g)
            elif n == 4:
                if flags.get('quartics', False):
                    zeros += roots_quartic(g)

        return zeros
Esempio n. 7
0
def roots(f, *symbols, **flags):
    """Computes symbolic roots of an univariate polynomial.

       Given an univariate  polynomial f with symbolic coefficients,
       returns a dictionary with its roots and their multiplicities.

       Only roots expressible via radicals will be returned.  To get
       a complete set of roots use RootOf class or numerical methods
       instead. By default cubic and quartic formulas are used in
       the algorithm. To disable them because of unreadable output
       set cubics=False or quartics=False respectively.

       To get roots from a specific domain set the 'domain' flag with
       one of the following specifiers: Z, Q, R, I, C. By default all
       roots are returned (this is equivalent to setting domain='C').

       By default a dictionary is returned giving a compact result in
       case of multiple roots.  However to get a tuple containing all
       those roots set the 'multiple' flag to True.

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

       >>> roots(x**2 - 1, x)
       {1: 1, -1: 1}

       >>> roots(x**2 - y, x)
       {y**(1/2): 1, -y**(1/2): 1}

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

    if f.is_multivariate:
        raise MultivariatePolyError(f)

    def _update_dict(result, root, k):
        if result.has_key(root):
            result[root] += k
        else:
            result[root] = k

    def _try_decompose(f):
        """Find roots using functional decomposition. """
        factors = poly_decompose(f)
        result, g = {}, factors[0]

        for i, h in enumerate(poly_sqf(g)):
            for r in _try_heuristics(h):
                _update_dict(result, r, i + 1)

        for factor in factors[1:]:
            last, result = result.copy(), {}

            for last_r, i in last.iteritems():
                g = factor.sub_term(last_r, (0,))

                for j, h in enumerate(poly_sqf(g)):
                    for r in _try_heuristics(h):
                        _update_dict(result, r, i * (j + 1))

        return result

    def _try_heuristics(f):
        """Find roots using formulas and some tricks. """
        if f.length == 1:
            if f.is_constant:
                return []
            else:
                return [S(0)] * f.degree

        if f.length == 2:
            if f.degree == 1:
                return roots_linear(f)
            else:
                return roots_binomial(f)

        x, result = f.symbols[0], []

        for i in [S(-1), S(1)]:
            if f(i).expand().is_zero:
                f = poly_div(f, x - i)[0]
                result.append(i)
                break

        n = f.degree

        if n == 1:
            result += roots_linear(f)
        elif n == 2:
            result += roots_quadratic(f)
        elif n == 3 and flags.get("cubics", True):
            result += roots_cubic(f)
        elif n == 4 and flags.get("quartics", False):
            result += roots_quartic(f)

        return result

    multiple = flags.get("multiple", False)

    if f.length == 1:
        if f.is_constant:
            if multiple:
                return []
            else:
                return {}
        else:
            result = {S(0): f.degree}
    else:
        (k,), f = f.as_reduced()

        if k == 0:
            zeros = {}
        else:
            zeros = {S(0): k}

        result = {}

        if f.length == 2:
            if f.degree == 1:
                result[roots_linear(f)[0]] = 1
            else:
                for r in roots_binomial(f):
                    _update_dict(result, r, 1)
        elif f.degree == 2:
            for r in roots_quadratic(f):
                _update_dict(result, r, 1)
        else:
            try:
                _, factors = poly_factors(f)

                if len(factors) == 1 and factors[0][1] == 1:
                    raise CoefficientError

                for factor, k in factors:
                    for r in _try_heuristics(factor):
                        _update_dict(result, r, k)
            except CoefficientError:
                result = _try_decompose(f)

        result.update(zeros)

    domain = flags.get("domain", None)

    if domain not in [None, "C"]:
        handlers = {
            "Z": lambda r: r.is_Integer,
            "Q": lambda r: r.is_Rational,
            "R": lambda r: r.is_real,
            "I": lambda r: r.is_imaginary,
        }

        try:
            query = handlers[domain]
        except KeyError:
            raise ValueError("Invalid domain: %s" % domain)

        for zero in dict(result).iterkeys():
            if not query(zero):
                del result[zero]

    predicate = flags.get("predicate", None)

    if predicate is not None:
        for zero in dict(result).iterkeys():
            if not predicate(zero):
                del result[zero]

    if not multiple:
        return result
    else:
        zeros = []

        for zero, k in result.iteritems():
            zeros.extend([zero] * k)

        return zeros
Esempio n. 8
0
def roots(f, *symbols, **flags):
    """Computes symbolic roots of an univariate polynomial.

       Given an univariate  polynomial f with symbolic coefficients,
       returns a dictionary with its roots and their multiplicities.

       Only roots expressible via radicals will be returned.  To get
       a complete set of roots use RootOf class or numerical methods
       instead. By default cubic and quartic formulas are used in
       the algorithm. To disable them because of unreadable output
       set cubics=False or quartics=False respectively.

       To get roots from a specific domain set the 'domain' flag with
       one of the following specifiers: Z, Q, R, I, C. By default all
       roots are returned (this is equivalent to setting domain='C').

       By default a dictionary is returned giving a compact result in
       case of multiple roots.  However to get a tuple containing all
       those roots set the 'multiple' flag to True.

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

       >>> roots(x**2 - 1, x)
       {1: 1, -1: 1}

       >>> roots(x**2 - y, x)
       {y**(1/2): 1, -y**(1/2): 1}

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

    if f.is_multivariate:
        raise MultivariatePolyError(f)

    def _update_dict(result, root, k):
        if root in result:
            result[root] += k
        else:
            result[root] = k

    def _try_decompose(f):
        """Find roots using functional decomposition. """
        factors = poly_decompose(f)
        result, g = {}, factors[0]

        for i, h in enumerate(poly_sqf(g)):
            for r in _try_heuristics(h):
                _update_dict(result, r, i + 1)

        for factor in factors[1:]:
            last, result = result.copy(), {}

            for last_r, i in last.iteritems():
                g = factor.sub_term(last_r, (0, ))

                for j, h in enumerate(poly_sqf(g)):
                    for r in _try_heuristics(h):
                        _update_dict(result, r, i * (j + 1))

        return result

    def _try_heuristics(f):
        """Find roots using formulas and some tricks. """
        if f.length == 1:
            if f.is_constant:
                return []
            else:
                return [S(0)] * f.degree

        if f.length == 2:
            if f.degree == 1:
                return roots_linear(f)
            else:
                return roots_binomial(f)

        x, result = f.symbols[0], []

        for i in [S(-1), S(1)]:
            if f(i).expand().is_zero:
                f = poly_div(f, x - i)[0]
                result.append(i)
                break

        n = f.degree

        if n == 1:
            result += roots_linear(f)
        elif n == 2:
            result += roots_quadratic(f)
        elif n == 3 and flags.get('cubics', True):
            result += roots_cubic(f)
        elif n == 4 and flags.get('quartics', False):
            result += roots_quartic(f)

        return result

    multiple = flags.get('multiple', False)

    if f.length == 1:
        if f.is_constant:
            if multiple:
                return []
            else:
                return {}
        else:
            result = {S(0): f.degree}
    else:
        (k, ), f = f.as_reduced()

        if k == 0:
            zeros = {}
        else:
            zeros = {S(0): k}

        result = {}

        if f.length == 2:
            if f.degree == 1:
                result[roots_linear(f)[0]] = 1
            else:
                for r in roots_binomial(f):
                    _update_dict(result, r, 1)
        elif f.degree == 2:
            for r in roots_quadratic(f):
                _update_dict(result, r, 1)
        else:
            try:
                _, factors = poly_factors(f)

                if len(factors) == 1 and factors[0][1] == 1:
                    raise CoefficientError

                for factor, k in factors:
                    for r in _try_heuristics(factor):
                        _update_dict(result, r, k)
            except CoefficientError:
                result = _try_decompose(f)

        result.update(zeros)

    domain = flags.get('domain', None)

    if domain not in [None, 'C']:
        handlers = {
            'Z': lambda r: r.is_Integer,
            'Q': lambda r: r.is_Rational,
            'R': lambda r: r.is_real,
            'I': lambda r: r.is_imaginary,
        }

        try:
            query = handlers[domain]
        except KeyError:
            raise ValueError("Invalid domain: %s" % domain)

        for zero in dict(result).iterkeys():
            if not query(zero):
                del result[zero]

    predicate = flags.get('predicate', None)

    if predicate is not None:
        for zero in dict(result).iterkeys():
            if not predicate(zero):
                del result[zero]

    if not multiple:
        return result
    else:
        zeros = []

        for zero, k in result.iteritems():
            zeros.extend([zero] * k)

        return zeros