def _prep(lower, upper=None): """ Helper to prepare the lower and upper bound EXAMPLES:: sage: RealSet._prep(1, 0) (0, 1) sage: RealSet._prep(oo) +Infinity """ if lower == minus_infinity: lower = minus_infinity if lower == infinity: lower = infinity else: lower = RLF(lower) if upper is None: return lower if upper == minus_infinity: upper = minus_infinity if upper == infinity: upper = infinity else: upper = RLF(upper) if upper is infinity or lower is minus_infinity: return lower, upper elif lower is infinity or upper is minus_infinity: return upper, lower elif upper < lower: return upper, lower else: return lower, upper
def rel_to_interval(op, val): """ Internal helper function. """ oo = infinity try: val = val.pyobject() except AttributeError: pass val = RLF(val) if op == eq: return [InternalRealInterval(val, True, val, True)] elif op == ne: return [ InternalRealInterval(-oo, False, val, False), InternalRealInterval(val, False, oo, False) ] elif op == gt: return [InternalRealInterval(val, False, oo, False)] elif op == ge: return [InternalRealInterval(val, True, oo, False)] elif op == lt: return [InternalRealInterval(-oo, False, val, False)] else: return [InternalRealInterval(-oo, False, val, True)]
def contains(self, x): """ Return whether `x` is contained in the set INPUT: - ``x`` -- a real number. OUTPUT: Boolean. EXAMPLES:: sage: s = RealSet(0,2) + RealSet.unbounded_above_closed(10); s (0, 2) + [10, +oo) sage: s.contains(1) True sage: s.contains(0) False sage: 10 in s # syntactic sugar True """ x = RLF(x) for interval in self._intervals: if interval.contains(x): return True return False
def intersection(self, other): """ Return the intersection of the two intervals INPUT: - ``other`` -- a :class:`RealInterval` OUTPUT: The intersection as a new :class:`RealInterval` EXAMPLES:: sage: I1 = RealSet.open(0, 2)[0]; I1 (0, 2) sage: I2 = RealSet.closed(1, 3)[0]; I2 [1, 3] sage: I1.intersection(I2) [1, 2) sage: I2.intersection(I1) [1, 2) sage: I1.closure().intersection(I2.interior()) (1, 2] sage: I2.interior().intersection(I1.closure()) (1, 2] sage: I3 = RealSet.closed(10, 11)[0]; I3 [10, 11] sage: I1.intersection(I3) (0, 0) sage: I3.intersection(I1) (0, 0) """ lower = upper = None lower_closed = upper_closed = None if self._lower < other._lower: lower = other._lower lower_closed = other._lower_closed elif self._lower > other._lower: lower = self._lower lower_closed = self._lower_closed else: lower = self._lower lower_closed = self._lower_closed and other._lower_closed if self._upper > other._upper: upper = other._upper upper_closed = other._upper_closed elif self._upper < other._upper: upper = self._upper upper_closed = self._upper_closed else: upper = self._upper upper_closed = self._upper_closed and other._upper_closed if lower > upper: lower = upper = RLF(0) lower_closed = upper_closed = False return InternalRealInterval(lower, lower_closed, upper, upper_closed)
def complement(self): """ Return the complement OUTPUT: The set-theoretic complement as a new :class:`RealSet`. EXAMPLES:: sage: RealSet(0,1).complement() (-oo, 0] + [1, +oo) sage: s1 = RealSet(0,2) + RealSet.unbounded_above_closed(10); s1 (0, 2) + [10, +oo) sage: s1.complement() (-oo, 0] + [2, 10) sage: s2 = RealSet(1,3) + RealSet.unbounded_below_closed(-10); s2 (-oo, -10] + (1, 3) sage: s2.complement() (-10, 1] + [3, +oo) """ n = self.n_components() if n == 0: return RealSet(minus_infinity, infinity) intervals = [] if self.inf() != minus_infinity: first = self._intervals[0] intervals.append( InternalRealInterval(RLF(minus_infinity), False, first._lower, first.lower_open())) if self.sup() != infinity: last = self._intervals[-1] intervals.append( InternalRealInterval(last._upper, last.upper_open(), RLF(infinity), False)) for i in range(1, n): prev = self._intervals[i - 1] next = self._intervals[i] i = InternalRealInterval(prev._upper, prev.upper_open(), next._lower, next.lower_open()) intervals.append(i) return RealSet(*intervals)
def unbounded_below_open(bound): """ Construct a semi-infinite interval INPUT: - ``bound`` -- a real number. OUTPUT: A new :class:`RealSet` from minus infinity to the bound (excluding). EXAMPLES:: sage: RealSet.unbounded_below_open(1) (-oo, 1) """ bound = RealSet._prep(bound) return RealSet(InternalRealInterval(RLF(minus_infinity), False, RLF(bound), False))
def unbounded_above_open(bound): """ Construct a semi-infinite interval INPUT: - ``bound`` -- a real number. OUTPUT: A new :class:`RealSet` from the bound (excluding) to plus infinity. EXAMPLES:: sage: RealSet.unbounded_above_open(1) (1, +oo) """ bound = RealSet._prep(bound) return RealSet(InternalRealInterval(RLF(bound), False, RLF(infinity), False))
def __mul__(self, right): r""" Scale an interval by a scalar on the left or right. If scaled with a negative number, the interval is flipped. EXAMPLES:: sage: i = RealSet.open_closed(0,2)[0]; i (0, 2] sage: 2 * i (0, 4] sage: 0 * i {0} sage: (-2) * i [-4, 0) sage: i * (-3) [-6, 0) sage: i * 0 {0} sage: i * 1 (0, 2] TESTS:: sage: from sage.sets.real_set import InternalRealInterval sage: i = InternalRealInterval(RLF(0), False, RLF(0), False) sage: (0 * i).is_empty() True """ if not isinstance(right, InternalRealInterval): right = RLF(right) if self.is_empty(): return self lower = self._lower * right lower_closed = self._lower_closed upper = self._upper * right upper_closed = self._upper_closed scalar = right elif not isinstance(self, InternalRealInterval): self = RLF(self) if right.is_empty(): return right lower = self * right._lower lower_closed = right._lower_closed upper = self * right._upper upper_closed = right._upper_closed scalar = self else: return NotImplemented if scalar == RLF(0): return InternalRealInterval(RLF(0), True, RLF(0), True) elif scalar < RLF(0): lower, lower_closed, upper, upper_closed = upper, upper_closed, lower, lower_closed if lower == -infinity: lower = -infinity if upper == infinity: upper = infinity return InternalRealInterval(lower, lower_closed, upper, upper_closed)