#!/usr/bin/python -tt #======================================================================= # General Documentation """Single-function module. See function docstring for description. """ #----------------------------------------------------------------------- # Additional Documentation # # RCS Revision Code: # $Id: has_close.py,v 1.1 2004/02/14 01:00:27 jlin Exp $ # # Modification History: # - 13 Feb 2004: Original by Johnny Lin, Computation Institute, # University of Chicago. Passed passably reasonable tests. # # Notes: # - Written for Python 2.2.2. # - Function is based on code from the MA module by Paul F. Dubois. # Some snippets of code in this function are copied directly from # lines in that module. # - Module docstrings can be tested using the doctest module. To # test, execute "python has_close.py". # - See import statements throughout for packages/modules required. # # Copyright (c) 2004 by Johnny Lin. For licensing, distribution # conditions, contact information, and additional documentation see # the URL http://www.johnny-lin.com/pylib.html. #======================================================================= #--------------------------- General Function -------------------------- def has_close(data, value, rtol=1.e-5, atol=1.e-8): """Test if data has any values "equal" to value. Returns 1 if any of the elements of argument data has a value "equal" to argument value; returns 0 otherwise. If data or value is floating point, "equal" means where abs(data-value) <= atol + rtol * abs(value). This is essentially the same algorithm used in the Numeric function allclose. If data and value are integer, "equal" means strict equality. Positional Input Arguments: * data: Data. Scalar or Numeric array, Python list/tuple of any size and shape. * value: Test value. Scalar or 1 element Numeric array, list, or tuple. Keyword Input Arguments: * rtol: "Relative" tolerance. Default is 1.e-5. Used in the comparison between data and value only if the two are floating point. * atol: "Absolute" tolerance. Default is 1.e-8. Used in the comparison between data and value only if the two are floating point. Examples: >>> from has_close import has_close >>> data = [20., -32., -1., 2., 5., 29.] >>> has_close(data, -1.) 1 >>> has_close(data, 10.) 0 """ import MA import Numeric as N abs = N.absolute #- Make sure data is Numeric type and value is a scalar within the # function: dataN = N.array(data) valueS = N.array(value)[0] #- Safe compare if floating. Strict compare if integer. Any other # type returns an error: if (dataN.typecode() in N.typecodes['Float']) or \ (type(valueS) == type(1.)): closemask = N.less_equal(abs(dataN-valueS), atol+rtol*abs(valueS)) elif (dataN.typecode() in N.typecodes['Integer']) and \ (type(valueS) == type(1)): closemask = N.where(dataN == valueS, 1, 0) else: raise ValueError, "has_close: Inputs must be Float or Integer" #- Return true if any elements of data has value: if MA.maximum(closemask) == 1: return 1 else: return 0 #-------------------------- Main: Test Module ------------------------- #- Define additional examples for doctest to use: __test__ = { 'Additional Examples': """ >>> from has_close import has_close >>> import Numeric as N >>> data = N.arange(20.) >>> has_close(data, -1.) 0 >>> data = N.arange(20.) >>> has_close(data, 10.) 1 >>> data = [3, 2, 5, 10, -2, -3, 63] >>> has_close(data, -2) 1 >>> data = [3, 2, 5, 10, -2, -3, 63] >>> has_close(data, -22) 0 >>> data = [3, 2, 5, 10, -2, -3, 63] >>> has_close(data, -1.9999999999) 1 >>> data = [3, 2, 5, 10, -2, -3, 63] >>> has_close(data, -2.01) 0 >>> data = N.arange(20.) >>> has_close(data, 10) 1 >>> data = N.arange(20.) >>> has_close(data, [10]) 1 >>> data = N.arange(20.) >>> has_close(data, N.array(15.)) 1 >>> data = N.arange(20.) >>> has_close(data, N.array(50.)) 0 >>> data = 4. >>> has_close(data, 2.) 0 >>> data = 4. >>> has_close(data, 4.) 1 >>> data = 4. >>> has_close(data, 3.9) 0 """ } #- Execute doctest if module is run from command line: if __name__ == "__main__": """Test the module. Tests the examples in all the module documentation strings, plus __test__. Note: To help ensure that module testing of this file works, the parent directory to the current directory is added to sys.path. """ import doctest, sys, os sys.path.append(os.pardir) doctest.testmod(sys.modules[__name__]) # ===== end file =====