1
2
3
4
5 """Single public function module.
6
7 See function docstring for description.
8 """
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
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
65
66 import num_settings as num
67 from num_settings import N
68 from num_settings import MA
69
70
71
72
73
74
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
139
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
150
151 xM = MA.masked_array(x)
152 yM = MA.masked_array(y)
153
154
155
156
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
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
181
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
192
193 xN = N.array(x)
194 yN = N.array(y)
195
196
197
198
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
213
214 if isinstance(output_mask, int):
215 return output_mask
216 else:
217 return output_mask.astype(int)
218
219
220
221
222
223
224
225
226 __test__ = { 'Additional Examples':
227 """
228 """ }
229
230
231
232
233
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
249