Package qtcm :: Module where_close
[hide private]
[frames] | no frames]

Source Code for Module qtcm.where_close

  1  #!/usr/bin/python -tt 
  2  #======================================================================= 
  3  #                        General Documentation 
  4   
  5  """Single public function module. 
  6   
  7     See function docstring for description. 
  8  """ 
  9   
 10  #----------------------------------------------------------------------- 
 11  #                       Additional Documentation 
 12  # 
 13  # RCS Revision Code: 
 14  #   $Id: where_close.py 16 2008-07-09 17:46:32Z jlin $ 
 15  # 
 16  # Modification History: 
 17  # - 19 Mar 2004:  Original by Johnny Lin, Computation Institute, 
 18  #   University of Chicago.  Passed reasonable tests. 
 19  # - 11 Oct 2004:  Added capability to handle MA/ma arrays.  Passed 
 20  #   passably reasonable tests. 
 21  # - 31 May 2008:  Made a part of the qtcm package. 
 22  # 
 23  # Notes: 
 24  # - Written for Python 2.2.2. 
 25  # - Function is based on code from the MA module by Paul F. Dubois. 
 26  #   Some snippets of code in this function are copied directly from  
 27  #   lines in that module. 
 28  # - Module docstrings can be tested using the doctest module.  To 
 29  #   test, execute "python where_close.py".  More complete and complex 
 30  #   testing uses the unittest package, found in the test sub-direc- 
 31  #   tory at the package level. 
 32  # - See import statements throughout for packages/modules required. 
 33  # 
 34  # Copyright (c) 2004-2008 by Johnny Lin.  For licensing, distribution  
 35  # conditions, contact information, and additional documentation see 
 36  # the URL http://www.johnny-lin.com/py_pkgs/qtcm/doc/. 
 37  #======================================================================= 
 38   
 39   
 40   
 41   
 42  #----------------------- Overall Module Imports ------------------------ 
 43   
 44  #- If you're importing this module in testing mode, or you're running 
 45  #  pydoc on this module via the command line, import user-specific 
 46  #  settings to make sure any non-standard libraries are found: 
 47   
 48  import os, sys 
 49  if (__name__ == "__main__") or \ 
 50     ("pydoc" in os.path.basename(sys.argv[0])): 
 51      import user 
 52  del os, sys 
 53   
 54   
 55  #- Import package version and set module version to package version: 
 56   
 57  import package_version as _package_version 
 58  __version__ = _package_version.version 
 59  __author__  = _package_version.author 
 60  __date__    = _package_version.date 
 61  __credits__ = _package_version.credits 
 62   
 63   
 64  #- Import Numpy or numarray packages: 
 65   
 66  import num_settings as num 
 67  from num_settings import N 
 68  from num_settings import MA 
 69   
 70   
 71   
 72   
 73  #--------------------------- Public Function --------------------------- 
 74   
75 -def where_close(x, y, rtol=1.e-5, atol=1.e-8):
76 """Mask of where x and y are element-wise "equal" to each other. 77 78 Returns an int integer array with elements equal to 1 where x 79 and y are "equal", and 0 otherwise. If x or y are floating 80 point, "equal" means where abs(x-y) <= atol + rtol * abs(y). 81 This is essentially the same algorithm used in the 82 numpy/Numeric/numarray function allclose. If x and y are 83 integer, "equal" means strict equality. Shape and size of 84 output is the same as x and y; if one is an array and the other 85 is scalar, shape and size of the output is the same as the 86 array. 87 88 Output is an MA/ma masked array, unless both inputs are not 89 MA/ma objects, in which case output is a numpy/Numeric/numarray 90 array. If inputs are both unmasked scalars the output is a 91 Python integer scalar. 92 93 Positional Input Arguments: 94 * x: Scalar, numpy/Numeric/numarray array, MA/ma array, Python 95 list/tuple of any size and shape. Floating or integer type. 96 * y: Scalar, numpy/Numeric/numarray array, MA/ma array, Python 97 list/tuple of any size and shape. Floating or integer type. 98 99 Keyword Input Arguments: 100 * rtol: "Relative" tolerance. Default is 1.e-5. Used in the 101 comparison between x and y only if the two are floating point. 102 * atol: "Absolute" tolerance. Default is 1.e-8. Used in the 103 comparison between x and y only if the two are floating point. 104 105 If either of the inputs are MA/ma masked objects, this function 106 uses the MA/ma default algorithm for comparison, i.e., masked 107 values are always considered equal. 108 109 Examples: 110 >>> from where_close import where_close 111 >>> x = [20., -32., -1., 2. , 5., 29.] 112 >>> y = [20.1, -31., -1., 2.01, 3., 28.99] 113 >>> ind = where_close(x, y) 114 >>> ['%.1g' % ind[i] for i in range(len(ind))] 115 ['0', '0', '1', '0', '0', '0'] 116 117 >>> from where_close import where_close 118 >>> x = [20., -32., -1., 2. , 5., 29.] 119 >>> y = [20.1, -31., -1., 2.000000000001, 3., 28.99] 120 >>> ind = where_close(x, y) 121 >>> ['%.1g' % ind[i] for i in range(len(ind))] 122 ['0', '0', '1', '1', '0', '0'] 123 124 >>> x = N.array([1, 5, 7, -2, 10]) 125 >>> y = N.array([1, -5, 17, -2, 0]) 126 >>> ind = where_close(x, y) 127 >>> ['%.1g' % ind[i] for i in range(len(ind))] 128 ['1', '0', '0', '1', '0'] 129 """ 130 if (not MA.isMA(x)) and (not MA.isMA(y)): 131 return _where_close_unmasked(x, y, rtol=rtol, atol=atol) 132 else: 133 return _where_close_masked(x, y, rtol=rtol, atol=atol)
134 135 136 137 138 #------------------ Private Function: For MA/ma Case ------------------ 139
140 -def _where_close_masked(x, y, rtol=1.e-5, atol=1.e-8):
141 """Version of where_close for masked arrays. 142 143 See docstring for where_close for details regarding parameters and 144 function. 145 """ 146 abs = MA.absolute 147 148 149 #- Make sure input is MA/ma type: 150 151 xM = MA.masked_array(x) 152 yM = MA.masked_array(y) 153 154 155 #- Safe compare if floating. Strict compare if integer. Any other 156 # type returns an error: 157 158 if (xM.typecode() in MA.typecodes['Float']) or \ 159 (yM.typecode() in MA.typecodes['Float']): 160 output_mask = MA.less_equal(abs(xM-yM), atol+rtol*abs(yM)) 161 162 elif (xM.typecode() in MA.typecodes['Integer']) and \ 163 (yM.typecode() in MA.typecodes['Integer']): 164 output_mask = MA.equal(xM, yM) 165 166 else: 167 raise ValueError, "where_close: Inputs must be Float or Integer" 168 169 170 #- Return output_mask: 171 172 if isinstance(output_mask, int): 173 return output_mask 174 else: 175 return output_mask.astype(MA.Int)
176 177 178 179 180 #-------- Private Function: For numarray/Numeric/numarray Case -------- 181
182 -def _where_close_unmasked(x, y, rtol=1.e-5, atol=1.e-8):
183 """Version of where_close for unmasked arrays. 184 185 See docstring for where_close for details regarding parameters and 186 function. 187 """ 188 abs = N.absolute 189 190 191 #- Make sure input is numpy/Numeric/numarray type: 192 193 xN = N.array(x) 194 yN = N.array(y) 195 196 197 #- Safe compare if floating. Strict compare if integer. Any other 198 # type returns an error: 199 200 if (num.typecode(xN) in N.typecodes['Float']) or \ 201 (num.typecode(yN) in N.typecodes['Float']): 202 output_mask = N.less_equal(abs(xN-yN), atol+rtol*abs(yN)) 203 204 elif (num.typecode(xN) in N.typecodes['Integer']) and \ 205 (num.typecode(yN) in N.typecodes['Integer']): 206 output_mask = N.equal(xN, yN) 207 208 else: 209 raise ValueError, "where_close: Inputs must be Float or Integer" 210 211 212 #- Return output_mask: 213 214 if isinstance(output_mask, int): 215 return output_mask 216 else: 217 return output_mask.astype(int)
218 219 220 221 222 #---------------------- Addition doctest Examples ---------------------- 223 224 #- Define additional examples for doctest to use: 225 226 __test__ = { 'Additional Examples': 227 """ 228 """ } 229 230 231 #-------------------------- Main: Test Module ------------------------- 232 233 #- Execute doctest if module is run from command line: 234 235 if __name__ == "__main__": 236 """Test the module. 237 238 Note: To help ensure that module testing of this file works, the 239 parent directory to the current directory is added to sys.path. 240 """ 241 import doctest, sys, os 242 sys.path.append(os.pardir) 243 doctest.testmod(sys.modules[__name__]) 244 245 246 247 248 # ===== end file ===== 249