def test_range_interval_intersection(): p = symbols('p', positive=True) assert isinstance(Range(3).intersect(Interval(p, p + 2)), Intersection) assert Range(4).intersect(Interval(0, 3)) == Range(4) assert Range(4).intersect(Interval(-oo, oo)) == Range(4) assert Range(4).intersect(Interval(1, oo)) == Range(1, 4) assert Range(4).intersect(Interval(1.1, oo)) == Range(2, 4) assert Range(4).intersect(Interval(0.1, 3)) == Range(1, 4) assert Range(4).intersect(Interval(0.1, 3.1)) == Range(1, 4) assert Range(4).intersect(Interval.open(0, 3)) == Range(1, 3) assert Range(4).intersect(Interval.open(0.1, 0.5)) is S.EmptySet
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, 3*pi/2, True, True), Interval(3*pi/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(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 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 _intersect(self, other): from sympy.functions.elementary.integers import ceiling, floor from sympy.functions.elementary.complexes import sign if other is S.Naturals: return self._intersect(Interval(1, S.Infinity)) if other is S.Integers: return self if other.is_Interval: if not all(i.is_number for i in other.args[:2]): return # In case of null Range, return an EmptySet. if self.size == 0: return S.EmptySet # trim down to self's size, and represent # as a Range with step 1. start = ceiling(max(other.inf, self.inf)) if start not in other: start += 1 end = floor(min(other.sup, self.sup)) if end not in other: end -= 1 return self.intersect(Range(start, end + 1)) if isinstance(other, Range): from sympy.solvers.diophantine import diop_linear from sympy.core.numbers import ilcm # non-overlap quick exits if not other: return S.EmptySet if not self: return S.EmptySet if other.sup < self.inf: return S.EmptySet if other.inf > self.sup: return S.EmptySet # work with finite end at the start r1 = self if r1.start.is_infinite: r1 = r1.reversed r2 = other if r2.start.is_infinite: r2 = r2.reversed # this equation represents the values of the Range; # it's a linear equation eq = lambda r, i: r.start + i * r.step # we want to know when the two equations might # have integer solutions so we use the diophantine # solver a, b = diop_linear(eq(r1, Dummy()) - eq(r2, Dummy())) # check for no solution no_solution = a is None and b is None if no_solution: return S.EmptySet # there is a solution # ------------------- # find the coincident point, c a0 = a.as_coeff_Add()[0] c = eq(r1, a0) # find the first point, if possible, in each range # since c may not be that point def _first_finite_point(r1, c): if c == r1.start: return c # st is the signed step we need to take to # get from c to r1.start st = sign(r1.start - c) * step # use Range to calculate the first point: # we want to get as close as possible to # r1.start; the Range will not be null since # it will at least contain c s1 = Range(c, r1.start + st, st)[-1] if s1 == r1.start: pass else: # if we didn't hit r1.start then, if the # sign of st didn't match the sign of r1.step # we are off by one and s1 is not in r1 if sign(r1.step) != sign(st): s1 -= st if s1 not in r1: return return s1 # calculate the step size of the new Range step = abs(ilcm(r1.step, r2.step)) s1 = _first_finite_point(r1, c) if s1 is None: return S.EmptySet s2 = _first_finite_point(r2, c) if s2 is None: return S.EmptySet # replace the corresponding start or stop in # the original Ranges with these points; the # result must have at least one point since # we know that s1 and s2 are in the Ranges def _updated_range(r, first): st = sign(r.step) * step if r.start.is_finite: rv = Range(first, r.stop, st) else: rv = Range(r.start, first + st, st) return rv r1 = _updated_range(self, s1) r2 = _updated_range(other, s2) # work with them both in the increasing direction if sign(r1.step) < 0: r1 = r1.reversed if sign(r2.step) < 0: r2 = r2.reversed # return clipped Range with positive step; it # can't be empty at this point start = max(r1.start, r2.start) stop = min(r1.stop, r2.stop) return Range(start, stop, step) else: return
def __eq__(self, other): return other == Interval(-S.Infinity, S.Infinity)
def _intersect(self, other): from sympy.solvers.diophantine import diophantine if self.base_set is S.Integers: g = None if isinstance(other, ImageSet) and other.base_set is S.Integers: g = other.lamda.expr m = other.lamda.variables[0] elif other is S.Integers: m = g = Dummy('x') if g is not None: f = self.lamda.expr n = self.lamda.variables[0] # Diophantine sorts the solutions according to the alphabetic # order of the variable names, since the result should not depend # on the variable name, they are replaced by the dummy variables # below a, b = Dummy('a'), Dummy('b') f, g = f.subs(n, a), g.subs(m, b) solns_set = diophantine(f - g) if solns_set == set(): return EmptySet() solns = list(diophantine(f - g)) if len(solns) != 1: return # since 'a' < 'b', select soln for n nsol = solns[0][0] t = nsol.free_symbols.pop() return imageset(Lambda(n, f.subs(a, nsol.subs(t, n))), S.Integers) if other == S.Reals: from sympy.solvers.solveset import solveset_real from sympy.core.function import expand_complex if len(self.lamda.variables) > 1: return None f = self.lamda.expr n = self.lamda.variables[0] n_ = Dummy(n.name, real=True) f_ = f.subs(n, n_) re, im = f_.as_real_imag() im = expand_complex(im) return imageset(Lambda(n_, re), self.base_set.intersect(solveset_real(im, n_))) elif isinstance(other, Interval): from sympy.solvers.solveset import (invert_real, invert_complex, solveset) f = self.lamda.expr n = self.lamda.variables[0] base_set = self.base_set new_inf, new_sup = None, None new_lopen, new_ropen = other.left_open, other.right_open if f.is_real: inverter = invert_real else: inverter = invert_complex g1, h1 = inverter(f, other.inf, n) g2, h2 = inverter(f, other.sup, n) if all(isinstance(i, FiniteSet) for i in (h1, h2)): if g1 == n: if len(h1) == 1: new_inf = h1.args[0] if g2 == n: if len(h2) == 1: new_sup = h2.args[0] # TODO: Design a technique to handle multiple-inverse # functions # Any of the new boundary values cannot be determined if any(i is None for i in (new_sup, new_inf)): return range_set = S.EmptySet if all(i.is_real for i in (new_sup, new_inf)): # this assumes continuity of underlying function # however fixes the case when it is decreasing if new_inf > new_sup: new_inf, new_sup = new_sup, new_inf new_interval = Interval(new_inf, new_sup, new_lopen, new_ropen) range_set = base_set._intersect(new_interval) else: if other.is_subset(S.Reals): solutions = solveset(f, n, S.Reals) if not isinstance(range_set, (ImageSet, ConditionSet)): range_set = solutions._intersect(other) else: return if range_set is S.EmptySet: return S.EmptySet elif isinstance(range_set, Range) and range_set.size is not S.Infinity: range_set = FiniteSet(*list(range_set)) if range_set is not None: return imageset(Lambda(n, f), range_set) return else: return
def test_multivariate_bool_as_set(): x, y = symbols('x,y') assert And(x >= 0, y >= 0).as_set() == Interval(0, oo)*Interval(0, oo) assert Or(x >= 0, y >= 0).as_set() == S.Reals*S.Reals - \ Interval(-oo, 0, True, True)*Interval(-oo, 0, True, True)
def test_issue_8975(): assert Or(And(-oo < x, x <= -2), And(2 <= x, x < oo)).as_set() == \ Interval(-oo, -2) + Interval(2, oo)
def set(self): return S.Reals * Interval(0, S.Infinity)
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 function_range(f, symbol, domain): """ Finds the range of a function in a given domain. This method is limited by the ability to determine the singularities and determine limits. Examples ======== >>> from sympy import Symbol, S, exp, log, pi, sqrt, sin, tan >>> from sympy.sets import Interval >>> from sympy.calculus.util import function_range >>> x = Symbol('x') >>> function_range(sin(x), x, Interval(0, 2*pi)) [-1, 1] >>> function_range(tan(x), x, Interval(-pi/2, pi/2)) (-oo, oo) >>> function_range(1/x, x, S.Reals) (-oo, oo) >>> function_range(exp(x), x, S.Reals) (0, oo) >>> function_range(log(x), x, S.Reals) (-oo, oo) >>> function_range(sqrt(x), x , Interval(-5, 9)) [0, 3] """ from sympy.solvers.solveset import solveset vals = S.EmptySet period = periodicity(f, symbol) if not any(period is i for i in (None, S.Zero)): inf = domain.inf inf_period = S.Zero if inf.is_infinite else inf sup_period = inf_period + period periodic_interval = Interval(inf_period, sup_period) domain = domain.intersect(periodic_interval) intervals = continuous_domain(f, symbol, domain) range_int = S.EmptySet if isinstance(intervals, Interval): interval_iter = (intervals,) else: interval_iter = intervals.args for interval in interval_iter: critical_points = S.EmptySet critical_values = S.EmptySet bounds = ((interval.left_open, interval.inf, '+'), (interval.right_open, interval.sup, '-')) for is_open, limit_point, direction in bounds: if is_open: critical_values += FiniteSet(limit(f, symbol, limit_point, direction)) vals += critical_values else: vals += FiniteSet(f.subs(symbol, limit_point)) critical_points += solveset(f.diff(symbol), symbol, domain) for critical_point in critical_points: vals += FiniteSet(f.subs(symbol, critical_point)) left_open, right_open = False, False if critical_values is not S.EmptySet: if critical_values.inf == vals.inf: left_open = True if critical_values.sup == vals.sup: right_open = True range_int += Interval(vals.inf, vals.sup, left_open, right_open) return range_int
def function_range(f, symbol, domain): """ Finds the range of a function in a given domain. This method is limited by the ability to determine the singularities and determine limits. Examples ======== >>> from sympy import Symbol, S, exp, log, pi, sqrt, sin, tan >>> from sympy.sets import Interval >>> from sympy.calculus.util import function_range >>> x = Symbol('x') >>> function_range(sin(x), x, Interval(0, 2*pi)) Interval(-1, 1) >>> function_range(tan(x), x, Interval(-pi/2, pi/2)) Interval(-oo, oo) >>> function_range(1/x, x, S.Reals) Union(Interval.open(-oo, 0), Interval.open(0, oo)) >>> function_range(exp(x), x, S.Reals) Interval.open(0, oo) >>> function_range(log(x), x, S.Reals) Interval(-oo, oo) >>> function_range(sqrt(x), x , Interval(-5, 9)) Interval(0, 3) """ from sympy.solvers.solveset import solveset if isinstance(domain, EmptySet): return S.EmptySet period = periodicity(f, symbol) if period is S.Zero: # the expression is constant wrt symbol return FiniteSet(f.expand()) if period is not None: if isinstance(domain, Interval): if (domain.inf - domain.sup).is_infinite: domain = Interval(0, period) elif isinstance(domain, Union): for sub_dom in domain.args: if isinstance(sub_dom, Interval) and \ ((sub_dom.inf - sub_dom.sup).is_infinite): domain = Interval(0, period) intervals = continuous_domain(f, symbol, domain) range_int = S.EmptySet if isinstance(intervals,(Interval, FiniteSet)): interval_iter = (intervals,) elif isinstance(intervals, Union): interval_iter = intervals.args else: raise NotImplementedError(filldedent(''' Unable to find range for the given domain. ''')) for interval in interval_iter: if isinstance(interval, FiniteSet): for singleton in interval: if singleton in domain: range_int += FiniteSet(f.subs(symbol, singleton)) elif isinstance(interval, Interval): vals = S.EmptySet critical_points = S.EmptySet critical_values = S.EmptySet bounds = ((interval.left_open, interval.inf, '+'), (interval.right_open, interval.sup, '-')) for is_open, limit_point, direction in bounds: if is_open: critical_values += FiniteSet(limit(f, symbol, limit_point, direction)) vals += critical_values else: vals += FiniteSet(f.subs(symbol, limit_point)) solution = solveset(f.diff(symbol), symbol, interval) if isinstance(solution, ConditionSet): raise NotImplementedError('Unable to find critical points for %s'.format(f)) critical_points += solution for critical_point in critical_points: vals += FiniteSet(f.subs(symbol, critical_point)) left_open, right_open = False, False if critical_values is not S.EmptySet: if critical_values.inf == vals.inf: left_open = True if critical_values.sup == vals.sup: right_open = True range_int += Interval(vals.inf, vals.sup, left_open, right_open) else: raise NotImplementedError(filldedent(''' Unable to find range for the given domain. ''')) return range_int
def interval(self): return Interval(self.args[1][1], self.args[1][2])
def prove(Eq): n = Symbol.n(integer=True, positive=True) u = Symbol.u(domain=Interval(0, n, integer=True)) v = Symbol.v(domain=Interval(0, n, integer=True)) Eq << apply(n, u, v) w, i, j = Eq[0].lhs.args Q = Eq[2].lhs.base Eq.x_slice_last, Eq.x_slice_domain = sets.imply.conditionset.apply( Q[u]).split() Eq << Eq.x_slice_domain.apply( discrete.combinatorics.permutation.index.equality, v) Eq.h_domain, Eq.x_h_equality = Eq[-1].split() hv = Eq.x_h_equality.function.lhs.indices[0] Eq << algebre.matrix.elementary.swap.invariant.permutation.apply(n + 1, w=w) Eq << Subset(Eq[-2].limits[0][1], Eq[-1].rhs, plausible=True) Eq << sets.subset.forall.imply.forall.apply(Eq[-1], Eq[-2]) Eq << Eq[-1].subs(Eq[-1].rhs.this.definition) Eq << Eq[-1].subs(i, n) Eq << Eq[-1].subs(j, hv) k = Eq[-1].function.lhs.function.arg.args[0].indices[-1] Eq.Xv_definition = Eq[1].subs(j, v) Eq << Eq.Xv_definition[k].set.union_comprehension((k, 0, n)) Eq.x_n1_set_comprehension = Eq[-2].subs(Eq[-1].reversed) Eq << Eq.Xv_definition[n] Eq << Eq[0].subs(i, n).subs(j, hv)[n] Eq << Eq[-2].this.rhs.subs(Eq[-1]) Eq << Eq[-1].this.rhs.expand() Eq << Eq[-1].subs(Eq.x_h_equality) Eq << Eq[-1].this.function.as_Or() Eq << (Eq[-1] & Eq.h_domain).split() Eq <<= Eq.x_n1_set_comprehension & Eq[-1] Eq.Xv_in_Qv, Eq.x_eq_swap_Xv = Eq[3].split() Eq << Eq.Xv_in_Qv.definition Eq.indexu_eq_indexu = Eq.x_eq_swap_Xv.function.rhs.args[0].indices[ 1].this.subs(Eq.Xv_definition) Eq.indexu_eq_indexv = Eq.x_slice_domain.apply( discrete.combinatorics.permutation.index.swap, u, v, w=w) Eq.indexu_contains, Eq.x_indexu_equality = Eq.x_slice_domain.apply( discrete.combinatorics.permutation.index.equality, u).split() Eq.equality_of_indexu_and_n = Eq.x_indexu_equality + Eq.x_slice_last.reversed i = Symbol.i(domain=Interval(0, n, integer=True)) j = Symbol.j(domain=Interval(0, n, integer=True)) Eq << Eq.x_slice_domain.apply( discrete.combinatorics.permutation.index.kronecker_delta.indexOf, i, j) x = Eq[-1].variable.base Eq << Eq[-1].subs(i, x[n]).split() Eq << Eq[-2].subs(Eq.x_slice_last) m = Symbol.m(domain=Interval(0, n, integer=True)) Eq.indexOf_indexed = Eq.x_slice_domain.apply( discrete.combinatorics.permutation.index.indexOf_indexed, j=m) Eq << Eq.indexOf_indexed.subs(m, n) Eq << Eq[-2].subs(Eq[-1]) Eq << Eq[-1].subs(j, Eq.equality_of_indexu_and_n.function.lhs).split() Eq << Eq[-2].subs(Eq.x_indexu_equality) Eq << Eq.indexOf_indexed.subs( m, Eq.equality_of_indexu_and_n.function.lhs.indices[0]).split() Eq <<= Eq.indexu_contains & Eq[-2] Eq << Eq[-3].subs(Eq[-1]) Eq << Eq[-1].subs(Eq.equality_of_indexu_and_n) Eq << Eq[-1].this.function.lhs.as_Piecewise() Eq << Eq[-1].this.function.as_Or() Eq << Eq.indexu_eq_indexv.subs(Eq[-1].reversed) Eq << Eq.indexu_eq_indexu.subs(Eq[-1]) Eq << Eq.x_eq_swap_Xv.subs(Eq[-1]) Eq << Eq[-1].subs(Eq.Xv_definition) Eq << algebre.matrix.elementary.swap.multiply.left.apply( x[:n + 1], i=n, j=Eq.h_domain.lhs, w=w) Eq << Eq[-2].subs(Eq[-1])
def test_not_empty_in(): 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_union_RealSubSet(): assert (S.Complexes).union(Interval(1, 2)) == S.Complexes assert (S.Complexes).union(S.Integers) == S.Complexes
def set(self): k = len(self.alpha) return Interval(0, 1)**k
def test_issue_16469(): x = Symbol("x", real=True) f = abs(x) assert function_range(f, x, S.Reals) == Interval(0, oo, False, True)
def set(self): return Intersection(S.Naturals0, Interval(0, self.n))**len(self.p)
def test_multivariate_relational_as_set(): assert (x*y >= 0).as_set() == Interval(0, oo)*Interval(0, oo) + \ Interval(-oo, 0)*Interval(-oo, 0)
def test_core_interval(): for c in (Interval, Interval(0, 2)): check(c)
def test_issue_8777(): assert And(x > 2, x < oo).as_set() == Interval(2, oo, left_open=True) assert And(x >= 1, x < oo).as_set() == Interval(1, oo) assert (x < oo).as_set() == Interval(-oo, oo) assert (x > -oo).as_set() == Interval(-oo, oo)
def function_range(f, symbol, domain): """ Finds the range of a function in a given domain. This method is limited by the ability to determine the singularities and determine limits. Parameters ========== f : :py:class:`~.Expr` The concerned function. symbol : :py:class:`~.Symbol` The variable for which the range of function is to be determined. domain : :py:class:`~.Interval` The domain under which the range of the function has to be found. Examples ======== >>> from sympy import Interval, Symbol, S, exp, log, pi, sqrt, sin, tan >>> from sympy.calculus.util import function_range >>> x = Symbol('x') >>> function_range(sin(x), x, Interval(0, 2*pi)) Interval(-1, 1) >>> function_range(tan(x), x, Interval(-pi/2, pi/2)) Interval(-oo, oo) >>> function_range(1/x, x, S.Reals) Union(Interval.open(-oo, 0), Interval.open(0, oo)) >>> function_range(exp(x), x, S.Reals) Interval.open(0, oo) >>> function_range(log(x), x, S.Reals) Interval(-oo, oo) >>> function_range(sqrt(x), x, Interval(-5, 9)) Interval(0, 3) Returns ======= :py:class:`~.Interval` Union of all ranges for all intervals under domain where function is continuous. Raises ====== NotImplementedError If any of the intervals, in the given domain, for which function is continuous are not finite or real, OR if the critical points of the function on the domain cannot be found. """ if domain is S.EmptySet: return S.EmptySet period = periodicity(f, symbol) if period == S.Zero: # the expression is constant wrt symbol return FiniteSet(f.expand()) from sympy.series.limits import limit from sympy.solvers.solveset import solveset if period is not None: if isinstance(domain, Interval): if (domain.inf - domain.sup).is_infinite: domain = Interval(0, period) elif isinstance(domain, Union): for sub_dom in domain.args: if isinstance(sub_dom, Interval) and \ ((sub_dom.inf - sub_dom.sup).is_infinite): domain = Interval(0, period) intervals = continuous_domain(f, symbol, domain) range_int = S.EmptySet if isinstance(intervals, (Interval, FiniteSet)): interval_iter = (intervals, ) elif isinstance(intervals, Union): interval_iter = intervals.args else: raise NotImplementedError( filldedent(''' Unable to find range for the given domain. ''')) for interval in interval_iter: if isinstance(interval, FiniteSet): for singleton in interval: if singleton in domain: range_int += FiniteSet(f.subs(symbol, singleton)) elif isinstance(interval, Interval): vals = S.EmptySet critical_points = S.EmptySet critical_values = S.EmptySet bounds = ((interval.left_open, interval.inf, '+'), (interval.right_open, interval.sup, '-')) for is_open, limit_point, direction in bounds: if is_open: critical_values += FiniteSet( limit(f, symbol, limit_point, direction)) vals += critical_values else: vals += FiniteSet(f.subs(symbol, limit_point)) solution = solveset(f.diff(symbol), symbol, interval) if not iterable(solution): raise NotImplementedError( 'Unable to find critical points for {}'.format(f)) if isinstance(solution, ImageSet): raise NotImplementedError( 'Infinite number of critical points for {}'.format(f)) critical_points += solution for critical_point in critical_points: vals += FiniteSet(f.subs(symbol, critical_point)) left_open, right_open = False, False if critical_values is not S.EmptySet: if critical_values.inf == vals.inf: left_open = True if critical_values.sup == vals.sup: right_open = True range_int += Interval(vals.inf, vals.sup, left_open, right_open) else: raise NotImplementedError( filldedent(''' Unable to find range for the given domain. ''')) return range_int
def __new__(cls): return Interval.__new__(cls, -S.Infinity, S.Infinity)
def bspline_basis(d, knots, n, x): """ The $n$-th B-spline at $x$ of degree $d$ with knots. Explanation =========== B-Splines are piecewise polynomials of degree $d$. They are defined on a set of knots, which is a sequence of integers or floats. Examples ======== The 0th degree splines have a value of 1 on a single interval: >>> from sympy import bspline_basis >>> from sympy.abc import x >>> d = 0 >>> knots = tuple(range(5)) >>> bspline_basis(d, knots, 0, x) Piecewise((1, (x >= 0) & (x <= 1)), (0, True)) For a given ``(d, knots)`` there are ``len(knots)-d-1`` B-splines defined, that are indexed by ``n`` (starting at 0). Here is an example of a cubic B-spline: >>> bspline_basis(3, tuple(range(5)), 0, x) Piecewise((x**3/6, (x >= 0) & (x <= 1)), (-x**3/2 + 2*x**2 - 2*x + 2/3, (x >= 1) & (x <= 2)), (x**3/2 - 4*x**2 + 10*x - 22/3, (x >= 2) & (x <= 3)), (-x**3/6 + 2*x**2 - 8*x + 32/3, (x >= 3) & (x <= 4)), (0, True)) By repeating knot points, you can introduce discontinuities in the B-splines and their derivatives: >>> d = 1 >>> knots = (0, 0, 2, 3, 4) >>> bspline_basis(d, knots, 0, x) Piecewise((1 - x/2, (x >= 0) & (x <= 2)), (0, True)) It is quite time consuming to construct and evaluate B-splines. If you need to evaluate a B-spline many times, it is best to lambdify them first: >>> from sympy import lambdify >>> d = 3 >>> knots = tuple(range(10)) >>> b0 = bspline_basis(d, knots, 0, x) >>> f = lambdify(x, b0) >>> y = f(0.5) Parameters ========== d : integer degree of bspline knots : list of integer values list of knots points of bspline n : integer $n$-th B-spline x : symbol See Also ======== bspline_basis_set References ========== .. [1] https://en.wikipedia.org/wiki/B-spline """ # make sure x has no assumptions so conditions don't evaluate xvar = x x = Dummy() knots = tuple(sympify(k) for k in knots) d = int(d) n = int(n) n_knots = len(knots) n_intervals = n_knots - 1 if n + d + 1 > n_intervals: raise ValueError("n + d + 1 must not exceed len(knots) - 1") if d == 0: result = Piecewise( (S.One, Interval(knots[n], knots[n + 1]).contains(x)), (0, True) ) elif d > 0: denom = knots[n + d + 1] - knots[n + 1] if denom != S.Zero: B = (knots[n + d + 1] - x) / denom b2 = bspline_basis(d - 1, knots, n + 1, x) else: b2 = B = S.Zero denom = knots[n + d] - knots[n] if denom != S.Zero: A = (x - knots[n]) / denom b1 = bspline_basis(d - 1, knots, n, x) else: b1 = A = S.Zero result = _add_splines(A, b1, B, b2, x) else: raise ValueError("degree must be non-negative: %r" % n) # return result with user-given x return result.xreplace({x: xvar})
def __hash__(self): return hash(Interval(-S.Infinity, S.Infinity))
def test_not_empty_in(): assert not_empty_in( FiniteSet(x, 2 * x).intersect(Interval(1, 2, True, False)), x) == Interval(S.Half, 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.Half, -2), Interval(1, Rational(-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) == Interval(-oo, oo) assert not_empty_in( FiniteSet(4, x / (x - 1)).intersect(Interval(2, 3)), x) == Interval(S(3) / 2, 2) 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)) raises(ValueError, lambda: not_empty_in(x)) raises(ValueError, lambda: not_empty_in(Interval(0, 1), x)) raises(NotImplementedError, lambda: not_empty_in(FiniteSet(x).intersect(S.Reals), x, a))
def _intersect(self, other): if other.is_Interval: return Intersection(S.Integers, other, Interval(self._inf, S.Infinity)) return None
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 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_ComplexRegion_from_real(): c1 = ComplexRegion(Interval(0, 1) * Interval(0, 2 * S.Pi), polar=True) raises(ValueError, lambda: c1.from_real(c1)) assert c1.from_real(Interval(-1, 1)) == ComplexRegion(Interval(-1, 1) * FiniteSet(0), False)
def test_is_convex(): assert is_convex(1 / x, x, domain=Interval(0, oo)) == True assert is_convex(1 / x, x, domain=Interval(-oo, 0)) == False assert is_convex(x**2, x, domain=Interval(0, oo)) == True assert is_convex(log(x), x) == False raises(NotImplementedError, lambda: is_convex(log(x), x, a))
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 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 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))