Exemple #1
0
    def __new__(cls, expr, func=None, x=None, auto=True, quadratic=False):
        """Construct a new ``RootSum`` instance carrying all roots of a polynomial. """
        coeff, poly = cls._transform(expr, x)

        if not poly.is_univariate:
            raise MultivariatePolynomialError("only univariate polynomials are allowed")

        if func is None:
            func = Lambda(poly.gen, poly.gen)
        else:
            try:
                is_func = func.is_Function
            except AttributeError:
                is_func = False

            if is_func and (func.nargs == 1 or 1 in func.nargs):
                if not isinstance(func, Lambda):
                    func = Lambda(poly.gen, func(poly.gen))
            else:
                raise ValueError("expected a univariate function, got %s" % func)

        var, expr = func.args

        if coeff is not S.One:
            expr = expr.subs(var, coeff*var)

        deg = poly.degree()

        if not expr.has(var):
            return deg*expr

        if expr.is_Add:
            add_const, expr = expr.as_independent(var)
        else:
            add_const = S.Zero

        if expr.is_Mul:
            mul_const, expr = expr.as_independent(var)
        else:
            mul_const = S.One

        func = Lambda(var, expr)

        rational = cls._is_func_rational(poly, func)
        (_, factors), terms = poly.factor_list(), []

        for poly, k in factors:
            if poly.is_linear:
                term = func(roots_linear(poly)[0])
            elif quadratic and poly.is_quadratic:
                term = sum(map(func, roots_quadratic(poly)))
            else:
                if not rational or not auto:
                    term = cls._new(poly, func, auto)
                else:
                    term = cls._rational_case(poly, func)

            terms.append(k*term)

        return mul_const*Add(*terms) + deg*add_const
Exemple #2
0
    def __new__(cls, expr, func=None, x=None, auto=True, quadratic=False):
        """Construct a new ``RootSum`` instance of roots of a polynomial."""
        coeff, poly = cls._transform(expr, x)

        if not poly.is_univariate:
            raise MultivariatePolynomialError(
                "only univariate polynomials are allowed")

        if func is None:
            func = Lambda(poly.gen, poly.gen)
        else:
            is_func = getattr(func, 'is_Function', False)

            if is_func and 1 in func.nargs:
                if not isinstance(func, Lambda):
                    func = Lambda(poly.gen, func(poly.gen))
            else:
                raise ValueError("expected a univariate function, got %s" %
                                 func)

        var, expr = func.variables[0], func.expr

        if coeff is not S.One:
            expr = expr.subs(var, coeff * var)

        deg = poly.degree()

        if not expr.has(var):
            return deg * expr

        if expr.is_Add:
            add_const, expr = expr.as_independent(var)
        else:
            add_const = S.Zero

        if expr.is_Mul:
            mul_const, expr = expr.as_independent(var)
        else:
            mul_const = S.One

        func = Lambda(var, expr)

        rational = cls._is_func_rational(poly, func)
        factors, terms = _pure_factors(poly), []

        for poly, k in factors:
            if poly.is_linear:
                term = func(roots_linear(poly)[0])
            elif quadratic and poly.is_quadratic:
                term = sum(map(func, roots_quadratic(poly)))
            else:
                if not rational or not auto:
                    term = cls._new(poly, func, auto)
                else:
                    term = cls._rational_case(poly, func)

            terms.append(k * term)

        return mul_const * Add(*terms) + deg * add_const
Exemple #3
0
    def _roots_trivial(cls, poly, radicals):
        """Compute roots in linear, quadratic and binomial cases. """
        if poly.degree() == 1:
            return roots_linear(poly)

        if not radicals:
            return None

        if poly.degree() == 2:
            return roots_quadratic(poly)
        elif poly.length() == 2 and poly.TC():
            return roots_binomial(poly)
        else:
            return None
    def _roots_trivial(cls, poly, radicals):
        """Compute roots in linear, quadratic and binomial cases. """
        if poly.degree() == 1:
            return roots_linear(poly)

        if not radicals:
            return None

        if poly.degree() == 2:
            return roots_quadratic(poly)
        elif poly.length() == 2 and poly.TC():
            return roots_binomial(poly)
        else:
            return None
Exemple #5
0
def roots_trivial(poly, radicals=True):
    """Compute roots in linear, quadratic and binomial cases. """
    if poly.degree() == 1:
        return roots_linear(poly)
    else:
        if not radicals:
            return None

        if poly in _rootof_trivial_cache:
            roots = _rootof_trivial_cache[poly]
        else:
            if radicals and poly.degree() == 2:
                roots = roots_quadratic(poly)
            elif radicals and poly.length() == 2 and poly.TC():
                roots = roots_binomial(poly)
            else:
                return None

            _rootof_trivial_cache[poly] = roots

        return roots
Exemple #6
0
def roots_trivial(poly, radicals=True):
    """Compute roots in linear, quadratic and binomial cases. """
    if poly.degree() == 1:
        return roots_linear(poly)
    else:
        if not radicals:
            return None

        if poly in _rootof_trivial_cache:
            roots = _rootof_trivial_cache[poly]
        else:
            if radicals and poly.degree() == 2:
                roots = roots_quadratic(poly)
            elif radicals and poly.length() == 2 and poly.TC():
                roots = roots_binomial(poly)
            else:
                return None

            _rootof_trivial_cache[poly] = roots

        return roots
Exemple #7
0
    def _roots_trivial(cls, poly, radicals):
        """Compute roots in linear, quadratic and binomial cases. """
        if poly.degree() == 1:
            return roots_linear(poly)

        if not radicals:
            return None
        free = len(poly.free_symbols)
        sort = isinstance(poly, PurePoly) and free or free > 1
        if poly.degree() == 2:
            roots = roots_quadratic(poly, sort=sort)
        elif poly.length() == 2 and poly.TC():
            roots = roots_binomial(poly, sort=sort)
        else:
            return None
        # put roots in same order as RootOf instances
        if not sort:
            key = [r.n(2) for r in roots]
            key = [(1 if not r.is_real else 0, C.re(r), C.im(r))
                for r in key]
            _, roots = zip(*sorted(zip(key, roots)))
        return roots
Exemple #8
0
def test_roots_linear():
    assert roots_linear(Poly(2*x + 1, x)) == [-Rational(1, 2)]
Exemple #9
0
def test_roots_linear():
    assert roots_linear(Poly(2 * x + 1, x)) == [-Rational(1, 2)]