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
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
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(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
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
def test_roots_linear(): assert roots_linear(Poly(2*x + 1, x)) == [-Rational(1, 2)]
def test_roots_linear(): assert roots_linear(Poly(2 * x + 1, x)) == [-Rational(1, 2)]