Mercurial > hg > medcouple
comparison pymedcouple @ 13:077261db7a58
Whitespace cleanup
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Fri, 16 Jan 2015 09:27:44 -0500 |
parents | c81f6d263897 |
children | 8e02346789b2 |
comparison
equal
deleted
inserted
replaced
12:c81f6d263897 | 13:077261db7a58 |
---|---|
9 """This is a partial sort of the weighted list L = [(a,w) for a in A, | 9 """This is a partial sort of the weighted list L = [(a,w) for a in A, |
10 w in W], so that the element at position n is in the correct spot. | 10 w in W], so that the element at position n is in the correct spot. |
11 Also known as quickselect. The elements of W are ignored for the | 11 Also known as quickselect. The elements of W are ignored for the |
12 purposes of this partial sort. | 12 purposes of this partial sort. |
13 """ | 13 """ |
14 | 14 |
15 beg = 0 | 15 beg = 0 |
16 end = len(L) | 16 end = len(L) |
17 | 17 |
18 while True: | 18 while True: |
19 pivot = random.randint(beg,end-1) | 19 pivot = random.randint(beg,end-1) |
20 pivotval = L[pivot][0] | 20 pivotval = L[pivot][0] |
21 L[pivot], L[end-1] = L[end-1], L[pivot] | 21 L[pivot], L[end-1] = L[end-1], L[pivot] |
22 | 22 |
23 idx = beg | 23 idx = beg |
24 for i in xrange(beg, end): | 24 for i in xrange(beg, end): |
25 if L[i][0] < pivotval: | 25 if L[i][0] < pivotval: |
26 L[idx], L[i] = L[i], L[idx] | 26 L[idx], L[i] = L[i], L[idx] |
27 idx += 1 | 27 idx += 1 |
37 | 37 |
38 def wmedian(A, W): | 38 def wmedian(A, W): |
39 """This computes the weighted median of array A with corresponding | 39 """This computes the weighted median of array A with corresponding |
40 weights W. | 40 weights W. |
41 """ | 41 """ |
42 | 42 |
43 AW = zip(A,W) | 43 AW = zip(A,W) |
44 n = len(AW) | 44 n = len(AW) |
45 | 45 |
46 wtot = sum(W) | 46 wtot = sum(W) |
47 | 47 |
48 beg = 0 | 48 beg = 0 |
49 end = n-1 | 49 end = n-1 |
50 | 50 |
51 while True: | 51 while True: |
52 mid = (beg + end)//2 | 52 mid = (beg + end)//2 |
53 | 53 |
54 partsort(AW, mid) | 54 partsort(AW, mid) |
55 trial = AW[mid][0] | 55 trial = AW[mid][0] |
56 | 56 |
57 wleft = wright = 0 | 57 wleft = wright = 0 |
58 for (a,w) in AW: | 58 for (a,w) in AW: |
79 | 79 |
80 Returns | 80 Returns |
81 ------- | 81 ------- |
82 mc : float | 82 mc : float |
83 The medcouple statistic | 83 The medcouple statistic |
84 | 84 |
85 .. [1] G. Brys, M. Hubert, and A. Struyf "A Robust Measure of | 85 .. [1] G. Brys, M. Hubert, and A. Struyf "A Robust Measure of |
86 Skewness." Journal of Computational and Graphical Statistics, Vol. | 86 Skewness." Journal of Computational and Graphical Statistics, Vol. |
87 13, No. 4 (Dec., 2004), pp. 996- 1017 | 87 13, No. 4 (Dec., 2004), pp. 996- 1017 |
88 | 88 |
89 .. [2] D. B. Johnson and T. Mizoguchi "Selecting the Kth Element | 89 .. [2] D. B. Johnson and T. Mizoguchi "Selecting the Kth Element |
90 in $X + Y$ and $X_1 + X_2 + \cdots X_m$". SIAM Journal of | 90 in $X + Y$ and $X_1 + X_2 + \cdots X_m$". SIAM Journal of |
91 Computing, Vol. 7, No. 2 (May 1978), pp. 147-53. | 91 Computing, Vol. 7, No. 2 (May 1978), pp. 147-53. |
92 | 92 |
93 """ | 93 """ |
94 # FIXME: Figure out what to do about NaNs. | 94 # FIXME: Figure out what to do about NaNs. |
95 | 95 |
96 n = len(X) | 96 n = len(X) |
97 n2 = (n-1)//2 | 97 n2 = (n-1)//2 |
98 | 98 |
99 if n < 3: | 99 if n < 3: |
100 return 0 | 100 return 0 |
103 | 103 |
104 if n % 2 == 1: | 104 if n % 2 == 1: |
105 Zmed = Z[n2] | 105 Zmed = Z[n2] |
106 else: | 106 else: |
107 Zmed = (Z[n2] + Z[n2+1])/2 | 107 Zmed = (Z[n2] + Z[n2+1])/2 |
108 | 108 |
109 #Check if the median is at the edges up to relative epsilon | 109 #Check if the median is at the edges up to relative epsilon |
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 |
117 | 117 |
118 # Scale inside [-0.5, 0.5], for greater numerical stability. | 118 # Scale inside [-0.5, 0.5], for greater numerical stability. |
119 Zden = 2*max(Z[0], -Z[-1]) | 119 Zden = 2*max(Z[0], -Z[-1]) |
120 Z = [z/Zden for z in Z] | 120 Z = [z/Zden for z in Z] |
121 Zmed /= Zden | 121 Zmed /= Zden |
122 | 122 |
123 Zeps = eps1*(eps1 + abs(Zmed)) | 123 Zeps = eps1*(eps1 + abs(Zmed)) |
124 | 124 |
125 # These overlap on the entries that are tied with the median | 125 # These overlap on the entries that are tied with the median |
126 Zplus = [z for z in Z if z >= -Zeps] | 126 Zplus = [z for z in Z if z >= -Zeps] |
127 Zminus = [z for z in Z if Zeps >= z] | 127 Zminus = [z for z in Z if Zeps >= z] |
155 Rtot = n_minus*n_plus | 155 Rtot = n_minus*n_plus |
156 medc_idx = (Rtot - 1)//2 | 156 medc_idx = (Rtot - 1)//2 |
157 | 157 |
158 # kth pair algorithm (Johnson & Mizoguchi) | 158 # kth pair algorithm (Johnson & Mizoguchi) |
159 while Rtot - Ltot > n_plus: | 159 while Rtot - Ltot > n_plus: |
160 | 160 |
161 # First, compute the median inside the given bounds | 161 # First, compute the median inside the given bounds |
162 # (Be stingy, reuse same generator) | 162 # (Be stingy, reuse same generator) |
163 [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]) |
164 | 164 |
165 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] |
166 W = [R[i] - L[i] + 1 for i in I2] | 166 W = [R[i] - L[i] + 1 for i in I2] |
167 Am = wmedian(A,W) | 167 Am = wmedian(A,W) |
168 | 168 |
169 Am_eps = eps1*(eps1 + abs(Am)) | 169 Am_eps = eps1*(eps1 + abs(Am)) |
170 | 170 |
171 # Compute new left and right boundaries, based on the weighted | 171 # Compute new left and right boundaries, based on the weighted |
172 # median | 172 # median |
173 P = [] | 173 P = [] |
176 j = 0 | 176 j = 0 |
177 for i in xrange(n_plus - 1, -1, -1): | 177 for i in xrange(n_plus - 1, -1, -1): |
178 while j < n_minus - 1 and h_kern(i, j) - Am > Am_eps: | 178 while j < n_minus - 1 and h_kern(i, j) - Am > Am_eps: |
179 j += 1 | 179 j += 1 |
180 P.append(j - 1) | 180 P.append(j - 1) |
181 | 181 |
182 P.reverse() | 182 P.reverse() |
183 | 183 |
184 j = n_minus - 1 | 184 j = n_minus - 1 |
185 for i in xrange(0, n_plus): | 185 for i in xrange(0, n_plus): |
186 while j >= 0 and h_kern(i, j) - Am < -Am_eps: | 186 while j >= 0 and h_kern(i, j) - Am < -Am_eps: |
213 A.reverse() | 213 A.reverse() |
214 | 214 |
215 Am = A[medc_idx - Ltot] | 215 Am = A[medc_idx - Ltot] |
216 | 216 |
217 return Am | 217 return Am |
218 | 218 |
219 | 219 |
220 def signum(x): | 220 def signum(x): |
221 if x > 0: | 221 if x > 0: |
222 return 1 | 222 return 1 |
223 if x < 0: | 223 if x < 0: |