def test_roots_quadratic(): assert roots_quadratic(Poly(2*x**2, x)) == [0, 0] assert roots_quadratic(Poly(2*x**2+3*x, x)) == [0, -Rational(3, 2)] assert roots_quadratic(Poly(2*x**2+3, x)) == [I*sqrt(6)/2, -I*sqrt(6)/2] assert roots_quadratic(Poly(2*x**2+4*x+3, x)) == \ [-1 + I*sqrt(2)/2, -1 - I*sqrt(2)/2]
def test_roots_quadratic(): assert roots_quadratic(Poly(2*x**2, x)) == [0, 0] assert roots_quadratic(Poly(2*x**2 + 3*x, x)) == [Rational(-3, 2), 0] assert roots_quadratic(Poly(2*x**2 + 3, x)) == [-I*sqrt(6)/2, I*sqrt(6)/2] assert roots_quadratic(Poly(2*x**2 + 4*x + 3, x)) == [-1 - I*sqrt(2)/2, -1 + I*sqrt(2)/2] _check(Poly(2*x**2 + 4*x + 3, x).all_roots()) f = x**2 + (2*a*e + 2*c*e)/(a - c)*x + (d - b + a*e**2 - c*e**2)/(a - c) assert roots_quadratic(Poly(f, x)) == \ [-e*(a + c)/(a - c) - sqrt((a*b + c*d - a*d - b*c + 4*a*c*e**2))/(a - c), -e*(a + c)/(a - c) + sqrt((a*b + c*d - a*d - b*c + 4*a*c*e**2))/(a - c)] # check for simplification f = Poly(y*x**2 - 2*x - 2*y, x) assert roots_quadratic(f) == \ [-sqrt(2*y**2 + 1)/y + 1/y, sqrt(2*y**2 + 1)/y + 1/y] f = Poly(x**2 + (-y**2 - 2)*x + y**2 + 1, x) assert roots_quadratic(f) == \ [1,y**2 + 1] f = Poly(sqrt(2)*x**2 - 1, x) r = roots_quadratic(f) assert r == _nsort(r) # issue 8255 f = Poly(-24*x**2 - 180*x + 264) assert [w.n(2) for w in f.all_roots(radicals=True)] == \ [w.n(2) for w in f.all_roots(radicals=False)] for _a, _b, _c in cartes((-2, 2), (-2, 2), (0, -1)): f = Poly(_a*x**2 + _b*x + _c) roots = roots_quadratic(f) assert roots == _nsort(roots)
def test_roots_quadratic(): assert roots_quadratic(Poly(2*x**2, x)) == [0, 0] assert roots_quadratic(Poly(2*x**2 + 3*x, x)) == [-Rational(3, 2), 0] assert roots_quadratic(Poly(2*x**2 + 3, x)) == [-I*sqrt(6)/2, I*sqrt(6)/2] assert roots_quadratic(Poly(2*x**2 + 4*x + 3, x)) == [-1 - I*sqrt(2)/2, -1 + I*sqrt(2)/2] f = x**2 + (2*a*e + 2*c*e)/(a - c)*x + (d - b + a*e**2 - c*e**2)/(a - c) assert roots_quadratic(Poly(f, x)) == \ [-e*(a + c)/(a - c) - sqrt((a*b + c*d - a*d - b*c + 4*a*c*e**2)/(a - c)**2), -e*(a + c)/(a - c) + sqrt((a*b + c*d - a*d - b*c + 4*a*c*e**2)/(a - c)**2)] # check for simplification f = Poly(y*x**2 - 2*x - 2*y, x) assert roots_quadratic(f) == \ [-sqrt(2*y**2 + 1)/y + 1/y, sqrt(2*y**2 + 1)/y + 1/y] f = Poly(x**2 + (-y**2 - 2)*x + y**2 + 1, x) assert roots_quadratic(f) == \ [y**2/2 - sqrt(y**4)/2 + 1, y**2/2 + sqrt(y**4)/2 + 1] f = Poly(sqrt(2)*x**2 - 1, x) r = roots_quadratic(f) assert r == _nsort(r) # issue 8255 f = Poly(-24*x**2 - 180*x + 264) assert [w.n(2) for w in f.all_roots(radicals=True)] == \ [w.n(2) for w in f.all_roots(radicals=False)] for _a, _b, _c in cartes((-2, 2), (-2, 2), (0, -1)): f = Poly(_a*x**2 + _b*x + _c) roots = roots_quadratic(f) assert roots == _nsort(roots)
def test_roots_quadratic(): assert roots_quadratic(Poly(2*x**2, x)) == [0, 0] assert roots_quadratic(Poly(2*x**2 + 3*x, x)) == [-Rational(3, 2), 0] assert roots_quadratic(Poly(2*x**2 + 3, x)) == [-I*sqrt(6)/2, I*sqrt(6)/2] assert roots_quadratic(Poly(2*x**2 + 4*x + 3, x)) == [-1 - I*sqrt(2)/2, -1 + I*sqrt(2)/2] f = x**2 + (2*a*e + 2*c*e)/(a - c)*x + (d - b + a*e**2 - c*e**2)/(a - c) assert roots_quadratic(Poly(f, x)) == \ [-e*(a + c)/(a - c) - sqrt((a*b + c*d - a*d - b*c + 4*a*c*e**2)/(a - c)**2), -e*(a + c)/(a - c) + sqrt((a*b + c*d - a*d - b*c + 4*a*c*e**2)/(a - c)**2)]
def test_roots_quadratic(): assert roots_quadratic(Poly(2*x**2, x)) == [0, 0] assert roots_quadratic(Poly(2*x**2 + 3*x, x)) == [-Rational(3, 2), 0] assert roots_quadratic(Poly(2*x**2 + 3, x)) == [-I*sqrt(6)/2, I*sqrt(6)/2] assert roots_quadratic(Poly(2*x**2 + 4*x+3, x)) == [-1 - I*sqrt(2)/2, -1 + I*sqrt(2)/2] f = x**2 + (2*a*e + 2*c*e)/(a - c)*x + (d - b + a*e**2 - c*e**2)/(a - c) assert roots_quadratic(Poly(f, x)) == \ [-e*(a + c)/(a - c) - ((a*b + c*d - a*d - b*c + 4*a*c*e**2)/(a - c)**2)**S.Half, -e*(a + c)/(a - c) + ((a*b + c*d - a*d - b*c + 4*a*c*e**2)/(a - c)**2)**S.Half]
def test_roots_binomial(): assert roots_binomial(Poly(5 * x, x)) == [0] assert roots_binomial(Poly(5 * x**4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5 * x + 2, x)) == [Rational(-2, 5)] A = 10**Rational(3, 4) / 10 assert roots_binomial(Poly(5*x**4 + 2, x)) == \ [-A - A*I, -A + A*I, A - A*I, A + A*I] _check(roots_binomial(Poly(x**8 - 2))) a1 = Symbol('a1', nonnegative=True) b1 = Symbol('b1', nonnegative=True) r0 = roots_quadratic(Poly(a1 * x**2 + b1, x)) r1 = roots_binomial(Poly(a1 * x**2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1]) for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)): if a == b and a != 1: # a == b == 1 is sufficient continue p = Poly(a * x**n + s * b) ans = roots_binomial(p) assert ans == _nsort(ans) # issue 8813 assert roots(Poly(2 * x**3 - 16 * y**3, x)) == { 2 * y * (Rational(-1, 2) - sqrt(3) * I / 2): 1, 2 * y: 1, 2 * y * (Rational(-1, 2) + sqrt(3) * I / 2): 1 }
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 test_roots_binomial(): assert roots_binomial(Poly(5*x, x)) == [0] assert roots_binomial(Poly(5*x**4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5*x + 2, x)) == [-Rational(2, 5)] A = 10**Rational(3, 4)/10 assert roots_binomial(Poly(5*x**4 + 2, x)) == \ [-A - A*I, -A + A*I, A - A*I, A + A*I] a1 = Symbol('a1', nonnegative=True) b1 = Symbol('b1', nonnegative=True) r0 = roots_quadratic(Poly(a1*x**2 + b1, x)) r1 = roots_binomial(Poly(a1*x**2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1]) for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)): if a == b and a != 1: # a == b == 1 is sufficient continue p = Poly(a*x**n + s*b) ans = roots_binomial(p) assert ans == _nsort(ans) # issue 8813 assert roots(Poly(2*x**3 - 16*y**3, x)) == { 2*y*(-S(1)/2 - sqrt(3)*I/2): 1, 2*y: 1, 2*y*(-S(1)/2 + sqrt(3)*I/2): 1}
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 test_roots_binomial(): assert roots_binomial(Poly(5 * x, x)) == [0] assert roots_binomial(Poly(5 * x ** 4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5 * x + 2, x)) == [-Rational(2, 5)] A = 10 ** Rational(3, 4) / 10 assert roots_binomial(Poly(5 * x ** 4 + 2, x)) == [-A - A * I, -A + A * I, A - A * I, A + A * I] a1 = Symbol("a1", nonnegative=True) b1 = Symbol("b1", nonnegative=True) r0 = roots_quadratic(Poly(a1 * x ** 2 + b1, x)) r1 = roots_binomial(Poly(a1 * x ** 2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1])
def test_roots_binomial(): assert roots_binomial(Poly(5 * x, x)) == [0] assert roots_binomial(Poly(5 * x**4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5 * x + 2, x)) == [-Rational(2, 5)] A = 10**Rational(3, 4) / 10 assert roots_binomial(Poly(5*x**4 + 2, x)) == \ [-A - A*I, -A + A*I, A - A*I, A + A*I] a1 = Symbol('a1', nonnegative=True) b1 = Symbol('b1', nonnegative=True) r0 = roots_quadratic(Poly(a1 * x**2 + b1, x)) r1 = roots_binomial(Poly(a1 * x**2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1])
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_binomial(): assert roots_binomial(Poly(5 * x, x)) == [0] assert roots_binomial(Poly(5 * x ** 4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5 * x + 2, x)) == [-Rational(2, 5)] A = 10 ** Rational(3, 4) / 10 assert roots_binomial(Poly(5 * x ** 4 + 2, x)) == [-A - A * I, -A + A * I, A - A * I, A + A * I] a1 = Symbol("a1", nonnegative=True) b1 = Symbol("b1", nonnegative=True) r0 = roots_quadratic(Poly(a1 * x ** 2 + b1, x)) r1 = roots_binomial(Poly(a1 * x ** 2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1]) for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)): if a == b and a != 1: # a == b == 1 is sufficient continue p = Poly(a * x ** n + s * b) roots = roots_binomial(p) assert roots == _nsort(roots)
def test_roots_binomial(): assert roots_binomial(Poly(5*x, x)) == [0] assert roots_binomial(Poly(5*x**4, x)) == [0, 0, 0, 0] assert roots_binomial(Poly(5*x + 2, x)) == [-Rational(2, 5)] A = 10**Rational(3, 4)/10 assert roots_binomial(Poly(5*x**4 + 2, x)) == \ [-A - A*I, -A + A*I, A - A*I, A + A*I] a1 = Symbol('a1', nonnegative=True) b1 = Symbol('b1', nonnegative=True) r0 = roots_quadratic(Poly(a1*x**2 + b1, x)) r1 = roots_binomial(Poly(a1*x**2 + b1, x)) assert powsimp(r0[0]) == powsimp(r1[0]) assert powsimp(r0[1]) == powsimp(r1[1]) for a, b, s, n in cartes((1, 2), (1, 2), (-1, 1), (2, 3, 4, 5)): if a == b and a != 1: # a == b == 1 is sufficient continue p = Poly(a*x**n + s*b) roots = roots_binomial(p) assert roots == _nsort(roots)