def sin(x): """evaluates the sine of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.sin(x)) elif isinstance(x, interval): if not x.is_valid: return interval(-1, 1, is_valid=x.is_valid) na, __ = divmod(x.start, np.pi / 2.0) nb, __ = divmod(x.end, np.pi / 2.0) start = min(np.sin(x.start), np.sin(x.end)) end = max(np.sin(x.start), np.sin(x.end)) if nb - na > 4: return interval(-1, 1, is_valid=x.is_valid) elif na == nb: return interval(start, end, is_valid=x.is_valid) else: if (na - 1) // 4 != (nb - 1) // 4: # sin has max end = 1 if (na - 3) // 4 != (nb - 3) // 4: # sin has min start = -1 return interval(start, end) else: # pragma: no cover raise NotImplementedError
def cos(x): """Evaluates the cos of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.sin(x)) elif isinstance(x, interval): if not (np.isfinite(x.start) and np.isfinite(x.end)): return interval(-1, 1, is_valid=x.is_valid) na, __ = divmod(x.start, np.pi / 2.0) nb, __ = divmod(x.end, np.pi / 2.0) start = min(np.cos(x.start), np.cos(x.end)) end = max(np.cos(x.start), np.cos(x.end)) if nb - na > 4: # differ more than 2*pi return interval(-1, 1, is_valid=x.is_valid) elif na == nb: # in the same quadarant return interval(start, end, is_valid=x.is_valid) else: if (na) // 4 != (nb) // 4: # cos has max end = 1 if (na - 2) // 4 != (nb - 2) // 4: # cos has min start = -1 return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def test_tan(): a = tan(interval(0, np.pi / 4)) assert a.start == 0 assert a.end == np.tan(np.pi / 4) a = tan(interval(np.pi / 4, 3 * np.pi / 4)) # discontinuity assert a.is_valid is None
def exp(x): """evaluates the exponential of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.exp(x), np.exp(x)) elif isinstance(x, interval): return interval(np.exp(x.start), np.exp(x.end), is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def tanh(x): """Evaluates the hyperbolic tan of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.tanh(x), np.tanh(x)) elif isinstance(x, interval): return interval(np.tanh(x.start), np.tanh(x.end), is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def test_exp(): a = exp(interval(-np.inf, 0)) assert a.start == np.exp(-np.inf) assert a.end == np.exp(0) a = exp(interval(1, 2)) assert a.start == np.exp(1) assert a.end == np.exp(2) a = exp(1) assert a.start == np.exp(1) assert a.end == np.exp(1)
def asinh(x): """Evaluates the inverse hyperbolic sine of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.arcsinh(x)) elif isinstance(x, interval): start = np.arcsinh(x.start) end = np.arcsinh(x.end) return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover return NotImplementedError
def atan(x): """evaluates the tan inverse of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.arctan(x)) elif isinstance(x, interval): start = np.arctan(x.start) end = np.arctan(x.end) return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def Abs(x): if isinstance(x, (int, float)): return interval(abs(x)) elif isinstance(x, interval): if x.start < 0 and x.end > 0: return interval(0, max(abs(x.start), abs(x.end)), is_valid=x.is_valid) else: return interval(abs(x.start), abs(x.end)) else: # pragma: no cover raise NotImplementedError
def test_log10(): a = log10(interval(1, 2)) assert a.start == 0 assert a.end == np.log10(2) a = log10(interval(-1, 1)) assert a.is_valid is None a = log10(interval(-3, -1)) assert a.is_valid is False a = log10(-3) assert a.is_valid is False a = log10(2) assert a.start == np.log10(2) assert a.end == np.log10(2)
def test_hashable(): ''' test that interval objects are hashable. this is required in order to be able to put them into the cache, which appears to be necessary for plotting in py3k. For details, see: https://github.com/sympy/sympy/pull/2101 https://github.com/sympy/sympy/issues/6533 ''' hash(interval(1, 1)) hash(interval(1, 1, is_valid=True)) hash(interval(-4, -0.5)) hash(interval(-2, -0.5)) hash(interval(0.25, 8.0))
def test_cosh(): a = cosh(interval(1, 2)) assert a.start == np.cosh(1) assert a.end == np.cosh(2) a = cosh(interval(-2, -1)) assert a.start == np.cosh(-1) assert a.end == np.cosh(-2) a = cosh(interval(-2, 1)) assert a.start == 1 assert a.end == np.cosh(-2) a = cosh(1) assert a.start == np.cosh(1) assert a.end == np.cosh(1)
def test_acosh(): a = acosh(interval(3, 5)) assert a.start == np.arccosh(3) assert a.end == np.arccosh(5) a = acosh(interval(0, 3)) assert a.is_valid is None a = acosh(interval(-3, 0.5)) assert a.is_valid is False a = acosh(0.5) assert a.is_valid is False a = acosh(2) assert a.start == np.arccosh(2) assert a.end == np.arccosh(2)
def test_ceil(): a = ceil(interval(0.2, 0.5)) assert a.start == 1 assert a.end == 1 a = ceil(interval(0.5, 1.5)) assert a.start == 1 assert a.end == 2 assert a.is_valid is None a = ceil(interval(-5, 5)) assert a.is_valid is None a = ceil(5.4) assert a.start == 6 assert a.end == 6
def test_floor(): a = floor(interval(0.2, 0.5)) assert a.start == 0 assert a.end == 0 a = floor(interval(0.5, 1.5)) assert a.start == 0 assert a.end == 1 assert a.is_valid is None a = floor(interval(-5, 5)) assert a.is_valid is None a = floor(5.4) assert a.start == 5 assert a.end == 5
def test_atan(): a = atan(interval(0, 1)) assert a.start == np.arctan(0) assert a.end == np.arctan(1) a = atan(1) assert a.start == np.arctan(1) assert a.end == np.arctan(1)
def test_tanh(): a = tanh(interval(-3, 3)) assert a.start == np.tanh(-3) assert a.end == np.tanh(3) a = tanh(3) assert a.start == np.tanh(3) assert a.end == np.tanh(3)
def test_sinh(): a = sinh(interval(-1, 1)) assert a.start == np.sinh(-1) assert a.end == np.sinh(1) a = sinh(1) assert a.start == np.sinh(1) assert a.end == np.sinh(1)
def test_atanh(): a = atanh(interval(-0.5, 0.5)) assert a.start == np.arctanh(-0.5) assert a.end == np.arctanh(0.5) a = atanh(interval(0, 3)) assert a.is_valid is None a = atanh(interval(-3, -2)) assert a.is_valid is False a = atanh(0.5) assert a.start == np.arctanh(0.5) assert a.end == np.arctanh(0.5) a = atanh(1.5) assert a.is_valid is False
def test_asinh(): a = asinh(interval(1, 2)) assert a.start == np.arcsinh(1) assert a.end == np.arcsinh(2) a = asinh(0.5) assert a.start == np.arcsinh(0.5) assert a.end == np.arcsinh(0.5)
def cosh(x): """Evaluates the hyperbolic cos of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.cosh(x), np.cosh(x)) elif isinstance(x, interval): # both signs if x.start < 0 and x.end > 0: end = max(np.cosh(x.start), np.cosh(x.end)) return interval(1, end, is_valid=x.is_valid) else: # Monotonic start = np.cosh(x.start) end = np.cosh(x.end) return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def test_cos(): a = cos(interval(0, np.pi / 4)) assert a.start == np.cos(np.pi / 4) assert a.end == 1 a = cos(interval(-np.pi / 4, np.pi / 4)) assert a.start == np.cos(-np.pi / 4) assert a.end == 1 a = cos(interval(np.pi / 4, 3 * np.pi / 4)) assert a.start == np.cos(3 * np.pi / 4) assert a.end == np.cos(np.pi / 4) a = cos(interval(3 * np.pi / 4, 5 * np.pi / 4)) assert a.start == -1 assert a.end == np.cos(3 * np.pi / 4) a = cos(interval(0, 3 * np.pi)) assert a.start == -1 assert a.end == 1 a = cos(interval(-np.pi / 3, 5 * np.pi / 4)) assert a.start == -1 assert a.end == 1 a = cos(interval(1, 2, is_valid=False)) assert a.is_valid is False
def test_sin(): a = sin(interval(0, np.pi / 4)) assert a.start == np.sin(0) assert a.end == np.sin(np.pi / 4) a = sin(interval(-np.pi / 4, np.pi / 4)) assert a.start == np.sin(-np.pi / 4) assert a.end == np.sin(np.pi / 4) a = sin(interval(np.pi / 4, 3 * np.pi / 4)) assert a.start == np.sin(np.pi / 4) assert a.end == 1 a = sin(interval(7 * np.pi / 6, 7 * np.pi / 4)) assert a.start == -1 assert a.end == np.sin(7 * np.pi / 6) a = sin(interval(0, 3 * np.pi)) assert a.start == -1 assert a.end == 1 a = sin(interval(np.pi / 3, 7 * np.pi / 4)) assert a.start == -1 assert a.end == 1 a = sin(np.pi / 4) assert a.start == np.sin(np.pi / 4) assert a.end == np.sin(np.pi / 4) a = sin(interval(1, 2, is_valid=False)) assert a.is_valid is False
def floor(x): """Evaluates the floor of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): return interval(np.floor(x)) elif isinstance(x, interval): if x.is_valid is False: return interval(-np.inf, np.inf, is_valid=False) else: start = np.floor(x.start) end = np.floor(x.end) # continuous over the argument if start == end: return interval(start, end, is_valid=x.is_valid) else: # not continuous over the interval return interval(start, end, is_valid=None) else: # pragma: no cover return NotImplementedError
def test_sqrt(): a = sqrt(interval(1, 4)) assert a.start == 1 assert a.end == 2 a = sqrt(interval(0.01, 1)) assert a.start == np.sqrt(0.01) assert a.end == 1 a = sqrt(interval(-1, 1)) assert a.is_valid is None a = sqrt(interval(-3, -1)) assert a.is_valid is False a = sqrt(4) assert (a == interval(2, 2)) == (True, True) a = sqrt(-3) assert a.is_valid is False
def sqrt(x): """Evaluates the square root of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): if x > 0: return interval(np.sqrt(x)) else: return interval(-np.inf, np.inf, is_valid=False) elif isinstance(x, interval): # Outside the domain if x.end < 0: return interval(-np.inf, np.inf, is_valid=False) # Partially outside the domain elif x.start < 0: return interval(-np.inf, np.inf, is_valid=None) else: return interval(np.sqrt(x.start), np.sqrt(x.end), is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def atanh(x): """Evaluates the inverse hyperbolic tangent of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): # Outside the domain if abs(x) >= 1: return interval(-np.inf, np.inf, is_valid=False) else: return interval(np.arctanh(x)) elif isinstance(x, interval): # outside the domain if x.is_valid is False or x.start >= 1 or x.end <= -1: return interval(-np.inf, np.inf, is_valid=False) # partly outside the domain elif x.start <= -1 or x.end >= 1: return interval(-np.inf, np.inf, is_valid=None) else: start = np.arctanh(x.start) end = np.arctanh(x.end) return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover return NotImplementedError
def acosh(x): """Evaluates the inverse hyperbolic cosine of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): # Outside the domain if x < 1: return interval(-np.inf, np.inf, is_valid=False) else: return interval(np.arccosh(x)) elif isinstance(x, interval): # Outside the domain if x.end < 1: return interval(-np.inf, np.inf, is_valid=False) # Partly outside the domain elif x.start < 1: return interval(-np.inf, np.inf, is_valid=None) else: start = np.arccosh(x.start) end = np.arccosh(x.end) return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover return NotImplementedError
def acos(x): """Evaluates the inverse cos of an interval""" np = import_module('numpy') if isinstance(x, (int, float)): if abs(x) > 1: # Outside the domain return interval(-np.inf, np.inf, is_valid=False) else: return interval(np.arccos(x), np.arccos(x)) elif isinstance(x, interval): # Outside the domain if x.is_valid is False or x.start > 1 or x.end < -1: return interval(-np.inf, np.inf, is_valid=False) # Partially outside the domain elif x.start < -1 or x.end > 1: return interval(-np.inf, np.inf, is_valid=None) else: start = np.arccos(x.start) end = np.arccos(x.end) return interval(start, end, is_valid=x.is_valid) else: # pragma: no cover raise NotImplementedError
def test_acos(): a = acos(interval(-0.5, 0.5)) assert a.start == np.arccos(0.5) assert a.end == np.arccos(-0.5) a = acos(interval(-1.5, 1.5)) assert a.is_valid is None a = acos(interval(-2, -1.5)) assert a.is_valid is False a = acos(interval(0, 2)) assert a.is_valid is None a = acos(interval(2, 5)) assert a.is_valid is False a = acos(0.5) assert a.start == np.arccos(0.5) assert a.end == np.arccos(0.5) a = acos(1.5) assert a.is_valid is False