def diameter(self): """Returns the distance between supremum and infimum of the interval Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> IReal(-10, 1).diameter() 11.0 >>> IReal().diameter() # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> IReal("undefined").diameter() # doctest: +ELLIPSIS Traceback (most recent call last): ... UndefinedIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if self.empty: raise EmptyIntervalError() if self.undefined: raise UndefinedIntervalError() rounding_mode_backup = rounding.get_mode() rounding.set_mode(1) ret = self.sup - self.inf rounding.set_mode(rounding_mode_backup) return ret
def middle(self): """Returns the middle point of the interval Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> IReal(-10, 5).middle() -2.5 >>> IReal().middle() # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> IReal("undefined").middle() # doctest: +ELLIPSIS Traceback (most recent call last): ... UndefinedIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if self.empty: raise EmptyIntervalError() if self.undefined: raise UndefinedIntervalError() rounding_mode_backup = rounding.get_mode() rounding.set_mode(1) ret = (self.inf + self.sup) / 2.0 rounding.set_mode(rounding_mode_backup) return ret
def _parse_limits(inf, sup): """Adjusts the entered limits applying directed rounding if possible Some examples of how it works are below: >>> rounding_mode_backup = rounding.get_mode() >>> x = _parse_limits(0.1, 0.1); x[0] == x[1] True >>> x = _parse_limits("0.1", "0.1"); x[0] < x[1] and str(x[0]) == str(x[1]) True >>> x = _parse_limits("0.25", 0.25); x[0] == x[1] True >>> x = _parse_limits("0.1", "0.3") >>> x[0] < 0.1 and x[1] > 0.3 and str(x[0]) == "0.1" and str(x[1]) == "0.3" True >>> _parse_limits(1, "1e1000") # doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: 'inf' or 'sup' fraction parts are too large... >>> _parse_limits("1e1000", 1) # doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: 'inf' or 'sup' fraction parts are too large... >>> rounding_mode_backup == rounding.get_mode() True """ new_inf, new_sup = inf, sup try: rounding_mode_backup = rounding.get_mode() if type(inf) == type(str()): number_fraction = rational2fraction(inf) rounding.set_mode(0) fp_numerator = float(number_fraction[0]) fp_denominator = float(number_fraction[1]) rounding.set_mode(-1) new_inf = fp_numerator / fp_denominator if type(sup) == type(str()): if inf != sup: number_fraction = rational2fraction(sup) rounding.set_mode(0) fp_numerator = float(number_fraction[0]) fp_denominator = float(number_fraction[1]) rounding.set_mode(1) new_sup = fp_numerator / fp_denominator except OverflowError: raise OverflowError("'inf' or 'sup' fraction parts are too large to" " convert them to float") finally: rounding.set_mode(rounding_mode_backup) return (float(new_inf), float(new_sup))
def distance(self, other): """Returns the Hausdorff distance of the interval Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> IReal(-10, 5).distance(IReal(10)) 20.0 >>> IReal(-10, 5).distance(IReal(10, 50)) 45.0 >>> x = IReal(-10, 5); x.distance(x) 0.0 >>> IReal(-1).distance(IReal()) # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> IReal().distance(IReal(-1)) # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> IReal("undefined").distance(IReal(12)) # doctest: +ELLIPSIS Traceback (most recent call last): ... UndefinedIntervalError:... >>> IReal(10).distance(IReal("undefined")) # doctest: +ELLIPSIS Traceback (most recent call last): ... UndefinedIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if self.empty or other.empty: raise EmptyIntervalError() if self.undefined or other.undefined: raise UndefinedIntervalError() rounding_mode_backup = rounding.get_mode() rounding.set_mode(1) ret = max(abs(self.inf-other.inf), abs(self.sup-other.sup)) rounding.set_mode(rounding_mode_backup) return ret
def __mul__(self, other): """Multiplication operator Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> IReal(0.25, 0.5) * IReal(2, 3) [0.5, 1.5] >>> IReal(-0.75, 0.75) * 2 [-1.5, 1.5] >>> x = IReal("0.1") * "0.1" >>> x.inf < x.sup and str(x.inf) == str(x.sup) True >>> IReal("undefined") * 2 undefined interval >>> IReal(2) * IReal() # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if type(other) != type(self): other = IReal(other) if self.empty or other.empty: raise EmptyIntervalError() x1, y1, x2, y2 = self.inf, self.sup, other.inf, other.sup rounding_mode_backup = rounding.get_mode() rounding.set_mode(-1) inf = min(x1*x2, x1*y2, y1*x2, y1*y2) rounding.set_mode(1) sup = max(x1*x2, x1*y2, y1*x2, y1*y2) rounding.set_mode(rounding_mode_backup) return IReal(inf, sup)
def __sub__(self, other): """Binary minus operator Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> IReal(0.25, 0.5) - IReal(2) [-1.75, -1.5] >>> IReal(-0.75, 0.75) - 2 [-2.75, -1.25] >>> x = IReal("0.1") - "0.1" >>> x.inf < x.sup and str(-x.inf) == str(x.sup) True >>> IReal("undefined") + 2 undefined interval >>> IReal(2) + IReal() # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if type(other) != type(self): other = IReal(other) if self.empty or other.empty: raise EmptyIntervalError() rounding_mode_backup = rounding.get_mode() rounding.set_mode(-1) inf = self.inf - other.sup rounding.set_mode(1) sup = self.sup - other.inf rounding.set_mode(rounding_mode_backup) return IReal(inf, sup)
def __invert__(self): """Inversion operator Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> ~IReal(0.25, 0.5) [2.0, 4.0] >>> x = ~IReal(0.1); x.inf < x.sup and str(x.inf) == str(x.sup) True >>> ~IReal("undefined") undefined interval >>> ~IReal(-2, 2) undefined interval >>> ~IReal() # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if self.empty: raise EmptyIntervalError() if 0.0 in self: return IReal("undefined") rounding_mode_backup = rounding.get_mode() rounding.set_mode(-1) inf = 1.0 / self.sup rounding.set_mode(1) sup = 1.0 / self.inf rounding.set_mode(rounding_mode_backup) return IReal(inf, sup)
def __div__(self, other): """Division operator Some examples: >>> rounding_mode_backup = rounding.get_mode() >>> IReal(0.25, 0.5) / IReal(2, 4) [0.0625, 0.25] >>> IReal(-0.75, 0.75) / 2 [-0.375, 0.375] >>> x = IReal("0.1") / "0.1" >>> x.inf < x.sup and str(x.inf) == str(x.sup) True >>> IReal(1) / IReal(-2, 2) undefined interval >>> IReal("undefined") / 2 undefined interval >>> IReal(2) / IReal() # doctest: +ELLIPSIS Traceback (most recent call last): ... EmptyIntervalError:... >>> rounding_mode_backup == rounding.get_mode() True """ if type(other) != type(self): other = IReal(other) if self.empty or other.empty: raise EmptyIntervalError() if 0.0 in other: return IReal("undefined") x1, y1, x2, y2 = self.inf, self.sup, other.inf, other.sup rounding_mode_backup = rounding.get_mode() rounding.set_mode(-1) inf = min(x1/x2, x1/y2, y1/x2, y1/y2) rounding.set_mode(1) sup = max(x1/x2, x1/y2, y1/x2, y1/y2) rounding.set_mode(rounding_mode_backup) return IReal(inf, sup)