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"')
Exemple #2
0
    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
Exemple #3
0
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"')
Exemple #4
0
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"')
Exemple #5
0
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
Exemple #6
0
    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)
Exemple #7
0
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))
Exemple #8
0
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)
        )
Exemple #9
0
 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.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)))
Exemple #12
0
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)
Exemple #13
0
 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)
Exemple #14
0
 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)
Exemple #15
0
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
Exemple #16
0
 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"))
Exemple #17
0
 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"))
Exemple #18
0
    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()
Exemple #19
0
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
Exemple #20
0
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)
Exemple #22
0
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
Exemple #23
0
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)
Exemple #24
0
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 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"')
Exemple #26
0
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
Exemple #27
0
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
Exemple #28
0
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
Exemple #29
0
 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
Exemple #30
0
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
Exemple #31
0
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;
Exemple #32
0
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;
Exemple #33
0
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
Exemple #34
0
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;
Exemple #35
0
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;
Exemple #36
0
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
Exemple #38
0
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
Exemple #39
0
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
Exemple #40
0
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)
Exemple #41
0
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))
Exemple #42
0
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))
Exemple #43
0
def isinf_usecase(x):
    return cmath.isinf(x)
Exemple #44
0
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
Exemple #46
0
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
Exemple #47
0
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
Exemple #48
0
    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