def isclose(a, b, rel_tol=1e-9, abs_tol=0.0, method='weak'): """ returns True if a is close in value to b. False otherwise :param a: one of the values to be tested :param b: the other value to be tested :param rel_tol=1e-8: The relative tolerance -- the amount of error allowed, relative to the magnitude of the input values. :param abs_tol=0.0: The minimum absolute tolerance level -- useful for comparisons to zero. :param method: The method to use. options are: "asymmetric" : the b value is used for scaling the tolerance "strong" : The tolerance is scaled by the smaller of the two values "weak" : The tolerance is scaled by the larger of the two values "average" : The tolerance is scaled by the average of the two values. NOTES: -inf, inf and NaN behave similar to the IEEE 754 standard. That -is, NaN is not close to anything, even itself. inf and -inf are -only close to themselves. Complex values are compared based on their absolute value. The function can be used with Decimal types, if the tolerance(s) are specified as Decimals:: isclose(a, b, rel_tol=Decimal('1e-9')) See PEP-0485 for a detailed description Copyright: Christopher H. Barker License: Apache License 2.0 http://opensource.org/licenses/apache2.0.php """ if method not in ("asymmetric", "strong", "weak", "average"): raise ValueError('method must be one of: "asymmetric",' ' "strong", "weak", "average"') if rel_tol < 0.0 or abs_tol < 0.0: raise ValueError('error tolerances must be non-negative') if a == b: # short-circuit exact equality return True # use cmath so it will work with complex or float if cmath.isinf(a) or cmath.isinf(b): # This includes the case of two infinities of opposite sign, or # one infinity and one finite number. Two infinities of opposite sign # would otherwise have an infinite relative tolerance. return False diff = abs(b - a) if method == "asymmetric": return (diff <= abs(rel_tol * b)) or (diff <= abs_tol) elif method == "strong": return (((diff <= abs(rel_tol * b)) and (diff <= abs(rel_tol * a))) or (diff <= abs_tol)) elif method == "weak": return (((diff <= abs(rel_tol * b)) or (diff <= abs(rel_tol * a))) or (diff <= abs_tol)) elif method == "average": return ((diff <= abs(rel_tol * (a + b) / 2) or (diff <= abs_tol))) else: raise ValueError('method must be one of:' ' "asymmetric", "strong", "weak", "average"')
def _helper(a, b, s) -> _compare_return_type: # Short-circuits on identity if a == b or ((equal_nan in {"relaxed", True}) and a != a and b != b): return (True, None) # Special-case for NaN comparisions when equal_nan=False if not (equal_nan in {"relaxed", True}) and (a != a or b != b): msg = ("Found {0} and {1} while comparing" + s + "and either one " "is nan and the other isn't, or both are nan and " "equal_nan is False").format(a, b) return (False, msg) diff = abs(a - b) allowed_diff = atol + rtol * abs(b) result = diff <= allowed_diff # Special-case for infinity comparisons # NOTE: if b is inf then allowed_diff will be inf when rtol is not 0 if ((cmath.isinf(a) or cmath.isinf(b)) and a != b): result = False msg = None if not result: if rtol == 0 and atol == 0: msg = f"{a} != {b}" else: msg = (f"Comparing{s}{a} and {b} gives a " f"difference of {diff}, but the allowed difference " f"with rtol={rtol} and atol={atol} is " f"only {allowed_diff}!") return result, msg
def isClose(a,b,rel_tol=1e-9,abs_tol=0.0,method='weak'): ''' returns True if a is close in value to b. False otherwise :param a: one of the values to be tested :param b: the other value to be tested :param rel_tol=1e-8: The relative tolerance -- the amount of error allowed, relative to the magnitude of the input values. :param abs_tol=0.0: The minimum absolute tolerance level -- useful for comparisons to zero. :param method: The method to use. options are: "asymmetric" : the b value is used for scaling the tolerance "strong" : The tolerance is scaled by the smaller of the two values "weak" : The tolerance is scaled by the larger of the two values "average" : The tolerance is scaled by the average of the two values. NOTES: -inf, inf and NaN behave similar to the IEEE 754 standard. That -is, NaN is not close to anything, even itself. inf and -inf are -only close to themselves. Complex values are compared based on their absolute value. The function can be used with Decimal types, if the tolerance(s) are specified as Decimals:: isclose(a, b, rel_tol=Decimal('1e-9')) See PEP-0485 for a detailed description ''' if method not in ("asymmetric", "strong", "weak", "average"): raise ValueError('method must be one of: "asymmetric",' ' "strong", "weak", "average"') if rel_tol < 0.0 or abs_tol < 0.0: raise ValueError('error tolerances must be non-negative') if a == b: # short-circuit exact equality return True # use cmath so it will work with complex or float if cmath.isinf(a) or cmath.isinf(b): # This includes the case of two infinities of opposite sign, or # one infinity and one finite number. Two infinities of opposite sign # would otherwise have an infinite relative tolerance. return False diff = abs(b - a) if method == "asymmetric": return (diff <= abs(rel_tol * b)) or (diff <= abs_tol) elif method == "strong": return (((diff <= abs(rel_tol * b)) and (diff <= abs(rel_tol * a))) or (diff <= abs_tol)) elif method == "weak": return (((diff <= abs(rel_tol * b)) or (diff <= abs(rel_tol * a))) or (diff <= abs_tol)) elif method == "average": return ((diff <= abs(rel_tol * (a + b) / 2) or (diff <= abs_tol))) else: raise ValueError('method must be one of:' ' "asymmetric", "strong", "weak", "average"')
def isClose(a, b, rel_tol=1e-9, abs_tol=0.0, method='weak'): """ code imported from math.isclose python 3.5 """ if method not in ("asymmetric", "strong", "weak", "average"): raise ValueError('method must be one of: "asymmetric",' ' "strong", "weak", "average"') if rel_tol < 0.0 or abs_tol < 0.0: raise ValueError('error tolerances must be non-negative') if a == b: # short-circuit exact equality return True # use cmath so it will work with complex or float if cmath.isinf(a) or cmath.isinf(b): # This includes the case of two infinities of opposite sign, or # one infinity and one finite number. Two infinities of opposite sign # would otherwise have an infinite relative tolerance. return False diff = abs(b - a) if method == "asymmetric": return (diff <= abs(rel_tol * b)) or (diff <= abs_tol) elif method == "strong": return (((diff <= abs(rel_tol * b)) and (diff <= abs(rel_tol * a))) or (diff <= abs_tol)) elif method == "weak": return (((diff <= abs(rel_tol * b)) or (diff <= abs(rel_tol * a))) or (diff <= abs_tol)) elif method == "average": return ((diff <= abs(rel_tol * (a + b) / 2) or (diff <= abs_tol))) else: raise ValueError('method must be one of:' ' "asymmetric", "strong", "weak", "average"')
def compare_with_tolerance(student_complex, instructor_complex, tolerance=default_tolerance, relative_tolerance=False): """ Compare student_complex to instructor_complex with maximum tolerance tolerance. - student_complex : student result (float complex number) - instructor_complex : instructor result (float complex number) - tolerance : float, or string (representing a float or a percentage) - relative_tolerance: bool, to explicitly use passed tolerance as relative Note: when a tolerance is a percentage (i.e. '10%'), it will compute that percentage of the instructor result and yield a number. If relative_tolerance is set to False, it will use that value and the instructor result to define the bounds of valid student result: instructor_complex = 10, tolerance = '10%' will give [9.0, 11.0]. If relative_tolerance is set to True, it will use that value and both instructor result and student result to define the bounds of valid student result: instructor_complex = 10, student_complex = 20, tolerance = '10%' will give [8.0, 12.0]. This is typically used internally to compare float, with a default_tolerance = '0.001%'. Default tolerance of 1e-3% is added to compare two floats for near-equality (to handle machine representation errors). Default tolerance is relative, as the acceptable difference between two floats depends on the magnitude of the floats. (http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/) Examples: In [183]: 0.000016 - 1.6*10**-5 Out[183]: -3.3881317890172014e-21 In [212]: 1.9e24 - 1.9*10**24 Out[212]: 268435456.0 """ if isinstance(tolerance, str): if tolerance == default_tolerance: relative_tolerance = True if tolerance.endswith('%'): tolerance = evaluator(dict(), dict(), tolerance[:-1]) * 0.01 if not relative_tolerance: tolerance = tolerance * abs(instructor_complex) else: tolerance = evaluator(dict(), dict(), tolerance) if relative_tolerance: tolerance = tolerance * max(abs(student_complex), abs(instructor_complex)) if isinf(student_complex) or isinf(instructor_complex): # If an input is infinite, we can end up with `abs(student_complex-instructor_complex)` and # `tolerance` both equal to infinity. Then, below we would have # `inf <= inf` which is a fail. Instead, compare directly. return student_complex == instructor_complex else: # v1 and v2 are, in general, complex numbers: # there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()). return abs(student_complex - instructor_complex) <= tolerance
def evaluate(self): if self.first == self.second: return True if cmath.isinf(self.first) or cmath.isinf(self.second): return False diff = abs(self.second - self.first) return ((diff <= abs(self.rel_tol * self.first)) or (diff <= abs(self.rel_tol * self.second))) or (diff <= self.abs_tol)
def isclose(a, b, rel_tol=1e-9, abs_tol=0.0): if rel_tol < 0.0 or abs_tol < 0.0: raise ValueError('error tolerances must be non-negative') if a == b: # fast-path for exact equality return True if cmath.isinf(a) or cmath.isinf(b): return False diff = abs(b - a) return ((diff <= abs(rel_tol * b)) or (diff <= abs(rel_tol * a)) or (diff <= abs_tol))
def isclose(a, b, rel_tol=1e-9, abs_tol=0.0): if rel_tol < 0.0 or abs_tol < 0.0: raise ValueError('error tolerances must be non-negative') if a == b: # fast-path for exact equality return True if cmath.isinf(a) or cmath.isinf(b): return False diff = abs(b - a) return ( (diff <= abs(rel_tol * b)) or (diff <= abs(rel_tol * a)) or (diff <= abs_tol) )
def test_isinf(self): self.failIf(cmath.isinf(1)) self.failIf(cmath.isinf(1j)) self.failIf(cmath.isinf(NAN)) self.assert_(cmath.isinf(INF)) self.assert_(cmath.isinf(complex(INF, 0))) self.assert_(cmath.isinf(complex(0, INF))) self.assert_(cmath.isinf(complex(INF, INF))) self.assert_(cmath.isinf(complex(NAN, INF))) self.assert_(cmath.isinf(complex(INF, NAN)))
def test_isinf(self): self.assertFalse(cmath.isinf(1)) self.assertFalse(cmath.isinf(1j)) self.assertFalse(cmath.isinf(NAN)) self.assertTrue(cmath.isinf(INF)) self.assertTrue(cmath.isinf(complex(INF, 0))) self.assertTrue(cmath.isinf(complex(0, INF))) self.assertTrue(cmath.isinf(complex(INF, INF))) self.assertTrue(cmath.isinf(complex(NAN, INF))) self.assertTrue(cmath.isinf(complex(INF, NAN)))
def is_integral(x): """Return whether the argument is equal to its integer part.""" if isinstance(x, complex): if x.imag: return False x = x.real return not cmath.isinf(x) and not cmath.isnan(x) and x == int(x)
def q(self, value): self._q = value if value == 0: self.gaussian_spot = ma.inf elif cm.isinf(value): self.gaussian_spot = 0 else: self.gaussian_spot = ma.sqrt(1 / value.real)
def convert(self, value): if isinstance(value, numbers.Rational): return self._searchvalue(float(value)) else: if cmath.isinf(value): return self.inf() elif cmath.isnan(value): raise Exception("cannot cast nan to pnum") else: return self._searchvalue(value)
def compare_with_tolerance(complex1, complex2, tolerance=default_tolerance, relative_tolerance=False): """ Compare complex1 to complex2 with maximum tolerance tol. If tolerance is type string, then it is counted as relative if it ends in %; otherwise, it is absolute. - complex1 : student result (float complex number) - complex2 : instructor result (float complex number) - tolerance : string representing a number or float - relative_tolerance: bool, used when`tolerance` is float to explicitly use passed tolerance as relative. Default tolerance of 1e-3% is added to compare two floats for near-equality (to handle machine representation errors). Default tolerance is relative, as the acceptable difference between two floats depends on the magnitude of the floats. (http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/) Examples: In [183]: 0.000016 - 1.6*10**-5 Out[183]: -3.3881317890172014e-21 In [212]: 1.9e24 - 1.9*10**24 Out[212]: 268435456.0 """ if relative_tolerance: tolerance = tolerance * max(abs(complex1), abs(complex2)) elif tolerance.endswith('%'): tolerance = evaluator(dict(), dict(), tolerance[:-1]) * 0.01 tolerance = tolerance * max(abs(complex1), abs(complex2)) else: tolerance = evaluator(dict(), dict(), tolerance) if isinf(complex1) or isinf(complex2): # If an input is infinite, we can end up with `abs(complex1-complex2)` and # `tolerance` both equal to infinity. Then, below we would have # `inf <= inf` which is a fail. Instead, compare directly. return complex1 == complex2 else: # v1 and v2 are, in general, complex numbers: # there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()). return abs(complex1 - complex2) <= tolerance
def test_isinf(self): import cmath assert not cmath.isinf(2+3j) assert cmath.isinf(float("inf")) assert cmath.isinf(-float("inf")) assert cmath.isinf(complex("infj")) assert cmath.isinf(complex("2-infj")) assert cmath.isinf(complex("inf+nanj")) assert cmath.isinf(complex("nan+infj"))
def q(self, value): self._q = value if value == 0: self.gaussian_spot = ma.inf elif cm.isinf(value): self.gaussian_spot = 0 else: self.gaussian_spot = ma.sqrt(1 / value.real) self.__create_superposition()
def call(cb): for a in angles: res = cb(a) aStr = str(a) if isinf(res): print('angle: ' + aStr + ', value: Infinity') return elif isnan(res): print('angle: ' + aStr + ', value: NaN') return print('angle: ' + aStr + ', value: ' + str(res))
def exp_m(image_array, topleft, xstride, ystride, max_iter): y, x = cuda.grid(2) if x < image_array.shape[1] and y < image_array.shape[0]: c = complex128(topleft + x * xstride - 1j * y * ystride) z = c i = 0 while i < max_iter and not isinf(z): z = exp(z) + c i += 1 get_log_color_rgb(image_array, x, y, i, max_iter)
def compare_with_tolerance(v1, v2, tol): ''' Compare v1 to v2 with maximum tolerance tol tol is relative if it ends in %; otherwise, it is absolute - v1 : student result (number) - v2 : instructor result (number) - tol : tolerance (string representing a number) ''' relative = tol.endswith('%') if relative: tolerance_rel = evaluator(dict(), dict(), tol[:-1]) * 0.01 tolerance = tolerance_rel * max(abs(v1), abs(v2)) else: tolerance = evaluator(dict(), dict(), tol) if isinf(v1) or isinf(v2): # If an input is infinite, we can end up with `abs(v1-v2)` and # `tolerance` both equal to infinity. Then, below we would have # `inf <= inf` which is a fail. Instead, compare directly. return v1 == v2 else: return abs(v1 - v2) <= tolerance
def isinf(x): """ Return True if the real or the imaginary part of x is positive or negative infinity. """ # try: # return [isinf(xi) for xi in x] # except TypeError: if isinstance(x, ADF): return isinf(x.x) else: if x.imag: return cmath.isinf(x) else: return math.isinf(x.real)
def compare_with_tolerance(v1, v2, tol=default_tolerance): ''' Compare v1 to v2 with maximum tolerance tol. tol is relative if it ends in %; otherwise, it is absolute - v1 : student result (float complex number) - v2 : instructor result (float complex number) - tol : tolerance (string representing a number) Default tolerance of 1e-3% is added to compare two floats for near-equality (to handle machine representation errors). It is relative, as the acceptable difference between two floats depends on the magnitude of the floats. (http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/) Examples: In [183]: 0.000016 - 1.6*10**-5 Out[183]: -3.3881317890172014e-21 In [212]: 1.9e24 - 1.9*10**24 Out[212]: 268435456.0 ''' relative = tol.endswith('%') if relative: tolerance_rel = evaluator(dict(), dict(), tol[:-1]) * 0.01 tolerance = tolerance_rel * max(abs(v1), abs(v2)) else: tolerance = evaluator(dict(), dict(), tol) if isinf(v1) or isinf(v2): # If an input is infinite, we can end up with `abs(v1-v2)` and # `tolerance` both equal to infinity. Then, below we would have # `inf <= inf` which is a fail. Instead, compare directly. return v1 == v2 else: # v1 and v2 are, in general, complex numbers: # there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()). return abs(v1 - v2) <= tolerance
def tt_sizecheck(size): """Check whether the given size is valid. Used for Sptensor""" size = np.array(size) isOk = True if size.ndim != 1: isOk = False else: for i in range(0, len(size)): val = size[i] if cmath.isnan(val) or cmath.isinf(val) or val <= 0 or val != round(val): isOk = False if not isOk: raise ValueError("size must be a row vector of real positive integers") return isOk
def tt_subscheck(subs): """Check whether the given list of subscripts are valid. Used for sptensor""" if subs.size == 0: return TRUE if subs.ndim != 2: raise ValueError("Subscript dimensions is incorrect") for i in range(0, (subs.size / subs[0].size)): for j in range(0, (subs[0].size)): val = subs[i][j] # print subs[i][j], val if cmath.isnan(val) or cmath.isinf(val) or val < 0 or val != round(val): raise ValueError("Subscripts must be a matrix of non-negative integers") return True
def _load_(self, value, context): if isinstance(value, complex): pass elif isinstance(value, (integer_types, float)): value = complex(value) elif isinstance(value, (tuple, list)): if len(value) != 2: raise ValueError() if not isinstance(value[0], (integer_types, float)) or not isinstance(value[1], (integer_types, float)): raise ValueError() value = complex(value[0], value[1]) else: raise ValueError() if not self.get_options().allow_nan and (cmath.isnan(value) or cmath.isinf(value)): raise ValueError() return value
def tt_sizecheck(size): """Check whether the given size is valid. Used for sptensor""" size = numpy.array(size) isOk = True if size.ndim != 1: isOk = False else: for i in range(0, len(size)): val = size[i] if cmath.isnan(val) or cmath.isinf(val) or val <= 0 or val != round(val): isOk = False if not isOk: raise ValueError("size must be a row vector of real positive integers") return isOk
def tt_subscheck(subs): """Check whether the given list of subscripts are valid. Used for sptensor""" if (subs.size == 0): return True if (subs.ndim != 2): raise ValueError("Subscript dimensions is incorrect") for i in range(0, (subs.size / subs[0].size)): for j in range(0, (subs[0].size)): val = subs[i][j]; #print subs[i][j], val if( cmath.isnan(val) or cmath.isinf(val) or val < 0 or val != round(val) ): raise ValueError("Subscripts must be a matrix of non-negative integers"); return True;
def tt_sizecheck(size): """Check whether the given size is valid. Used for sptensor""" size = numpy.array(size); isOk = True; if(size.ndim != 1): isOk = False; else: for i in range(0, len(size)): val = size[i]; if(cmath.isnan(val) or cmath.isinf(val) or val <= 0 or val != round(val)): isOk = False; if(not isOk): raise ValueError("size must be a row vector of real positive integers"); return isOk;
def tt_subscheck(my_subs): """Check whether the given list of subscripts are valid. Used for Sptensor""" isOk = True if my_subs.size == 0: isOk = True elif my_subs.ndim != 2: isOk = False else: for i in range(0, (my_subs.size / my_subs[0].size)): for j in range(0, my_subs[0].size): val = my_subs[i][j] if cmath.isnan(val) or cmath.isinf(val) or val < 0 or val != round(val): isOk = False if not isOk: raise ValueError("Subscripts must be a matrix of non-negative integers") return isOk
def tt_subscheck(subs): """Check whether the given list of subscripts are valid. Used for sptensor""" isOk = True; if(subs.size == 0): isOk = True; elif(subs.ndim != 2): isOk = False; else: for i in range(0, (subs.size / subs[0].size)): for j in range(0, (subs[0].size)): val = subs[i][j]; if( cmath.isnan(val) or cmath.isinf(val) or val < 0 or val != round(val) ): isOk = False; if(not isOk): raise ValueError("Subscripts must be a matrix of non-negative integers"); return isOk;
def isinf(x, /) -> bool: '''Return True if x is inf in any direction''' # C methods try: return _math.isinf(x) except Exception: pass try: return _cmath.isinf(x) except Exception: pass # if these fail # allow for customized types try: return bool(x.isinf()) except Exception: pass # otherwise raise TypeError(f'invalid type, type {type(x).__name__}')
def lambert(image_array, topleft, xstride, ystride, max_iter): y, x = cuda.grid(2) if x < image_array.shape[1] and y < image_array.shape[0]: c = complex128(topleft + x * xstride - complex128(1j) * y * ystride) c = exp(c * exp(-c)) z = c o = complex128(0.0) for i in range(max_iter): z = power(c, z) if isinf(z): get_log_color_rgb(image_array, x, y, i, max_iter) return if is_close(z, o): get_log_color_b(image_array, x, y, i, max_iter) return if i % 3 == 0: o = z
print('arc tangent =', cmath.atan(c)) print('sine =', cmath.sin(c)) print('cosine =', cmath.cos(c)) print('tangent =', cmath.tan(c)) # hyperbolic functions c = 2 + 2j print('inverse hyperbolic sine =', cmath.asinh(c)) print('inverse hyperbolic cosine =', cmath.acosh(c)) print('inverse hyperbolic tangent =', cmath.atanh(c)) print('hyperbolic sine =', cmath.sinh(c)) print('hyperbolic cosine =', cmath.cosh(c)) print('hyperbolic tangent =', cmath.tanh(c)) # classification functions print(cmath.isfinite(2 + 2j)) # True print(cmath.isfinite(cmath.inf + 2j)) # False print(cmath.isinf(2 + 2j)) # False print(cmath.isinf(cmath.inf + 2j)) # True print(cmath.isinf(cmath.nan + 2j)) # False print(cmath.isnan(2 + 2j)) # False print(cmath.isnan(cmath.inf + 2j)) # False print(cmath.isnan(cmath.nan + 2j)) # True print(cmath.isclose(2 + 2j, 2.01 + 1.9j, rel_tol=0.05)) # True print(cmath.isclose(2 + 2j, 2.01 + 1.9j, abs_tol=0.005)) # False
def compare_with_tolerance(student_complex, instructor_complex, tolerance=default_tolerance, relative_tolerance=False): """ Compare student_complex to instructor_complex with maximum tolerance tolerance. - student_complex : student result (float complex number) - instructor_complex : instructor result (float complex number) - tolerance : float, or string (representing a float or a percentage) - relative_tolerance: bool, to explicitly use passed tolerance as relative Note: when a tolerance is a percentage (i.e. '10%'), it will compute that percentage of the instructor result and yield a number. If relative_tolerance is set to False, it will use that value and the instructor result to define the bounds of valid student result: instructor_complex = 10, tolerance = '10%' will give [9.0, 11.0]. If relative_tolerance is set to True, it will use that value and both instructor result and student result to define the bounds of valid student result: instructor_complex = 10, student_complex = 20, tolerance = '10%' will give [8.0, 12.0]. This is typically used internally to compare float, with a default_tolerance = '0.001%'. Default tolerance of 1e-3% is added to compare two floats for near-equality (to handle machine representation errors). Default tolerance is relative, as the acceptable difference between two floats depends on the magnitude of the floats. (http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/) Examples: In [183]: 0.000016 - 1.6*10**-5 Out[183]: -3.3881317890172014e-21 In [212]: 1.9e24 - 1.9*10**24 Out[212]: 268435456.0 """ if isinstance(tolerance, str): if tolerance == default_tolerance: relative_tolerance = True if tolerance.endswith('%'): tolerance = evaluator(dict(), dict(), tolerance[:-1]) * 0.01 if not relative_tolerance: tolerance = tolerance * abs(instructor_complex) else: tolerance = evaluator(dict(), dict(), tolerance) if relative_tolerance: tolerance = tolerance * max(abs(student_complex), abs(instructor_complex)) if isinf(student_complex) or isinf(instructor_complex): # If an input is infinite, we can end up with `abs(student_complex-instructor_complex)` and # `tolerance` both equal to infinity. Then, below we would have # `inf <= inf` which is a fail. Instead, compare directly. return student_complex == instructor_complex else: # v1 and v2 are, in general, complex numbers: # there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()). decimal_places = None # count the "decimal_places" for "student_complex". e.g, for # "student_complex" value "152.3667" the "decimal_places" will be # 4 as there are 4 digits "3667" after decimal if isinstance(student_complex, float): decimal_places = Decimal( str(student_complex)).as_tuple().exponent * -1 # pylint: disable=E1103 abs_value = abs(student_complex - instructor_complex) # decimal_places could be NaN in some cases if decimal_places and isinstance(decimal_places, int): # abs_value contains 17 digits exponent value so # round it up to "decimal_places" abs_value = round(abs_value, decimal_places) return abs_value <= tolerance
a = 1 + 1j #Be sure to have a coefficient in front of 'j'! b = complex(2,2) #Defines a complex number '2 + 2i' #Addition, subtraction, multiplication and division works without cmath real_coefficient = a.real complex_coefficient = a.imag polar_angle = cmath.phase(a) polar_radius = abs(a) rectangular_to_polar = cmath.polar(a) polar_to_rectangular = cmath.rect(1, math.pi) e_to_the_a = cmath.exp(a) #Takes 'e' to the power of 'a' square_root = cmath.sqrt(a) logarithm = cmath.log(a,b) #Logarithm of 'a' with base 'n' natural_logarithm = cmath.log(a) #Leaving out the 'n' makes this a natural logarithm log10 = cmath.log10(a) #Logarithm base 10 sine = cmath.sin(a) cosine = cmath.cos(a) tangent = cmath.tan(a) arcsine = cmath.asin(a) arccosine = cmath.acos(a) arctangent = cmath.atan(a) check_for_infinite_value = cmath.isinf(a)
def test_isinf(): assert cmath.isinf(float('inf')) == isinf(float('inf')) assert cmath.isinf(-float('inf')) == isinf(-float('inf')) assert cmath.isinf(float('nan')) == isinf(float('nan')) assert isinf(sympy.oo) assert isinf(-sympy.oo) assert not isinf(sympy.nan) assert cmath.isinf(1.0) == isinf(1.0) assert cmath.isinf(0) == isinf(0) inf = float('inf') nan = float('nan') assert cmath.isinf(complex(inf)) == isinf(complex(inf)) assert cmath.isinf(complex(1, inf)) == isinf(complex(1, inf)) assert cmath.isinf(complex(1, -inf)) == isinf(complex(1, -inf)) assert cmath.isinf(complex(inf, 1)) == isinf(complex(inf, 1)) assert cmath.isinf(complex(inf, inf)) == isinf(complex(inf, inf)) assert cmath.isinf(complex(1, nan)) == isinf(complex(1, nan)) assert cmath.isinf(complex(nan, 1)) == isinf(complex(nan, 1)) assert cmath.isinf(complex(nan, nan)) == isinf(complex(nan, nan))
def ucomplex(z, u, df=inf, label=None, independent=True): """ Create an elementary uncertain complex number :arg z: the value (estimate) :type z: complex :arg u: the standard uncertainty or variance :type u: float, 2-element or 4-element sequence :arg df: the degrees-of-freedom :type df: float :type label: str :rtype: :class:`~lib.UncertainComplex` :raises: :exc:`ValueError` if ``df`` or ``u`` have illegal values. ``u`` can be a float, a 2-element or 4-element sequence. If ``u`` is a float, the standard uncertainty in both the real and imaginary components is taken to be ``u``. If ``u`` is a 2-element sequence, the first element is taken to be the standard uncertainty in the real component and the second element is taken to be the standard uncertainty in the imaginary component. If ``u`` is a 4-element sequence, the sequence is interpreted as a variance-covariance matrix. **Examples**:: >>> uc = ucomplex(1+2j,(.5,.5),3,label='x') >>> uc ucomplex((1+2j), u=[0.5,0.5], r=0.0, df=3.0, label=x) >>> cv = (1.2,0.7,0.7,2.2) >>> uc = ucomplex(0.2-.5j, cv) >>> variance(uc) VarianceCovariance(rr=1.1999999999999997, ri=0.7, ir=0.7, ii=2.2) """ # Arguments to these math functions must be compatible with float # otherwise a TypeError is raised by Python if cmath.isnan(z) or cmath.isinf(z): raise ValueError("invalid: '{!r}'".format(z)) if df < 1 or math.isnan(df): raise ValueError("invalid dof: '{!r}'".format(df)) if is_sequence(u): case = len(u) if case == 2: u_r = float(u[0]) u_i = float(u[1]) r = None elif case == 4: u_r, cv1, cv2, u_i = u # nan != nan is True if math.isinf(cv1) or cv1 != cv2: raise ValueError( "covariance elements not equal: {!r} and {!r}".format( cv1, cv2)) u_r = math.sqrt(u_r) u_i = math.sqrt(u_i) r = cv1 / (u_r * u_i) if cv1 != 0 else None # Allow a little tolerance for numerical imprecision if r is not None and abs(r) > 1 + 1E-10: raise ValueError("invalid correlation: {!r}, cv={}".format( r, u)) if r is not None: # This overrides an initial assignment independent = False else: raise ValueError("invalid uncertainty sequence: '{!r}'".format(u))
def isinf_usecase(x): return cmath.isinf(x)
print('sine =', cmath.sin(c)) print('cosine =', cmath.cos(c)) print('tangent =', cmath.tan(c)) # hyperbolic functions c = 2 + 2j print('inverse hyperbolic sine =', cmath.asinh(c)) print('inverse hyperbolic cosine =', cmath.acosh(c)) print('inverse hyperbolic tangent =', cmath.atanh(c)) print('hyperbolic sine =', cmath.sinh(c)) print('hyperbolic cosine =', cmath.cosh(c)) print('hyperbolic tangent =', cmath.tanh(c)) # classification functions print(cmath.isfinite(2 + 2j)) # True print(cmath.isfinite(cmath.inf + 2j)) # False print(cmath.isinf(2 + 2j)) # False print(cmath.isinf(cmath.inf + 2j)) # True print(cmath.isinf(cmath.nan + 2j)) # False print(cmath.isnan(2 + 2j)) # False print(cmath.isnan(cmath.inf + 2j)) # False print(cmath.isnan(cmath.nan + 2j)) # True print(cmath.isclose(2+2j, 2.01+1.9j, rel_tol=0.05)) # True print(cmath.isclose(2+2j, 2.01+1.9j, abs_tol=0.005)) # False
def nice_float(x): """ Return a short string representation of a floating point number. Taken from the python-nicefloat module <http://labix.org/python-nicefloat>, which is based on the paper "Printing Floating-Point Numbers Quickly and Accurately" by Robert G. Burger and R. Kent Dybvig. """ # Special cases for 0, infinity, and NaN if not x: return '0.' if cmath.isinf(x): if x < 0: return '-Inf' return 'Inf' if cmath.isnan(x): return 'Nan' # Copied from http://labix.org/python-nicefloat f, e = math.frexp(x) if x < 0: f = -f f = int(f * 2**53) e -= 53 if e >= 0: be = 2**e if f != 2**52: r, s, mp, mm = f*be*2, 2, be, be else: be1 = be*2 r, s, mp, mm = f*be1*2, 4, be1, be elif e == -1074 or f != 2**52: r, s, mp, mm = f*2, 2**(1-e), 1, 1 else: r, s, mp, mm = f*4, 2**(2-e), 2, 1 k = 0 round = f % 2 == 0 while not round and r+mp*10 <= s or r+mp*10 < s: r *= 10 mp *= 10 mm *= 10 k -= 1 while round and r+mp >= s or r+mp > s: s *= 10 k += 1 l = [] while True: d, r = divmod(r*10, s) d = int(d) mp *= 10 mm *= 10 tc1 = round and r == mm or r < mm tc2 = round and r+mp == s or r+mp > s if not tc1: if not tc2: l.append(d) continue l.append(d+1) elif not tc2 or r*2 < s: l.append(d) else: l.append(d+1) break if k <= 0: l.insert(0, '0' * abs(k)) l.insert(0, '.') elif k < len(l): l.insert(k, '.') else: l.append('0' * (k - len(l))) l.append('.') n = ''.join(map(str, l)) # Further shorten the string using scientific notation if n.startswith('.000'): n = n[1:] p = 0 while n.startswith('0'): n = n[1:] p -= 1 n1 = (n[0] + '.' + n[1:] + 'e' + str(p-1)).replace('.e', 'e') n2 = n + 'e' + str(p-len(n)) n = n2 if len(n2) < len(n1) else n1 elif n.endswith('00.'): n = n[:-1] p = 0 while n.endswith('0'): n = n[:-1] p += 1 n = n + 'e' + str(p) if x < 0: n = '-' + n return n
def compare_with_tolerance(student_complex, instructor_complex, tolerance=default_tolerance, relative_tolerance=False): """ Compare student_complex to instructor_complex with maximum tolerance tolerance. - student_complex : student result (float complex number) - instructor_complex : instructor result (float complex number) - tolerance : float, or string (representing a float or a percentage) - relative_tolerance: bool, to explicitly use passed tolerance as relative Note: when a tolerance is a percentage (i.e. '10%'), it will compute that percentage of the instructor result and yield a number. If relative_tolerance is set to False, it will use that value and the instructor result to define the bounds of valid student result: instructor_complex = 10, tolerance = '10%' will give [9.0, 11.0]. If relative_tolerance is set to True, it will use that value and both instructor result and student result to define the bounds of valid student result: instructor_complex = 10, student_complex = 20, tolerance = '10%' will give [8.0, 12.0]. This is typically used internally to compare float, with a default_tolerance = '0.001%'. Default tolerance of 1e-3% is added to compare two floats for near-equality (to handle machine representation errors). Default tolerance is relative, as the acceptable difference between two floats depends on the magnitude of the floats. (http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/) Examples: In [183]: 0.000016 - 1.6*10**-5 Out[183]: -3.3881317890172014e-21 In [212]: 1.9e24 - 1.9*10**24 Out[212]: 268435456.0 """ if isinstance(tolerance, str): if tolerance == default_tolerance: relative_tolerance = True if tolerance.endswith('%'): tolerance = evaluator(dict(), dict(), tolerance[:-1]) * 0.01 if not relative_tolerance: tolerance = tolerance * abs(instructor_complex) else: tolerance = evaluator(dict(), dict(), tolerance) if relative_tolerance: tolerance = tolerance * max(abs(student_complex), abs(instructor_complex)) if isinf(student_complex) or isinf(instructor_complex): # If an input is infinite, we can end up with `abs(student_complex-instructor_complex)` and # `tolerance` both equal to infinity. Then, below we would have # `inf <= inf` which is a fail. Instead, compare directly. return student_complex == instructor_complex # because student_complex and instructor_complex are not necessarily # complex here, we enforce it here: student_complex = complex(student_complex) instructor_complex = complex(instructor_complex) # if both the instructor and student input are real, # compare them as Decimals to avoid rounding errors if not (instructor_complex.imag or student_complex.imag): # if either of these are not a number, short circuit and return False if isnan(instructor_complex.real) or isnan(student_complex.real): return False student_decimal = Decimal(str(student_complex.real)) instructor_decimal = Decimal(str(instructor_complex.real)) tolerance_decimal = Decimal(str(tolerance)) return abs(student_decimal - instructor_decimal) <= tolerance_decimal else: # v1 and v2 are, in general, complex numbers: # there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()). return abs(student_complex - instructor_complex) <= tolerance
def __init__(self, domain, mode, freq_def, tags, rho, rho_1d, ifc_1d, xstep=100, zstep=100, maps=None, plot=False, limits=None): """ DESCRIPTION: ------------ Constructor which initialises the 2D magnetotelluric class: (*) check for argument type (*) check for valid argument values (*) initialises required values ARGUMENTS: ---------- param domain :: the 2d mesh domain type domain :: ``escript data object`` param mode :: TE or TM mode type mode :: ``string`` param freq_def :: highest/lowest frequency & points per decade type freq_def :: ``dictionary`` param tags :: the tag names of the regions defined in the mesh type tags :: ``list`` param rho :: the resistivity values of the regions in the mesh type rho :: ``list`` param rho_1d :: the resistivity values at the left & right boundary type rho_1d :: ``dictionary`` param ifc_1d :: the layer interface depths of the left & right boundary type ifc_1d :: ``dictionary`` param xstep :: user-defined step size for horizontal sample list type xstep :: ``number`` (optional) param zstep :: user-defined step size for vertical sample list type zstep :: ``number`` (optional) param maps :: list with user-defined functions which map the resistivity for each region type maps :: ``list`` (optional) param plot :: user-defined flag to show a plot of apparent resistivity and phase at each frequency type plot :: ``boolean`` (optional) DATA ATTRIBUTES: ---------------- self.domain :: escript data object of mesh self.X :: escript data object with all mesh coordinates self.mode :: string with TE or TM mode self.xmin :: float with x-coordinate minimum self.xmax :: float with x-coordinate maximum self.zmin :: float with z-coordinate minimum self.zmax :: float with z-coordinate maximum self.zstep :: number with sample step in vertical direction self.xstep :: number with sample step in horizontal direction self.rho :: list with resistivity values of all regions self.rho_1d :: dictionary with resistivity values at boundaries left/right self.ifc_1d :: dictionary with interface depths at boundaries left/right self.plot :: boolean flag to show plots of apparent resistivity and phase self.sigma :: escript data object with the conductivity model (based on 'rho' and 'maps') self.frequencies :: list of sounding frequencies self.boundary_mask :: Dirichlet mask at boundaries """ if not HAVE_FINLEY: raise ImportError("Finley module not available") #make python3 compatible, since long disappeared in python 3 if sys.version_info[0] == 3: long_type = int else: long_type = long # --- # Checks # --- # Types: if not isinstance(domain, escript.Domain): raise ValueError("Input parameter DOMAIN must be an Escript mesh") if not isinstance(mode, str): raise ValueError("Input parameter MODE must be a string") if not isinstance(freq_def, dict) or len(freq_def) != 3: raise ValueError( "Input parameter FREQ_DEF must be a dictionary with length 3") if not isinstance(tags, list) or not all( isinstance(t, str) for t in tags): raise ValueError("Input parameter TAGS must be a list of strings") if not isinstance(rho, list) or not all( isinstance(d, (int, long_type, float)) for d in rho): raise ValueError("Input parameter RHO must be a list of numbers") if not isinstance(rho_1d, dict) or len(rho_1d) != 2: raise ValueError( "Input parameter RHO_1D must be a dictionary with length 2") if not isinstance(ifc_1d, dict) or len(ifc_1d) != 2: raise ValueError( "Input parameter IFC_1D must be a dictionary with length 2") if not isinstance(xstep, (int, long_type, float)): raise ValueError("Optional input parameter XSTEP must be a number") if not isinstance(zstep, (int, long_type, float)): raise ValueError("Optional input parameter ZSTEP must be a number") if maps is not None: if not isinstance(maps, list) or not all( isinstance(m, (types.FunctionType, types.NoneType)) for m in maps): raise ValueError( "Optional input parameter MAPS must be a list of Functions or Nones" ) if plot is not None: if not isinstance(plot, bool): raise ValueError( "Optional input parameter PLOT must be True or False") # Values: if mode.upper() != "TE" and mode.upper() != "TM": # Check mode: raise ValueError( "Input parameter mode must be either 'TE' or 'TM'") if not 'high' in freq_def and not 'low' in freq_def and not 'step' in freq_def: raise ValueError( "Input dictionary FREQ_DEF must have keys 'high', 'low' and 'step' defined" ) if freq_def['high'] < freq_def['low']: raise ValueError( "High frequency value is smaller than low frequency value in input parameter FREQ_DEF" ) if freq_def['step'] < 1: raise ValueError( "Step frequency value is smaller than 1 in input parameter FREQ_DEF" ) if not all(r > 0 for r in rho): # Check resistivity values: raise ValueError("Input parameter RHO must be all positive") if len(rho) != len(tags): # Check resistivity list-length: raise ValueError( "Input parameter RHO must have the same length as input parameter TAGS" ) if not 'left' in rho_1d and not 'right' in rho_1d: raise ValueError( "Input dictionary RHO_1D must have keys 'left' and 'right' defined" ) if not 'left' in ifc_1d and not 'right' in ifc_1d: raise ValueError( "Input dictionary IFC_1D must have keys 'left' and 'right' defined" ) if len(ifc_1d['left']) - 1 != len(rho_1d['left']) and len( ifc_1d['right']) - 1 != len(rho_1d['right']): raise ValueError( "Lists with values in input dictionary RHO_1D must have length equal to IFC_1D" ) if xstep < 0.5: # Step size should be non-zero but should not be smaller than 0.5m: raise ValueError("Input parameter XSTEP must be at least 0.5") if zstep < 0.5: # Step size should be non-zero but should not be smaller than 0.5m: raise ValueError("Input parameter ZSTEP must be at least 0.5") # --- # Domain coordinates & tags: # --- # Extract the model coordinates.. X = escript.Solution(domain).getX() # Get the Min/Max coordinates: xmin = escript.inf(X[0]) xmax = escript.sup(X[0]) zmin = escript.inf(X[1]) zmax = escript.sup(X[1]) # Get the tag names from the mesh file mesh_tags = escript.getTagNames(domain) if xmin >= xmax or zmin >= zmax: raise ValueError("The mesh limits are not valid (min >= max)") if zmin >= 0: raise ValueError( "The mesh must be defined with a negative vertical axis") if not set(mesh_tags) == set(tags): print("user-tags:", tags) print("mesh-tags:", mesh_tags) raise ValueError( "Input parameter TAGS does not match the tags defined in the mesh" ) # --- # Define the boundary mask: # --- boundary_mask = self.__setBoundaryMask(X) # --- # Calculate list of sounding frequencies: # --- frequencies = self.__getSoundingFrequencies(freq_def) # --- # Tag the domain with conductivity maps: # --- sigma_model = self.__tagDomain(domain, X, tags, rho, maps) # Check for valid values if escript.inf(sigma_model) < 0 or escript.sup(sigma_model) < 0: raise ValueError("Negative conductivity encountered") if cmath.isnan( escript.inf(sigma_model) ) or \ cmath.isnan( escript.sup(sigma_model) ) or \ cmath.isinf( escript.sup(sigma_model) ): raise ValueError("The conductivity model contains NaNs or INFs") # --- # Projector and Locator objects. # --- print("Setting up Escript Locator and Projector objects...") # Setup a list with sample points along the vertical mesh extent, bottom to top: xsample = self.__getSamplePoints(escript.inf(X[0]), escript.sup(X[0]), xstep, constant=0.0) # Get the locations of mesh points at the surface via the Locator object # operating on the continuous function-space (i.e. nodes) of the domain. loc = pdetools.Locator(escript.ContinuousFunction(domain), xsample) # Instantiate the Projector class with smoothing on (fast=False); # the Projector is used to calculate the gradient correctly. proj = pdetools.Projector(domain, reduce=False, fast=False) # --- # Print information: # --- print("") print("=" * 72) print("Escript MT2D, version", self.__version) print("=" * 72) print("Mesh XMin/XMax : ", xmin, xmax) print("Mesh ZMin/ZMax : ", zmin, zmax) print("Number of Tags : ", len(tags)) print("Mapping : ", { True: 'Yes', False: 'No' }[maps is not None]) print("Conductivity Model : ", sigma_model) print("Nr of Frequencies : ", len(frequencies)) print("Start/End/Step (Hz) : ", freq_def["high"], freq_def["low"], freq_def["step"]) print("Mode : ", mode.upper()) print("Solver : ", MT_2D._solver) print("Show plots : ", plot) print("=" * 72) print("") if self._debug: print("Mesh-Info : ") print(domain.print_mesh_info(full=False)) # --- # Set all required variables as data attributes # --- self.domain = domain self.X = X self.mode = mode self.xmin = xmin self.xmax = xmax self.zmin = zmin self.zmax = zmax self.zstep = zstep self.xstep = xstep self.rho = rho self.rho_1d = rho_1d self.ifc_1d = ifc_1d self.plot = plot self.limits = limits self.sigma = sigma_model self.frequencies = frequencies self.boundary_mask = boundary_mask self.proj = proj self.loc = loc