def test_function_range(): x, y, a, b = symbols('x y a b') assert function_range(sin(x), x, Interval(-pi/2, pi/2) ) == Interval(-1, 1) assert function_range(sin(x), x, Interval(0, pi) ) == Interval(0, 1) assert function_range(tan(x), x, Interval(0, pi) ) == Interval(-oo, oo) assert function_range(tan(x), x, Interval(pi/2, pi) ) == Interval(-oo, 0) assert function_range((x + 3)/(x - 2), x, Interval(-5, 5) ) == Union(Interval(-oo, Rational(2, 7)), Interval(Rational(8, 3), oo)) assert function_range(1/(x**2), x, Interval(-1, 1) ) == Interval(1, oo) assert function_range(exp(x), x, Interval(-1, 1) ) == Interval(exp(-1), exp(1)) assert function_range(log(x) - x, x, S.Reals ) == Interval(-oo, -1) assert function_range(sqrt(3*x - 1), x, Interval(0, 2) ) == Interval(0, sqrt(5)) assert function_range(x*(x - 1) - (x**2 - x), x, S.Reals ) == FiniteSet(0) assert function_range(x*(x - 1) - (x**2 - x) + y, x, S.Reals ) == FiniteSet(y) assert function_range(sin(x), x, Union(Interval(-5, -3), FiniteSet(4)) ) == Union(Interval(-sin(3), 1), FiniteSet(sin(4))) assert function_range(cos(x), x, Interval(-oo, -4) ) == Interval(-1, 1) assert function_range(cos(x), x, S.EmptySet) == S.EmptySet assert function_range(x/sqrt(x**2+1), x, S.Reals) == Interval.open(-1,1) raises(NotImplementedError, lambda : function_range( exp(x)*(sin(x) - cos(x))/2 - x, x, S.Reals)) raises(NotImplementedError, lambda : function_range( sin(x) + x, x, S.Reals)) # issue 13273 raises(NotImplementedError, lambda : function_range( log(x), x, S.Integers)) raises(NotImplementedError, lambda : function_range( sin(x)/2, x, S.Naturals))
def test_bool_as_set(): assert ITE(y <= 0, False, y >= 1).as_set() == Interval(1, oo) assert And(x <= 2, x >= -2).as_set() == Interval(-2, 2) assert Or(x >= 2, x <= -2).as_set() == Interval(-oo, -2) + Interval(2, oo) assert Not(x > 2).as_set() == Interval(-oo, 2) # issue 10240 assert Not(And(x > 2, x < 3)).as_set() == \ Union(Interval(-oo, 2), Interval(3, oo)) assert true.as_set() == S.UniversalSet assert false.as_set() == EmptySet() assert x.as_set() == S.UniversalSet assert And(Or(x < 1, x > 3), x < 2).as_set() == Interval.open(-oo, 1) assert And(x < 1, sin(x) < 3).as_set() == (x < 1).as_set() raises(NotImplementedError, lambda: (sin(x) < 1).as_set())
def __new__(cls, sets, polar=False): from sympy import symbols x, y, r, theta = symbols('x, y, r, theta') I = S.ImaginaryUnit # Rectangular Form if polar is False: if all(_a.is_FiniteSet for _a in sets.args) and (len(sets.args) == 2): # ** ProductSet of FiniteSets in the Complex Plane. ** # For Cases like ComplexPlane({2, 4}*{3}), It # would return {2 + 3*I, 4 + 3*I} complex_num = [] for x in sets.args[0]: for y in sets.args[1]: complex_num.append(x + I * y) obj = FiniteSet(*complex_num) else: obj = ImageSet.__new__(cls, Lambda((x, y), x + I * y), sets) # Polar Form elif polar is True: new_sets = [] # sets is Union of ProductSets if not sets.is_ProductSet: for k in sets.args: new_sets.append(k) # sets is ProductSets else: new_sets.append(sets) # Normalize input theta for k, v in enumerate(new_sets): from sympy.sets import ProductSet new_sets[k] = ProductSet(v.args[0], normalize_theta_set(v.args[1])) sets = Union(*new_sets) from sympy import cos, sin obj = ImageSet.__new__( cls, Lambda((r, theta), r * (cos(theta) + I * sin(theta))), sets) return obj
def test_continuous_domain(): x = Symbol("x") assert continuous_domain(sin(x), x, Interval(0, 2 * pi)) == Interval(0, 2 * pi) assert continuous_domain(tan(x), x, Interval(0, 2 * pi)) == Union( Interval(0, pi / 2, False, True), Interval(pi / 2, pi * Rational(3, 2), True, True), Interval(pi * Rational(3, 2), 2 * pi, True, False), ) assert continuous_domain((x - 1) / ((x - 1)**2), x, S.Reals) == Union(Interval(-oo, 1, True, True), Interval(1, oo, True, True)) assert continuous_domain(log(x) + log(4 * x - 1), x, S.Reals) == Interval(Rational(1, 4), oo, True, True) assert continuous_domain(1 / sqrt(x - 3), x, S.Reals) == Interval(3, oo, True, True) assert continuous_domain(1 / x - 2, x, S.Reals) == Union(Interval.open(-oo, 0), Interval.open(0, oo)) assert continuous_domain(1 / (x**2 - 4) + 2, x, S.Reals) == Union(Interval.open(-oo, -2), Interval.open(-2, 2), Interval.open(2, oo))
def solve_poly_inequalities(polys): """Solve polynomial inequalities with rational coefficients. Examples ======== >>> from sympy import Poly >>> from sympy.solvers.inequalities import solve_poly_inequalities >>> from sympy.abc import x >>> solve_poly_inequalities((( ... Poly(x**2 - 3), ">"), ( ... Poly(-x**2 + 1), ">"))) Union(Interval.open(-oo, -sqrt(3)), Interval.open(-1, 1), Interval.open(sqrt(3), oo)) """ return Union(*[s for p in polys for s in solve_poly_inequality(*p)])
def __new__(cls, sets): new_sets = [] # sets is Union of ProductSets if not sets.is_ProductSet: for k in sets.args: new_sets.append(k) # sets is ProductSets else: new_sets.append(sets) # Normalize input theta for k, v in enumerate(new_sets): new_sets[k] = ProductSet(v.args[0], normalize_theta_set(v.args[1])) sets = Union(*new_sets) return Set.__new__(cls, sets)
def solve_univariate_inequality(expr, gen, assume=True, relational=True): """Solves a real univariate inequality. Examples ======== >>> from sympy.solvers.inequalities import solve_univariate_inequality >>> from sympy.core.symbol import Symbol >>> x = Symbol('x', real=True) >>> solve_univariate_inequality(x**2 >= 4, x) Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)) >>> solve_univariate_inequality(x**2 >= 4, x, relational=False) (-oo, -2] U [2, oo) """ # Implementation for continous functions from sympy.solvers.solvers import solve solns = solve(expr.lhs - expr.rhs, gen, assume=assume) oo = S.Infinity start = -oo sol_sets = [S.EmptySet] for x in sorted(s for s in solns if s.is_real): end = x if simplify( expr.subs(gen, (start + end) / 2 if start != -oo else end - 1)): sol_sets.append(Interval(start, end, True, True)) if simplify(expr.subs(gen, x)): sol_sets.append(FiniteSet(x)) start = end end = oo if simplify(expr.subs(gen, start + 1)): sol_sets.append(Interval(start, end, True, True)) rv = Union(*sol_sets) return rv if not relational else rv.as_relational(gen)
def solve_poly_inequalities(polys): """Solve polynomial inequalities with rational coefficients. Examples ======== >>> from sympy.solvers.inequalities import solve_poly_inequalities >>> from sympy.polys import Poly >>> from sympy.abc import x >>> solve_poly_inequalities((( ... Poly(x**2 - 3), ">"), ( ... Poly(-x**2 + 1), ">"))) (-oo, -sqrt(3)) U (-1, 1) U (sqrt(3), oo) """ from sympy import Union return Union(*[solve_poly_inequality(*p) for p in polys])
def test_print_SetOp(): f1 = FiniteSet(x, 1, 3) f2 = FiniteSet(y, 2, 4) assert mpp.doprint( Union(f1, f2, evaluate=False) ) == '<mrow><mfenced close="}" open="{"><mn>1</mn><mn>3</mn><mi>x</mi></mfenced><mo>∪</mo><mfenced close="}" open="{"><mn>2</mn><mn>4</mn><mi>y</mi></mfenced></mrow>' assert mpp.doprint( Intersection(f1, f2, evaluate=False) ) == '<mrow><mfenced close="}" open="{"><mn>1</mn><mn>3</mn><mi>x</mi></mfenced><mo>∩</mo><mfenced close="}" open="{"><mn>2</mn><mn>4</mn><mi>y</mi></mfenced></mrow>' assert mpp.doprint( Complement(f1, f2, evaluate=False) ) == '<mrow><mfenced close="}" open="{"><mn>1</mn><mn>3</mn><mi>x</mi></mfenced><mo>∖</mo><mfenced close="}" open="{"><mn>2</mn><mn>4</mn><mi>y</mi></mfenced></mrow>' assert mpp.doprint( SymmetricDifference(f1, f2, evaluate=False) ) == '<mrow><mfenced close="}" open="{"><mn>1</mn><mn>3</mn><mi>x</mi></mfenced><mo>∆</mo><mfenced close="}" open="{"><mn>2</mn><mn>4</mn><mi>y</mi></mfenced></mrow>'
def __new__(cls, sym, condition, base_set): if condition == S.false: return S.EmptySet if condition == S.true: return base_set if isinstance(base_set, EmptySet): return base_set if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: return Union( FiniteSet(*sifted[True]), Basic.__new__(cls, sym, condition, FiniteSet(*sifted[None]))) else: return FiniteSet(*sifted[True]) return Basic.__new__(cls, sym, condition, base_set)
def as_set(self): """ Rewrite logic operators and relationals in terms of real sets. Examples ======== >>> from sympy import Or, Symbol >>> x = Symbol('x', real=True) >>> Or(x>2, x<-2).as_set() (-oo, -2) U (2, oo) """ from sympy.sets.sets import Union if len(self.free_symbols) == 1: return Union(*[arg.as_set() for arg in self.args]) else: raise NotImplementedError("Sorry, Or.as_set has not yet been" " implemented for multivariate" " expressions")
def _(x, exponent): """ Powers in interval arithmetic https://en.wikipedia.org/wiki/Interval_arithmetic """ s1 = x.start**exponent s2 = x.end**exponent if ((s2 > s1) if exponent > 0 else (x.end > -x.start)) == True: left_open = x.left_open right_open = x.right_open # TODO: handle unevaluated condition. sleft = s2 else: # TODO: `s2 > s1` could be unevaluated. left_open = x.right_open right_open = x.left_open sleft = s1 if x.start.is_positive: return Interval(Min(s1, s2), Max(s1, s2), left_open, right_open) elif x.end.is_negative: return Interval(Min(s1, s2), Max(s1, s2), left_open, right_open) # Case where x.start < 0 and x.end > 0: if exponent.is_odd: if exponent.is_negative: if x.start.is_zero: return Interval(s2, oo, x.right_open) if x.end.is_zero: return Interval(-oo, s1, True, x.left_open) return Union(Interval(-oo, s1, True, x.left_open), Interval(s2, oo, x.right_open)) else: return Interval(s1, s2, x.left_open, x.right_open) elif exponent.is_even: if exponent.is_negative: if x.start.is_zero: return Interval(s2, oo, x.right_open) if x.end.is_zero: return Interval(s1, oo, x.left_open) return Interval(0, oo) else: return Interval(S.Zero, sleft, S.Zero not in x, left_open)
def test_codomain(): x = Symbol('x', real=True) assert codomain(x, Interval(-1, 1), x) == Interval(-1, 1) assert codomain(x, Interval(0, 1, True, True), x) == \ Interval(0, 1, True, True) assert codomain(x, Interval(1, 2, True, False), x) == Interval(1, 2, True, False) assert codomain(x, Interval(1, 2, False, True), x) == Interval(1, 2, False, True) assert codomain(x**2, Interval(-1, 1), x) == Interval(0, 1) assert codomain(x**3, Interval(0, 1), x) == Interval(0, 1) assert codomain(x/(x**2 - 4), Interval(3, 4), x) == Interval(S(1)/3, S(3)/5) assert codomain(1, Interval(-1, 4), x) == FiniteSet(1) assert codomain(x, Interval(-oo, oo), x) == S.Reals assert codomain(1/x**2, FiniteSet(1, 2, -1, 0), x) == FiniteSet(1, S(1)/4) assert codomain(x, FiniteSet(1, -1, 3, 5), x) == FiniteSet(-1, 1, 3, 5) assert codomain(x**2 - x, FiniteSet(1, -1, 3, 5, -oo), x) == \ FiniteSet(0, 2, 6, 20, oo) assert codomain(x**2/(x - 4), FiniteSet(4), x) == S.EmptySet assert codomain(x**2 - x, FiniteSet(S(1)/2, -oo, oo, 2), x) == \ FiniteSet(S(-1)/4, 2, oo) assert codomain(x**2, Interval(-1, 1, True, True), x) == Interval(0, 1, False, True) assert codomain(x**2, Interval(-1, 1, False, True), x) == Interval(0, 1) assert codomain(x**2, Interval(-1, 1, True, False), x) == Interval(0, 1) assert codomain(1/x, Interval(0, 1), x) == Interval(1, oo) assert codomain(1/x, Interval(-1, 1), x) == Union(Interval(-oo, -1), Interval(1, oo)) assert codomain(1/x**2, Interval(-1, 1), x) == Interval(1, oo) assert codomain(1/x**2, Interval(-1, 1, True, False), x) == Interval(1, oo) assert codomain(1/x**2, Interval(-1, 1, True, True), x) == \ Interval(1, oo, True, True) assert codomain(1/x**2, Interval(-1, 1, False, True), x) == Interval(1, oo) assert codomain(1/x, Interval(1, 2), x) == Interval(S(1)/2, 1) assert codomain(1/x**2, Interval(-2, -1, True, True), x) == \ Interval(S(1)/4, 1, True, True) assert codomain(x**2/(x - 4), Interval(-oo, oo), x) == \ Complement(S.Reals, Interval(0, 16, True, True)) assert codomain(x**2/(x - 4), Interval(3, 4), x) == Interval(-oo, -9) assert codomain(-x**2/(x - 4), Interval(3, 4), x) == Interval(9, oo) assert codomain((x**2 - x)/(x**3 - 1), S.Reals, x) == Interval(-1, S(1)/3, False, True) assert codomain(-x**2 + 1/x, S.Reals, x) == S.Reals assert codomain(x**2 - 1/x, S.Reals, x) == S.Reals assert codomain(x**2, Union(Interval(1, 2), FiniteSet(3)), x) == \ Union(Interval(1, 4), FiniteSet(9)) assert codomain(x/(x**2 - 4), Union(Interval(-oo, 1), Interval(0, oo)), x) == S.Reals assert codomain(x, Union(Interval(-1, 1), FiniteSet(-oo)), x) == \ Union(Interval(-1, 1), FiniteSet(-oo)) assert codomain(x**2 - x, Interval(1, oo), x) == Interval(0, oo) raises(ValueError, lambda: codomain(sqrt(x), Interval(-1, 2), x))
def reduce_union(sets): """sympy.set does not reduce complements in a union""" if isinstance(sets, Union): new_args = [] for sset in sets._args: if not sset.is_Complement: new_args.append(sset) if sset.is_Complement: if len(sset.args) != 2: raise ReGraphError("complement without 2 args") other_sets = [s for s in sets._args if s != sset] new_sset = Complement(sset.args[0], Complement(sset.args[1], *other_sets, evaluate=True), evaluate=True) new_args.append(new_sset) return Union(*new_args, evaluate=True) else: return sets
def union(self, other): if isinstance(other, AtEmptySet): return copy.deepcopy(self) elif isinstance(other, AtUnivSet): return AtUnivSet() elif isinstance(other, AtSymSet): # return # convert(AtSymSet(FiniteSet(*list(self.at_set)).union(other.at_set))) return convert( AtSymSet( reduce_union( Union(FiniteSet(*list(self.at_set)), other.at_set, evaluate=True)))) elif isinstance(other, AtFinSet): return AtFinSet(self.at_set.union(other.at_set)) # elif isinstance(other, AtPosStringSet): # elif isinstance(other, AtNegStringSet): else: raise AtSetError( "Finite Numerical set cannot union with type {}".format( type(other)))
def test_ComplexRegion_contains(): # contains in ComplexRegion a = Interval(2, 3) b = Interval(4, 6) c = Interval(7, 9) c1 = ComplexRegion(a * b) c2 = ComplexRegion(Union(a * b, c * a)) assert 2.5 + 4.5 * I in c1 assert 2 + 4 * I in c1 assert 3 + 4 * I in c1 assert 8 + 2.5 * I in c2 assert 2.5 + 6.1 * I not in c1 assert 4.5 + 3.2 * I not in c1 r1 = Interval(0, 1) theta1 = Interval(0, 2 * S.Pi) c3 = ComplexRegion(r1 * theta1, polar=True) assert 0.5 + 0.6 * I in c3 assert I in c3 assert 1 in c3 assert 0 in c3 assert 1 + I not in c3 assert 1 - I not in c3
def test_normalize_theta_set(): # Interval assert normalize_theta_set(Interval(9*pi/2, 5*pi)) == Interval(pi/2, pi) assert normalize_theta_set(Interval(-3*pi/2, pi/2)) == \ Interval(0, 2*pi, False, True) assert normalize_theta_set(Interval(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval(3*pi/2, 2*pi, False, True)) assert normalize_theta_set(Interval(-4*pi, 3*pi)) == \ Interval(0, 2*pi, False, True) assert normalize_theta_set(Interval(-3*pi/2, -pi/2)) == \ Interval(pi/2, 3*pi/2) # FiniteSet assert normalize_theta_set(FiniteSet(0, pi, 3*pi)) == FiniteSet(0, pi) assert normalize_theta_set(FiniteSet(0, pi/2, pi, 2*pi)) == \ FiniteSet(0, pi/2, pi) assert normalize_theta_set(FiniteSet(0, -pi/2, -pi, -2*pi)) == \ FiniteSet(0, pi, 3*pi/2) assert normalize_theta_set(FiniteSet(-3*pi/2, pi/2)) == \ FiniteSet(pi/2) # ValueError for non-real sets raises(ValueError, lambda: normalize_theta_set(S.Complex))
def test_stationary_points(): x, y = symbols("x y") assert stationary_points(sin(x), x, Interval(-pi / 2, pi / 2)) == {-pi / 2, pi / 2} assert stationary_points(sin(x), x, Interval.Ropen(0, pi / 4)) == EmptySet() assert stationary_points( tan(x), x, ) == EmptySet() assert stationary_points(sin(x) * cos(x), x, Interval(0, pi)) == { pi / 4, pi * Rational(3, 4), } assert stationary_points(sec(x), x, Interval(0, pi)) == {0, pi} assert stationary_points((x + 3) * (x - 2), x) == FiniteSet(Rational(-1, 2)) assert stationary_points((x + 3) / (x - 2), x, Interval(-5, 5)) == EmptySet() assert stationary_points((x**2 + 3) / (x - 2), x) == {2 - sqrt(7), 2 + sqrt(7)} assert stationary_points((x**2 + 3) / (x - 2), x, Interval(0, 5)) == {2 + sqrt(7)} assert stationary_points(x**4 + x**3 - 5 * x**2, x, S.Reals) == FiniteSet(-2, 0, Rational(5, 4)) assert stationary_points(exp(x), x) == EmptySet() assert stationary_points(log(x) - x, x, S.Reals) == {1} assert stationary_points(cos(x), x, Union(Interval(0, 5), Interval(-6, -3))) == { 0, -pi, pi, } assert stationary_points(y, x, S.Reals) == S.Reals assert stationary_points(y, x, S.EmptySet) == S.EmptySet
def test_ComplexRegion_union(): # Polar form c1 = ComplexRegion(Interval(0, 1) * Interval(0, 2 * S.Pi), polar=True) c2 = ComplexRegion(Interval(0, 1) * Interval(0, S.Pi), polar=True) c3 = ComplexRegion(Interval(0, oo) * Interval(0, S.Pi), polar=True) c4 = ComplexRegion(Interval(0, oo) * Interval(S.Pi, 2 * S.Pi), polar=True) p1 = Union( Interval(0, 1) * Interval(0, 2 * S.Pi), Interval(0, 1) * Interval(0, S.Pi)) p2 = Union( Interval(0, oo) * Interval(0, S.Pi), Interval(0, oo) * Interval(S.Pi, 2 * S.Pi)) assert c1.union(c2) == ComplexRegion(p1, polar=True) assert c3.union(c4) == ComplexRegion(p2, polar=True) # Rectangular form c5 = ComplexRegion(Interval(2, 5) * Interval(6, 9)) c6 = ComplexRegion(Interval(4, 6) * Interval(10, 12)) c7 = ComplexRegion(Interval(0, 10) * Interval(-10, 0)) c8 = ComplexRegion(Interval(12, 16) * Interval(14, 20)) p3 = Union( Interval(2, 5) * Interval(6, 9), Interval(4, 6) * Interval(10, 12)) p4 = Union( Interval(0, 10) * Interval(-10, 0), Interval(12, 16) * Interval(14, 20)) assert c5.union(c6) == ComplexRegion(p3) assert c7.union(c8) == ComplexRegion(p4) assert c1.union(Interval(2, 4)) == Union(c1, Interval(2, 4), evaluate=False) assert c5.union(Interval(2, 4)) == Union(c5, Interval(2, 4), evaluate=False)
def test_not_empty_in(): from sympy.abc import x a = Symbol('a', real=True) assert not_empty_in(FiniteSet(x, 2*x).intersect(Interval(1, 2, True, False)), x) == \ Interval(S(1)/2, 2, True, False) assert not_empty_in(FiniteSet(x, x**2).intersect(Interval(1, 2)), x) == \ Union(Interval(-sqrt(2), -1), Interval(1, 2)) assert not_empty_in(FiniteSet(x**2 + x, x).intersect(Interval(2, 4)), x) == \ Union(Interval(-sqrt(17)/2 - S(1)/2, -2), Interval(1, -S(1)/2 + sqrt(17)/2), Interval(2, 4)) assert not_empty_in(FiniteSet(x/(x - 1)).intersect(S.Reals), x) == Complement(S.Reals, FiniteSet(1)) assert not_empty_in(FiniteSet(a/(a - 1)).intersect(S.Reals), a) == Complement(S.Reals, FiniteSet(1)) assert not_empty_in(FiniteSet((x**2 - 3*x + 2)/(x - 1)).intersect(S.Reals), x) == \ Complement(S.Reals, FiniteSet(1)) assert not_empty_in(FiniteSet(3, 4, x/(x - 1)).intersect(Interval(2, 3)), x) == \ Union(Interval(S(3)/2, 2), FiniteSet(3)) assert not_empty_in(FiniteSet(x/(x**2 - 1)).intersect(S.Reals), x) == \ Complement(S.Reals, FiniteSet(-1, 1)) assert not_empty_in(FiniteSet(x, x**2).intersect(Union(Interval(1, 3, True, True), Interval(4, 5))), x) == \ Union(Interval(-sqrt(5), -2), Interval(-sqrt(3), -1, True, True), Interval(1, 3, True, True), Interval(4, 5)) assert not_empty_in(FiniteSet(1).intersect(Interval(3, 4)), x) == S.EmptySet assert not_empty_in(FiniteSet(x**2/(x + 2)).intersect(Interval(1, oo)), x) == \ Union(Interval(-2, -1, True, False), Interval(2, oo))
def test_normalize_theta_set(): # Interval assert normalize_theta_set(Interval(pi, 2*pi)) == \ Union(FiniteSet(0), Interval.Ropen(pi, 2*pi)) assert normalize_theta_set(Interval(pi * Rational(9, 2), 5 * pi)) == Interval(pi / 2, pi) assert normalize_theta_set(Interval(pi * Rational(-3, 2), pi / 2)) == Interval.Ropen(0, 2 * pi) assert normalize_theta_set(Interval.open(pi*Rational(-3, 2), pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.open(pi/2, 2*pi)) assert normalize_theta_set(Interval.open(pi*Rational(-7, 2), pi*Rational(-3, 2))) == \ Union(Interval.Ropen(0, pi/2), Interval.open(pi/2, 2*pi)) assert normalize_theta_set(Interval(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval.Ropen(pi*Rational(3, 2), 2*pi)) assert normalize_theta_set(Interval.open(-pi/2, pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.open(pi*Rational(3, 2), 2*pi)) assert normalize_theta_set(Interval(-4 * pi, 3 * pi)) == Interval.Ropen(0, 2 * pi) assert normalize_theta_set(Interval(pi * Rational(-3, 2), -pi / 2)) == Interval( pi / 2, pi * Rational(3, 2)) assert normalize_theta_set(Interval.open(0, 2 * pi)) == Interval.open( 0, 2 * pi) assert normalize_theta_set(Interval.Ropen(-pi/2, pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.Ropen(pi*Rational(3, 2), 2*pi)) assert normalize_theta_set(Interval.Lopen(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval.open(pi*Rational(3, 2), 2*pi)) assert normalize_theta_set(Interval(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval.Ropen(pi*Rational(3, 2), 2*pi)) assert normalize_theta_set(Interval.open( 4 * pi, pi * Rational(9, 2))) == Interval.open(0, pi / 2) assert normalize_theta_set(Interval.Lopen( 4 * pi, pi * Rational(9, 2))) == Interval.Lopen(0, pi / 2) assert normalize_theta_set(Interval.Ropen( 4 * pi, pi * Rational(9, 2))) == Interval.Ropen(0, pi / 2) assert normalize_theta_set(Interval.open(3*pi, 5*pi)) == \ Union(Interval.Ropen(0, pi), Interval.open(pi, 2*pi)) # FiniteSet assert normalize_theta_set(FiniteSet(0, pi, 3 * pi)) == FiniteSet(0, pi) assert normalize_theta_set(FiniteSet(0, pi / 2, pi, 2 * pi)) == FiniteSet(0, pi / 2, pi) assert normalize_theta_set(FiniteSet(0, -pi / 2, -pi, -2 * pi)) == FiniteSet( 0, pi, pi * Rational(3, 2)) assert normalize_theta_set(FiniteSet(pi*Rational(-3, 2), pi/2)) == \ FiniteSet(pi/2) assert normalize_theta_set(FiniteSet(2 * pi)) == FiniteSet(0) # Unions assert normalize_theta_set(Union(Interval(0, pi/3), Interval(pi/2, pi))) == \ Union(Interval(0, pi/3), Interval(pi/2, pi)) assert normalize_theta_set(Union(Interval(0, pi), Interval(2*pi, pi*Rational(7, 3)))) == \ Interval(0, pi) # ValueError for non-real sets raises(ValueError, lambda: normalize_theta_set(S.Complexes)) # NotImplementedError for subset of reals raises(NotImplementedError, lambda: normalize_theta_set(Interval(0, 1))) # NotImplementedError without pi as coefficient raises(NotImplementedError, lambda: normalize_theta_set(Interval(1, 2 * pi))) raises(NotImplementedError, lambda: normalize_theta_set(Interval(2 * pi, 10))) raises(NotImplementedError, lambda: normalize_theta_set(FiniteSet(0, 3, 3 * pi)))
def not_empty_in(finset_intersection, *syms): """ Finds the domain of the functions in `finite_set` in which the `finite_set` is not-empty Parameters ========== finset_intersection: The unevaluated intersection of FiniteSet containing real-valued functions with Union of Sets syms: Tuple of symbols Symbol for which domain is to be found Raises ====== NotImplementedError The algorithms to find the non-emptiness of the given FiniteSet are not yet implemented. ValueError The input is not valid. RuntimeError It is a bug, please report it to the github issue tracker (https://github.com/sympy/sympy/issues). Examples ======== >>> from sympy import FiniteSet, Interval, not_empty_in, oo >>> from sympy.abc import x >>> not_empty_in(FiniteSet(x/2).intersect(Interval(0, 1)), x) Interval(0, 2) >>> not_empty_in(FiniteSet(x, x**2).intersect(Interval(1, 2)), x) Union(Interval(-sqrt(2), -1), Interval(1, 2)) >>> not_empty_in(FiniteSet(x**2/(x + 2)).intersect(Interval(1, oo)), x) Union(Interval(-2, -1, True), Interval(2, oo, False, True)) """ # TODO: handle piecewise defined functions # TODO: handle transcendental functions # TODO: handle multivariate functions if len(syms) == 0: raise ValueError("One or more symbols must be given in syms.") if finset_intersection.is_EmptySet: return EmptySet() if isinstance(finset_intersection, Union): elm_in_sets = finset_intersection.args[0] return Union(not_empty_in(finset_intersection.args[1], *syms), elm_in_sets) if isinstance(finset_intersection, FiniteSet): finite_set = finset_intersection _sets = S.Reals else: finite_set = finset_intersection.args[1] _sets = finset_intersection.args[0] if not isinstance(finite_set, FiniteSet): raise ValueError('A FiniteSet must be given, not %s: %s' % (type(finite_set), finite_set)) if len(syms) == 1: symb = syms[0] else: raise NotImplementedError('more than one variables %s not handled' % (syms,)) def elm_domain(expr, intrvl): """ Finds the domain of an expression in any given interval """ from sympy.solvers.solveset import solveset _start = intrvl.start _end = intrvl.end _singularities = solveset(expr.as_numer_denom()[1], symb, domain=S.Reals) if intrvl.right_open: if _end is S.Infinity: _domain1 = S.Reals else: _domain1 = solveset(expr < _end, symb, domain=S.Reals) else: _domain1 = solveset(expr <= _end, symb, domain=S.Reals) if intrvl.left_open: if _start is S.NegativeInfinity: _domain2 = S.Reals else: _domain2 = solveset(expr > _start, symb, domain=S.Reals) else: _domain2 = solveset(expr >= _start, symb, domain=S.Reals) # domain in the interval expr_with_sing = Intersection(_domain1, _domain2) expr_domain = Complement(expr_with_sing, _singularities) return expr_domain if isinstance(_sets, Interval): return Union(*[elm_domain(element, _sets) for element in finite_set]) if isinstance(_sets, Union): _domain = S.EmptySet for intrvl in _sets.args: _domain_element = Union(*[elm_domain(element, intrvl) for element in finite_set]) _domain = Union(_domain, _domain_element) return _domain
def test_normalize_theta_set(): # Interval assert normalize_theta_set(Interval(pi, 2*pi)) == \ Union(FiniteSet(0), Interval.Ropen(pi, 2*pi)) assert normalize_theta_set(Interval(9 * pi / 2, 5 * pi)) == Interval(pi / 2, pi) assert normalize_theta_set(Interval(-3 * pi / 2, pi / 2)) == Interval.Ropen(0, 2 * pi) assert normalize_theta_set(Interval.open(-3*pi/2, pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.open(pi/2, 2*pi)) assert normalize_theta_set(Interval.open(-7*pi/2, -3*pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.open(pi/2, 2*pi)) assert normalize_theta_set(Interval(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval.Ropen(3*pi/2, 2*pi)) assert normalize_theta_set(Interval.open(-pi/2, pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.open(3*pi/2, 2*pi)) assert normalize_theta_set(Interval(-4 * pi, 3 * pi)) == Interval.Ropen(0, 2 * pi) assert normalize_theta_set(Interval(-3 * pi / 2, -pi / 2)) == Interval( pi / 2, 3 * pi / 2) assert normalize_theta_set(Interval.open(0, 2 * pi)) == Interval.open( 0, 2 * pi) assert normalize_theta_set(Interval.Ropen(-pi/2, pi/2)) == \ Union(Interval.Ropen(0, pi/2), Interval.Ropen(3*pi/2, 2*pi)) assert normalize_theta_set(Interval.Lopen(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval.open(3*pi/2, 2*pi)) assert normalize_theta_set(Interval(-pi/2, pi/2)) == \ Union(Interval(0, pi/2), Interval.Ropen(3*pi/2, 2*pi)) assert normalize_theta_set(Interval.open(4 * pi, 9 * pi / 2)) == Interval.open( 0, pi / 2) assert normalize_theta_set(Interval.Lopen(4 * pi, 9 * pi / 2)) == Interval.Lopen( 0, pi / 2) assert normalize_theta_set(Interval.Ropen(4 * pi, 9 * pi / 2)) == Interval.Ropen( 0, pi / 2) assert normalize_theta_set(Interval.open(3*pi, 5*pi)) == \ Union(Interval.Ropen(0, pi), Interval.open(pi, 2*pi)) # FiniteSet assert normalize_theta_set(FiniteSet(0, pi, 3 * pi)) == FiniteSet(0, pi) assert normalize_theta_set(FiniteSet(0, pi / 2, pi, 2 * pi)) == FiniteSet(0, pi / 2, pi) assert normalize_theta_set(FiniteSet(0, -pi / 2, -pi, -2 * pi)) == FiniteSet( 0, pi, 3 * pi / 2) assert normalize_theta_set(FiniteSet(-3*pi/2, pi/2)) == \ FiniteSet(pi/2) assert normalize_theta_set(FiniteSet(2 * pi)) == FiniteSet(0) # Unions assert normalize_theta_set(Union(Interval(0, pi/3), Interval(pi/2, pi))) == \ Union(Interval(0, pi/3), Interval(pi/2, pi)) assert normalize_theta_set(Union(Interval(0, pi), Interval(2*pi, 7*pi/3))) == \ Interval(0, pi) # ValueError for non-real sets raises(ValueError, lambda: normalize_theta_set(S.Complexes))
def solve_univariate_inequality(expr, gen, relational=True): """Solves a real univariate inequality. Examples ======== >>> from sympy.solvers.inequalities import solve_univariate_inequality >>> from sympy.core.symbol import Symbol >>> x = Symbol('x') >>> solve_univariate_inequality(x**2 >= 4, x) Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)) >>> solve_univariate_inequality(x**2 >= 4, x, relational=False) (-oo, -2] U [2, oo) """ from sympy.solvers.solvers import solve, denoms # This keeps the function independent of the assumptions about `gen`. # `solveset` makes sure this function is called only when the domain is # real. d = Dummy(real=True) expr = expr.subs(gen, d) _gen = gen gen = d if expr is S.true: rv = S.Reals elif expr is S.false: rv = S.EmptySet else: e = expr.lhs - expr.rhs parts = n, d = e.as_numer_denom() if all(i.is_polynomial(gen) for i in parts): solns = solve(n, gen, check=False) singularities = solve(d, gen, check=False) else: solns = solve(e, gen, check=False) singularities = [] for d in denoms(e): singularities.extend(solve(d, gen)) include_x = expr.func(0, 0) def valid(x): v = e.subs(gen, x) try: r = expr.func(v, 0) except TypeError: r = S.false if r in (S.true, S.false): return r if v.is_real is False: return S.false else: v = v.n(2) if v.is_comparable: return expr.func(v, 0) return S.false start = S.NegativeInfinity sol_sets = [S.EmptySet] try: reals = _nsort(set(solns + singularities), separated=True)[0] except NotImplementedError: raise NotImplementedError('sorting of these roots is not supported') for x in reals: end = x if end in [S.NegativeInfinity, S.Infinity]: if valid(S(0)): sol_sets.append(Interval(start, S.Infinity, True, True)) break pt = ((start + end)/2 if start is not S.NegativeInfinity else (end/2 if end.is_positive else (2*end if end.is_negative else end - 1))) if valid(pt): sol_sets.append(Interval(start, end, True, True)) if x in singularities: singularities.remove(x) elif include_x: sol_sets.append(FiniteSet(x)) start = end end = S.Infinity # in case start == -oo then there were no solutions so we just # check a point between -oo and oo (e.g. 0) else pick a point # past the last solution (which is start after the end of the # for-loop above pt = (0 if start is S.NegativeInfinity else (start/2 if start.is_negative else (2*start if start.is_positive else start + 1))) if valid(pt): sol_sets.append(Interval(start, end, True, True)) rv = Union(*sol_sets).subs(gen, _gen) return rv if not relational else rv.as_relational(_gen)
def normalize_theta_set(theta): """ Normalize a Real Set `theta` in the Interval [0, 2*pi). It returns a normalized value of theta in the Set. For Interval, a maximum of one cycle [0, 2*pi], is returned i.e. for theta equal to [0, 10*pi], returned normalized value would be [0, 2*pi). As of now intervals with end points as non-multiples of `pi` is not supported. Raises ====== NotImplementedError The algorithms for Normalizing theta Set are not yet implemented. ValueError The input is not valid, i.e. the input is not a real set. RuntimeError It is a bug, please report to the github issue tracker. Examples ======== >>> from sympy.sets.fancysets import normalize_theta_set >>> from sympy import Interval, FiniteSet, pi >>> normalize_theta_set(Interval(9*pi/2, 5*pi)) [pi/2, pi] >>> normalize_theta_set(Interval(-3*pi/2, pi/2)) [0, 2*pi) >>> normalize_theta_set(Interval(-pi/2, pi/2)) [0, pi/2] U [3*pi/2, 2*pi) >>> normalize_theta_set(Interval(-4*pi, 3*pi)) [0, 2*pi) >>> normalize_theta_set(Interval(-3*pi/2, -pi/2)) [pi/2, 3*pi/2] >>> normalize_theta_set(FiniteSet(0, pi, 3*pi)) {0, pi} """ from sympy.functions.elementary.trigonometric import _pi_coeff as coeff if theta.is_Interval: interval_len = theta.measure # one complete circle if interval_len >= 2 * S.Pi: if interval_len == 2 * S.Pi and theta.left_open and theta.right_open: k = coeff(theta.start) return Union(Interval(0, k * S.Pi, False, True), Interval(k * S.Pi, 2 * S.Pi, True, True)) return Interval(0, 2 * S.Pi, False, True) k_start, k_end = coeff(theta.start), coeff(theta.end) if k_start is None or k_end is None: raise NotImplementedError( "Normalizing theta without pi as coefficient is " "not yet implemented") new_start = k_start * S.Pi new_end = k_end * S.Pi if new_start > new_end: return Union(Interval(S.Zero, new_end, False, theta.right_open), Interval(new_start, 2 * S.Pi, theta.left_open, True)) else: return Interval(new_start, new_end, theta.left_open, theta.right_open) elif theta.is_FiniteSet: new_theta = [] for element in theta: k = coeff(element) if k is None: raise NotImplementedError('Normalizing theta without pi as ' 'coefficient, is not Implemented.') else: new_theta.append(k * S.Pi) return FiniteSet(*new_theta) elif theta.is_Union: return Union( *[normalize_theta_set(interval) for interval in theta.args]) elif theta.is_subset(S.Reals): raise NotImplementedError( "Normalizing theta when, it is of type %s is not " "implemented" % type(theta)) else: raise ValueError(" %s is not a real set" % (theta))
def test_NZQRC_unions(): # check that all trivial number set unions are simplified: nbrsets = (S.Naturals, S.Naturals0, S.Integers, S.Rationals, S.Reals, S.Complexes) unions = (Union(a, b) for a in nbrsets for b in nbrsets) assert all(u.is_Union is False for u in unions)
def solve_univariate_inequality(expr, gen, relational=True): """Solves a real univariate inequality. Examples ======== >>> from sympy.solvers.inequalities import solve_univariate_inequality >>> from sympy.core.symbol import Symbol >>> x = Symbol('x', real=True) >>> solve_univariate_inequality(x**2 >= 4, x) Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)) >>> solve_univariate_inequality(x**2 >= 4, x, relational=False) (-oo, -2] U [2, oo) """ from sympy.solvers.solvers import solve, denoms e = expr.lhs - expr.rhs parts = n, d = e.as_numer_denom() if all(i.is_polynomial(gen) for i in parts): solns = solve(n, gen, check=False) singularities = solve(d, gen, check=False) else: solns = solve(e, gen, check=False) singularities = [] for d in denoms(e): singularities.extend(solve(d, gen)) include_x = expr.func(0, 0) def valid(x): v = e.subs(gen, x) try: r = expr.func(v, 0) except TypeError: r = S.false if r in (S.true, S.false): return r if v.is_real is False: return S.false else: v = v.n(2) if v.is_comparable: return expr.func(v, 0) return S.false start = S.NegativeInfinity sol_sets = [S.EmptySet] try: reals = _nsort(set(solns + singularities), separated=True)[0] except NotImplementedError: raise NotImplementedError('sorting of these roots is not supported') for x in reals: end = x if end in [S.NegativeInfinity, S.Infinity]: if valid(S(0)): sol_sets.append(Interval(start, S.Infinity, True, True)) break if valid((start + end)/2 if start != S.NegativeInfinity else end - 1): sol_sets.append(Interval(start, end, True, True)) if x in singularities: singularities.remove(x) elif include_x: sol_sets.append(FiniteSet(x)) start = end end = S.Infinity if valid(start + 1): sol_sets.append(Interval(start, end, True, True)) rv = Union(*sol_sets) return rv if not relational else rv.as_relational(gen)
def reduce_rational_inequalities(exprs, gen, relational=True): """Reduce a system of rational inequalities with rational coefficients. Examples ======== >>> from sympy import Poly, Symbol >>> from sympy.solvers.inequalities import reduce_rational_inequalities >>> x = Symbol('x', real=True) >>> reduce_rational_inequalities([[x**2 <= 0]], x) Eq(x, 0) >>> reduce_rational_inequalities([[x + 2 > 0]], x) And(-2 < x, x < oo) >>> reduce_rational_inequalities([[(x + 2, ">")]], x) And(-2 < x, x < oo) >>> reduce_rational_inequalities([[x + 2]], x) Eq(x, -2) """ exact = True eqs = [] solution = S.EmptySet for _exprs in exprs: _eqs = [] for expr in _exprs: if isinstance(expr, tuple): expr, rel = expr else: if expr.is_Relational: expr, rel = expr.lhs - expr.rhs, expr.rel_op else: expr, rel = expr, '==' if expr is S.true: numer, denom, rel = S.Zero, S.One, '==' elif expr is S.false: numer, denom, rel = S.One, S.One, '==' else: numer, denom = expr.together().as_numer_denom() try: (numer, denom), opt = parallel_poly_from_expr( (numer, denom), gen) except PolynomialError: raise PolynomialError(filldedent(''' only polynomials and rational functions are supported in this context''')) if not opt.domain.is_Exact: numer, denom, exact = numer.to_exact(), denom.to_exact(), False domain = opt.domain.get_exact() if not (domain.is_ZZ or domain.is_QQ): expr = numer/denom expr = Relational(expr, 0, rel) solution = Union(solution, solve_univariate_inequality(expr, gen, relational=False)) else: _eqs.append(((numer, denom), rel)) eqs.append(_eqs) solution = Union(solution, solve_rational_inequalities(eqs)) if not exact: solution = solution.evalf() if relational: solution = solution.as_relational(gen) return solution
def solve_univariate_inequality(expr, gen, relational=True, domain=S.Reals, continuous=False): """Solves a real univariate inequality. Parameters ========== expr : Relational The target inequality gen : Symbol The variable for which the inequality is solved relational : bool A Relational type output is expected or not domain : Set The domain over which the equation is solved continuous: bool True if expr is known to be continuous over the given domain (and so continuous_domain() doesn't need to be called on it) Raises ====== NotImplementedError The solution of the inequality cannot be determined due to limitation in `solvify`. Notes ===== Currently, we cannot solve all the inequalities due to limitations in `solvify`. Also, the solution returned for trigonometric inequalities are restricted in its periodic interval. See Also ======== solvify: solver returning solveset solutions with solve's output API Examples ======== >>> from sympy.solvers.inequalities import solve_univariate_inequality >>> from sympy import Symbol, sin, Interval, S >>> x = Symbol('x') >>> solve_univariate_inequality(x**2 >= 4, x) ((2 <= x) & (x < oo)) | ((x <= -2) & (-oo < x)) >>> solve_univariate_inequality(x**2 >= 4, x, relational=False) Union(Interval(-oo, -2), Interval(2, oo)) >>> domain = Interval(0, S.Infinity) >>> solve_univariate_inequality(x**2 >= 4, x, False, domain) Interval(2, oo) >>> solve_univariate_inequality(sin(x) > 0, x, relational=False) Interval.open(0, pi) """ from sympy import im from sympy.calculus.util import (continuous_domain, periodicity, function_range) from sympy.solvers.solvers import denoms from sympy.solvers.solveset import solveset_real, solvify, solveset from sympy.solvers.solvers import solve # This keeps the function independent of the assumptions about `gen`. # `solveset` makes sure this function is called only when the domain is # real. _gen = gen _domain = domain if gen.is_real is False: rv = S.EmptySet return rv if not relational else rv.as_relational(_gen) elif gen.is_real is None: gen = Dummy('gen', real=True) try: expr = expr.xreplace({_gen: gen}) except TypeError: raise TypeError( filldedent(''' When gen is real, the relational has a complex part which leads to an invalid comparison like I < 0. ''')) rv = None if expr is S.true: rv = domain elif expr is S.false: rv = S.EmptySet else: e = expr.lhs - expr.rhs period = periodicity(e, gen) if period is S.Zero: e = expand_mul(e) const = expr.func(e, 0) if const is S.true: rv = domain elif const is S.false: rv = S.EmptySet elif period is not None: frange = function_range(e, gen, domain) rel = expr.rel_op if rel == '<' or rel == '<=': if expr.func(frange.sup, 0): rv = domain elif not expr.func(frange.inf, 0): rv = S.EmptySet elif rel == '>' or rel == '>=': if expr.func(frange.inf, 0): rv = domain elif not expr.func(frange.sup, 0): rv = S.EmptySet inf, sup = domain.inf, domain.sup if sup - inf is S.Infinity: domain = Interval(0, period, False, True) if rv is None: n, d = e.as_numer_denom() try: if gen not in n.free_symbols and len(e.free_symbols) > 1: raise ValueError # this might raise ValueError on its own # or it might give None... solns = solvify(e, gen, domain) if solns is None: # in which case we raise ValueError raise ValueError except (ValueError, NotImplementedError): # replace gen with generic x since it's # univariate anyway raise NotImplementedError( filldedent(''' The inequality, %s, cannot be solved using solve_univariate_inequality. ''' % expr.subs(gen, Symbol('x')))) expanded_e = expand_mul(e) def valid(x): # this is used to see if gen=x satisfies the # relational by substituting it into the # expanded form and testing against 0, e.g. # if expr = x*(x + 1) < 2 then e = x*(x + 1) - 2 # and expanded_e = x**2 + x - 2; the test is # whether a given value of x satisfies # x**2 + x - 2 < 0 # # expanded_e, expr and gen used from enclosing scope v = expanded_e.subs(gen, expand_mul(x)) try: r = expr.func(v, 0) except TypeError: r = S.false if r in (S.true, S.false): return r if v.is_real is False: return S.false else: v = v.n(2) if v.is_comparable: return expr.func(v, 0) # not comparable or couldn't be evaluated raise NotImplementedError( 'relationship did not evaluate: %s' % r) singularities = [] for d in denoms(expr, gen): singularities.extend(solvify(d, gen, domain)) if not continuous: domain = continuous_domain(expanded_e, gen, domain) include_x = '=' in expr.rel_op and expr.rel_op != '!=' try: discontinuities = set(domain.boundary - FiniteSet(domain.inf, domain.sup)) # remove points that are not between inf and sup of domain critical_points = FiniteSet( *(solns + singularities + list(discontinuities))).intersection( Interval(domain.inf, domain.sup, domain.inf not in domain, domain.sup not in domain)) if all(r.is_number for r in critical_points): reals = _nsort(critical_points, separated=True)[0] else: from sympy.utilities.iterables import sift sifted = sift(critical_points, lambda x: x.is_real) if sifted[None]: # there were some roots that weren't known # to be real raise NotImplementedError try: reals = sifted[True] if len(reals) > 1: reals = list(sorted(reals)) except TypeError: raise NotImplementedError except NotImplementedError: raise NotImplementedError( 'sorting of these roots is not supported') # If expr contains imaginary coefficients, only take real # values of x for which the imaginary part is 0 make_real = S.Reals if im(expanded_e) != S.Zero: check = True im_sol = FiniteSet() try: a = solveset(im(expanded_e), gen, domain) if not isinstance(a, Interval): for z in a: if z not in singularities and valid( z) and z.is_real: im_sol += FiniteSet(z) else: start, end = a.inf, a.sup for z in _nsort(critical_points + FiniteSet(end)): valid_start = valid(start) if start != end: valid_z = valid(z) pt = _pt(start, z) if pt not in singularities and pt.is_real and valid( pt): if valid_start and valid_z: im_sol += Interval(start, z) elif valid_start: im_sol += Interval.Ropen(start, z) elif valid_z: im_sol += Interval.Lopen(start, z) else: im_sol += Interval.open(start, z) start = z for s in singularities: im_sol -= FiniteSet(s) except (TypeError): im_sol = S.Reals check = False if isinstance(im_sol, EmptySet): raise ValueError( filldedent(''' %s contains imaginary parts which cannot be made 0 for any value of %s satisfying the inequality, leading to relations like I < 0. ''' % (expr.subs(gen, _gen), _gen))) make_real = make_real.intersect(im_sol) empty = sol_sets = [S.EmptySet] start = domain.inf if valid(start) and start.is_finite: sol_sets.append(FiniteSet(start)) for x in reals: end = x if valid(_pt(start, end)): sol_sets.append(Interval(start, end, True, True)) if x in singularities: singularities.remove(x) else: if x in discontinuities: discontinuities.remove(x) _valid = valid(x) else: # it's a solution _valid = include_x if _valid: sol_sets.append(FiniteSet(x)) start = end end = domain.sup if valid(end) and end.is_finite: sol_sets.append(FiniteSet(end)) if valid(_pt(start, end)): sol_sets.append(Interval.open(start, end)) if im(expanded_e) != S.Zero and check: rv = (make_real).intersect(_domain) else: rv = Intersection((Union(*sol_sets)), make_real, _domain).subs(gen, _gen) return rv if not relational else rv.as_relational(_gen)
def normalize_theta_set(theta): """ Normalize a Real Set theta in the Interval [0, 2*pi). It currently supports Interval and FiniteSet. It Returns a the normalized value of theta in the Set. For Interval, a maximum of one cycle [0, 2*pi], is returned i.e. for theta equal to [0, 10*pi], returned normalized value would be [0, 2*pi). As of now it supports theta as FiniteSet and Interval. Raises ====== NotImplementedError The algorithms for Normalizing theta Set are not yet implemented. ValueError The input is not valid, i.e. the input is not a real set. RuntimeError It is a bug, please report to the github issue tracker. Examples ======== >>> from sympy.sets.fancysets import normalize_theta_set >>> from sympy import Interval, FiniteSet, pi >>> normalize_theta_set(Interval(9*pi/2, 5*pi)) [pi/2, pi] >>> normalize_theta_set(Interval(-3*pi/2, pi/2)) [0, 2*pi) >>> normalize_theta_set(Interval(-pi/2, pi/2)) [0, pi/2] U [3*pi/2, 2*pi) >>> normalize_theta_set(Interval(-4*pi, 3*pi)) [0, 2*pi) >>> normalize_theta_set(Interval(-3*pi/2, -pi/2)) [pi/2, 3*pi/2] >>> normalize_theta_set(FiniteSet(0, pi, 3*pi)) {0, pi} """ from sympy.functions.elementary.trigonometric import _pi_coeff as coeff from sympy.functions.elementary.complexes import Abs if theta.is_Interval: # one complete circle if Abs(theta.args[0] - theta.args[1]) >= 2 * S.Pi: return Interval(0, 2 * S.Pi, False, True) new_theta = [] for val in [theta.args[0], theta.args[1]]: k = coeff(val) if (not k) and (k != S.Zero): raise NotImplementedError('Normalizing theta without pi as' 'coefficient, is not Implemented.') elif k == S.Zero: if val == S.Zero: new_theta.append(S.Zero) else: # when theta is n*pi new_theta.append(2 * S.Pi) else: new_theta.append(k * S.Pi) # for negative theta if new_theta[0] > new_theta[1]: return Union(Interval(S(0), new_theta[1]), Interval(new_theta[0], 2 * S.Pi, False, True)) else: return Interval(*new_theta) elif theta.is_FiniteSet: new_theta = [] for element in theta: k = coeff(element) if (not k) and (k != S.Zero): raise NotImplementedError('Normalizing theta without pi as' 'coefficient, is not Implemented.') elif k == S.Zero: if element == S.Zero: new_theta.append(S.Zero) else: new_theta.append(k * S.Pi) return FiniteSet(*new_theta) elif theta.is_subset(S.Reals): raise NotImplementedError("Normalizing theta when, its %s is not" "Implemented" % type(theta)) else: raise ValueError(" %s is not a real set" % (theta))