Mercurial > hg > medcouple
annotate medcouple.py @ 37:4fb3b87b8610
Add GPL'ed header
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 06 Apr 2015 08:43:43 -0400 |
parents | 9a531463663e |
children | 2493b21d7d8b |
rev | line source |
---|---|
5
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
1 #!/usr/bin/python |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
2 |
37
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
3 # medcouple.py --- |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
4 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
5 # Copyright © 2015 Jordi Gutiérrez Hermoso <jordigh@octave.org> |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
6 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
7 # Author: Jordi Gutiérrez Hermoso |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
8 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
9 # This program is free software; you can redistribute it and/or |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
10 # modify it under the terms of the GNU General Public License |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
11 # as published by the Free Software Foundation; either version 3 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
12 # of the License, or (at your option) any later version. |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
13 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
14 # This program is distributed in the hope that it will be useful, |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
17 # GNU General Public License for more details. |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
18 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
19 # You should have received a copy of the GNU General Public License |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
20 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
21 |
4fb3b87b8610
Add GPL'ed header
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
33
diff
changeset
|
22 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
23 import random |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
24 |
7 | 25 from itertools import tee, izip |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
26 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
27 def wmedian(A, W): |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
28 """This computes the weighted median of array A with corresponding |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
29 weights W. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
30 """ |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
31 |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
32 AW = zip(A, W) |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
33 n = len(AW) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
34 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
35 wtot = sum(W) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
36 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
37 beg = 0 |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
38 end = n - 1 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
39 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
40 while True: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
41 mid = (beg + end)//2 |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
42 |
31
1a2bb52722c2
pymedcouple: replace slow Python partsort with faster built-in full sort
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
24
diff
changeset
|
43 AW = sorted(AW, key = lambda x: x[0]) # A partial sort would suffice here |
1a2bb52722c2
pymedcouple: replace slow Python partsort with faster built-in full sort
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
24
diff
changeset
|
44 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
45 trial = AW[mid][0] |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
46 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
47 wleft = wright = 0 |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
48 for (a, w) in AW: |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
49 if a < trial: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
50 wleft += w |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
51 else: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
52 # This also includes a == trial, i.e. the "middle" |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
53 # weight. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
54 wright += w |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
55 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
56 if 2*wleft > wtot: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
57 end = mid |
21
d63e763f8ac1
wmedian: don't infinite loop if wleft == wright
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
20
diff
changeset
|
58 elif 2*wright < wtot: |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
59 beg = mid |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
60 else: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
61 return trial |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
62 |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
63 |
10
3d145bcc8694
Remove more debug code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
9
diff
changeset
|
64 def medcouple_1d(X, eps1 = 2**-52, eps2 = 2**-1022): |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
65 """Calculates the medcouple robust measure of skewness. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
66 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
67 Parameters |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
68 ---------- |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
69 y : array-like, 1-d |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
70 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
71 Returns |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
72 ------- |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
73 mc : float |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
74 The medcouple statistic |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
75 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
76 .. [1] G. Brys, M. Hubert, and A. Struyf "A Robust Measure of |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
77 Skewness." Journal of Computational and Graphical Statistics, Vol. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
78 13, No. 4 (Dec., 2004), pp. 996- 1017 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
79 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
80 .. [2] D. B. Johnson and T. Mizoguchi "Selecting the Kth Element |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
81 in $X + Y$ and $X_1 + X_2 + \cdots X_m$". SIAM Journal of |
9 | 82 Computing, Vol. 7, No. 2 (May 1978), pp. 147-53. |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
83 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
84 """ |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
85 # FIXME: Figure out what to do about NaNs. |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
86 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
87 n = len(X) |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
88 n2 = (n - 1)//2 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
89 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
90 if n < 3: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
91 return 0 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
92 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
93 Z = sorted(X, reverse=True) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
94 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
95 if n % 2 == 1: |
7 | 96 Zmed = Z[n2] |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
97 else: |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
98 Zmed = (Z[n2] + Z[n2 + 1])/2 |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
99 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
100 #Check if the median is at the edges up to relative epsilon |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
101 if abs(Z[0] - Zmed) < eps1*(eps1 + abs(Zmed)): |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
102 return -1.0 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
103 if abs(Z[-1] - Zmed) < eps1*(eps1 + abs(Zmed)): |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
104 return 1.0 |
7 | 105 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
106 # Centre Z wrt median, so that median(Z) = 0. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
107 Z = [z - Zmed for z in Z] |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
108 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
109 # Scale inside [-0.5, 0.5], for greater numerical stability. |
7 | 110 Zden = 2*max(Z[0], -Z[-1]) |
5
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
111 Z = [z/Zden for z in Z] |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
112 Zmed /= Zden |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
113 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
114 Zeps = eps1*(eps1 + abs(Zmed)) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
115 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
116 # These overlap on the entries that are tied with the median |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
117 Zplus = [z for z in Z if z >= -Zeps] |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
118 Zminus = [z for z in Z if Zeps >= z] |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
119 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
120 n_plus = len(Zplus) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
121 n_minus = len(Zminus) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
122 |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
123 |
10
3d145bcc8694
Remove more debug code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
9
diff
changeset
|
124 def h_kern(i, j): |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
125 """Kernel function h for the medcouple, closing over the values of |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
126 Zplus and Zminus just defined above. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
127 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
128 In case a and be are within epsilon of the median, the kernel |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
129 is the signum of their position. |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
130 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
131 """ |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
132 a = Zplus[i] |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
133 b = Zminus[j] |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
134 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
135 if abs(a - b) <= 2*eps2: |
7 | 136 h = signum(n_plus - 1 - i - j) |
137 else: | |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
138 h = (a + b)/(a - b) |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
139 |
7 | 140 return h |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
141 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
142 # Init left and right borders |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
143 L = [0]*n_plus |
7 | 144 R = [n_minus - 1]*n_plus |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
145 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
146 Ltot = 0 |
7 | 147 Rtot = n_minus*n_plus |
22
f5b4a2ab6204
medcouple_1d: modify the definition of medc_idx to match R's definition
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
21
diff
changeset
|
148 medc_idx = Rtot//2 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
149 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
150 # kth pair algorithm (Johnson & Mizoguchi) |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
151 while Rtot - Ltot > n_plus: |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
152 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
153 # First, compute the median inside the given bounds |
6 | 154 # (Be stingy, reuse same generator) |
155 [I1, I2] = tee(i for i in xrange(0, n_plus) if L[i] <= R[i]) | |
156 | |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
157 A = [h_kern(i, (L[i] + R[i])//2) for i in I1] |
7 | 158 W = [R[i] - L[i] + 1 for i in I2] |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
159 Am = wmedian(A, W) |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
160 |
7 | 161 Am_eps = eps1*(eps1 + abs(Am)) |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
162 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
163 # Compute new left and right boundaries, based on the weighted |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
164 # median |
7 | 165 P = [] |
166 Q = [] | |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
167 |
7 | 168 j = 0 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
169 for i in xrange(n_plus - 1, -1, -1): |
20
8e02346789b2
Fix off by one error in P computation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
13
diff
changeset
|
170 while j < n_minus and h_kern(i, j) - Am > Am_eps: |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
171 j += 1 |
12
c81f6d263897
Spaces around plus and minus
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
11
diff
changeset
|
172 P.append(j - 1) |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
173 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
174 P.reverse() |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
175 |
7 | 176 j = n_minus - 1 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
177 for i in xrange(0, n_plus): |
7 | 178 while j >= 0 and h_kern(i, j) - Am < -Am_eps: |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
179 j -= 1 |
12
c81f6d263897
Spaces around plus and minus
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
11
diff
changeset
|
180 Q.append(j + 1) |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
181 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
182 # Check on which side of those bounds the desired median of |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
183 # the whole matrix may be. |
7 | 184 sumP = sum(P) + len(P) |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
185 sumQ = sum(Q) |
11
4c7d7ff28a0e
Rename mid_idx to medc_idx
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
10
diff
changeset
|
186 |
4c7d7ff28a0e
Rename mid_idx to medc_idx
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
10
diff
changeset
|
187 if medc_idx <= sumP - 1: |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
188 R = P |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
189 Rtot = sumP |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
190 else: |
11
4c7d7ff28a0e
Rename mid_idx to medc_idx
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
10
diff
changeset
|
191 if medc_idx > sumQ - 1: |
7 | 192 L = Q |
193 Ltot = sumQ | |
194 else: | |
195 return Am | |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
196 |
7 | 197 # Didn't find the median, but now we have a very small search |
198 # space to find it in, just between the left and right boundaries. | |
199 # This space is of size Rtot - Ltot which is <= n_plus | |
200 A = [] | |
201 for (i, (l, r)) in enumerate(izip(L, R)): | |
202 for j in xrange(l, r + 1): | |
10
3d145bcc8694
Remove more debug code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
9
diff
changeset
|
203 A.append(h_kern(i, j)) |
31
1a2bb52722c2
pymedcouple: replace slow Python partsort with faster built-in full sort
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
24
diff
changeset
|
204 |
1a2bb52722c2
pymedcouple: replace slow Python partsort with faster built-in full sort
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
24
diff
changeset
|
205 A.sort() # A partial sort would suffice here |
7 | 206 A.reverse() |
207 | |
23
29a178b23219
Whitespace style fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22
diff
changeset
|
208 Am = A[medc_idx - Ltot] |
11
4c7d7ff28a0e
Rename mid_idx to medc_idx
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
10
diff
changeset
|
209 |
7 | 210 return Am |
13
077261db7a58
Whitespace cleanup
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
12
diff
changeset
|
211 |
4
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
212 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
213 def signum(x): |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
214 if x > 0: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
215 return 1 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
216 if x < 0: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
217 return -1 |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
218 else: |
74d0d08dbc95
Add Python implementation
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
219 return 0 |
5
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
220 |
8
b3e878bb793d
Remove debug statements
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
7
diff
changeset
|
221 |
5
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
222 def main(): |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
223 import sys |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
224 fname = sys.argv[1] |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
225 with open(fname) as f: |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
226 data = [float(x) for x in f.readlines() if x.strip() != ""] |
8
b3e878bb793d
Remove debug statements
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
7
diff
changeset
|
227 |
7 | 228 print "%.16g" % medcouple_1d(data) |
5
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
229 |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
230 if __name__ == "__main__": |
cbe17f888c79
Make it executable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
4
diff
changeset
|
231 main() |