Mercurial > hg > medcouple
comparison pymedcouple @ 8:b3e878bb793d
Remove debug statements
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Thu, 15 Jan 2015 16:25:44 -0500 |
parents | 6c7c7dc9d8ef |
children | e6bcaf38edaa |
comparison
equal
deleted
inserted
replaced
7:6c7c7dc9d8ef | 8:b3e878bb793d |
---|---|
110 if abs(Z[0] - Zmed) < eps1*(eps1 + abs(Zmed)): | 110 if abs(Z[0] - Zmed) < eps1*(eps1 + abs(Zmed)): |
111 return -1.0 | 111 return -1.0 |
112 if abs(Z[-1] - Zmed) < eps1*(eps1 + abs(Zmed)): | 112 if abs(Z[-1] - Zmed) < eps1*(eps1 + abs(Zmed)): |
113 return 1.0 | 113 return 1.0 |
114 | 114 |
115 if debug: | |
116 print "Zmed = ", Zmed | |
117 | |
118 # Centre Z wrt median, so that median(Z) = 0. | 115 # Centre Z wrt median, so that median(Z) = 0. |
119 Z = [z - Zmed for z in Z] | 116 Z = [z - Zmed for z in Z] |
120 | 117 |
121 # Scale inside [-0.5, 0.5], for greater numerical stability. | 118 # Scale inside [-0.5, 0.5], for greater numerical stability. |
122 Zden = 2*max(Z[0], -Z[-1]) | 119 Zden = 2*max(Z[0], -Z[-1]) |
123 if debug: | |
124 print "Zden =", Zden | |
125 | |
126 Z = [z/Zden for z in Z] | 120 Z = [z/Zden for z in Z] |
127 Zmed /= Zden | 121 Zmed /= Zden |
128 | 122 |
129 Zeps = eps1*(eps1 + abs(Zmed)) | 123 Zeps = eps1*(eps1 + abs(Zmed)) |
130 | 124 |
131 # These overlap on the entries that are tied with the median | 125 # These overlap on the entries that are tied with the median |
132 Zplus = [z for z in Z if z >= -Zeps] | 126 Zplus = [z for z in Z if z >= -Zeps] |
133 Zminus = [z for z in Z if Zeps >= z] | 127 Zminus = [z for z in Z if Zeps >= z] |
134 | 128 |
135 if debug: | |
136 for zp in Zplus: | |
137 print "Zplus : %g" % zp | |
138 for zm in Zminus: | |
139 print "Zminus: %g" % zm | |
140 | |
141 n_plus = len(Zplus) | 129 n_plus = len(Zplus) |
142 n_minus = len(Zminus) | 130 n_minus = len(Zminus) |
143 | |
144 if debug: | |
145 print "n_plus =", n_plus | |
146 print "n_minus = ", n_minus | |
147 | 131 |
148 def h_kern(i, j, debug=False): | 132 def h_kern(i, j, debug=False): |
149 """Kernel function h for the medcouple, closing over the values of | 133 """Kernel function h for the medcouple, closing over the values of |
150 Zplus and Zminus just defined above. | 134 Zplus and Zminus just defined above. |
151 | 135 |
159 if abs(a - b) <= 2*eps2: | 143 if abs(a - b) <= 2*eps2: |
160 h = signum(n_plus - 1 - i - j) | 144 h = signum(n_plus - 1 - i - j) |
161 else: | 145 else: |
162 h = (a+b)/(a-b) | 146 h = (a+b)/(a-b) |
163 | 147 |
164 if False: | |
165 print "a = {a}, b = {b}, h({i},{j}) = {h}".format(**locals()) | |
166 | |
167 return h | 148 return h |
168 | 149 |
169 # Init left and right borders | 150 # Init left and right borders |
170 L = [0]*n_plus | 151 L = [0]*n_plus |
171 R = [n_minus - 1]*n_plus | 152 R = [n_minus - 1]*n_plus |
172 | 153 |
173 Ltot = 0 | 154 Ltot = 0 |
174 Rtot = n_minus*n_plus | 155 Rtot = n_minus*n_plus |
175 mid_idx = (Rtot-1)//2 | 156 mid_idx = (Rtot-1)//2 |
176 | 157 |
177 if debug: | |
178 print "mid_idx = ", mid_idx | |
179 | |
180 # kth pair algorithm (Johnson & Mizoguchi) | 158 # kth pair algorithm (Johnson & Mizoguchi) |
181 while Rtot - Ltot > n_plus: | 159 while Rtot - Ltot > n_plus: |
182 if debug: | 160 |
183 print "L = ", L | |
184 print "R = ", R | |
185 | |
186 # First, compute the median inside the given bounds | 161 # First, compute the median inside the given bounds |
187 # (Be stingy, reuse same generator) | 162 # (Be stingy, reuse same generator) |
188 [I1, I2] = tee(i for i in xrange(0, n_plus) if L[i] <= R[i]) | 163 [I1, I2] = tee(i for i in xrange(0, n_plus) if L[i] <= R[i]) |
189 | 164 |
190 A = [h_kern(i, (L[i] + R[i])//2) for i in I1] | 165 A = [h_kern(i, (L[i] + R[i])//2) for i in I1] |
191 W = [R[i] - L[i] + 1 for i in I2] | 166 W = [R[i] - L[i] + 1 for i in I2] |
192 Am = wmedian(A,W) | 167 Am = wmedian(A,W) |
193 if debug: | |
194 print "Am = ", Am | |
195 | 168 |
196 Am_eps = eps1*(eps1 + abs(Am)) | 169 Am_eps = eps1*(eps1 + abs(Am)) |
197 | 170 |
198 # Compute new left and right boundaries, based on the weighted | 171 # Compute new left and right boundaries, based on the weighted |
199 # median | 172 # median |
216 | 189 |
217 # Check on which side of those bounds the desired median of | 190 # Check on which side of those bounds the desired median of |
218 # the whole matrix may be. | 191 # the whole matrix may be. |
219 sumP = sum(P) + len(P) | 192 sumP = sum(P) + len(P) |
220 sumQ = sum(Q) | 193 sumQ = sum(Q) |
221 if debug: | |
222 print "P: ", sumP, P | |
223 print "Q: ", sumQ, Q | |
224 print | |
225 | 194 |
226 if mid_idx <= sumP - 1: | 195 if mid_idx <= sumP - 1: |
227 R = P | 196 R = P |
228 Rtot = sumP | 197 Rtot = sumP |
229 else: | 198 else: |
234 return Am | 203 return Am |
235 | 204 |
236 # Didn't find the median, but now we have a very small search | 205 # Didn't find the median, but now we have a very small search |
237 # space to find it in, just between the left and right boundaries. | 206 # space to find it in, just between the left and right boundaries. |
238 # This space is of size Rtot - Ltot which is <= n_plus | 207 # This space is of size Rtot - Ltot which is <= n_plus |
239 if debug: | |
240 print "L =", L | |
241 print "R =", R | |
242 A = [] | 208 A = [] |
243 for (i, (l, r)) in enumerate(izip(L, R)): | 209 for (i, (l, r)) in enumerate(izip(L, R)): |
244 for j in xrange(l, r + 1): | 210 for j in xrange(l, r + 1): |
245 A.append(h_kern(i, j, debug=debug)) | 211 A.append(h_kern(i, j, debug=debug)) |
246 A.sort() | 212 A.sort() |
247 A.reverse() | 213 A.reverse() |
248 | 214 |
249 if debug: | |
250 print "len(A) = ", len(A) | |
251 Am = A[mid_idx - Ltot] | 215 Am = A[mid_idx - Ltot] |
252 return Am | 216 return Am |
253 | 217 |
254 | 218 |
255 def signum(x): | 219 def signum(x): |
258 if x < 0: | 222 if x < 0: |
259 return -1 | 223 return -1 |
260 else: | 224 else: |
261 return 0 | 225 return 0 |
262 | 226 |
227 | |
263 def main(): | 228 def main(): |
264 import sys | 229 import sys |
265 fname = sys.argv[1] | 230 fname = sys.argv[1] |
266 with open(fname) as f: | 231 with open(fname) as f: |
267 data = [float(x) for x in f.readlines() if x.strip() != ""] | 232 data = [float(x) for x in f.readlines() if x.strip() != ""] |
233 | |
268 print "%.16g" % medcouple_1d(data) | 234 print "%.16g" % medcouple_1d(data) |
269 | 235 |
270 if __name__ == "__main__": | 236 if __name__ == "__main__": |
271 main() | 237 main() |