Mercurial > hg > medcouple
annotate medcouple.d @ 74:305b7361a5bd default tip @
showalgo: save a snapshot instead of waiting for keyboard input
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Sun, 29 May 2016 19:05:01 -0400 |
parents | 18e7cd6ff057 |
children |
rev | line source |
---|---|
38
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
1 // medcouple.d --- |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
2 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
3 // Copyright © 2016 Jordi Gutiérrez Hermoso <jordigh@octave.org> |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
4 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
5 // Author: Jordi Gutiérrez Hermoso |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
6 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
7 // This program is free software; you can redistribute it and/or |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
8 // modify it under the terms of the GNU General Public License |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
9 // as published by the Free Software Foundation; either version 3 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
10 // of the License, or (at your option) any later version. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
11 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
12 // This program is distributed in the hope that it will be useful, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
15 // GNU General Public License for more details. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
16 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
17 // You should have received a copy of the GNU General Public License |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
18 // along with this program. If not, see <http://www.gnu.org/licenses/>. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
19 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
20 import std.stdio; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
21 import std.array; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
22 import std.conv: to; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
23 import std.range: iota, zip; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
24 import std.string: strip; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
25 import std.typecons: Tuple; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
26 import std.algorithm: filter, map, max, reduce, sort, topN; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
27 import std.math: abs; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
28 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
29 // Could also just be reduce!"a+b", they call this "string lambda" |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
30 alias sum = reduce!((a,b) => a + b); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
31 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
32 int signum(T)(T val) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
33 return (cast(T)(0) < val ) - (val < cast(T)(0)); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
34 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
35 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
36 double wmedian(double[] A, long[] W) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
37 auto AW = zip(A,W).array; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
38 long n = AW.length; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
39 auto wtot = sum(W); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
40 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
41 typeof(n) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
42 beg = 0, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
43 end = n - 1; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
44 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
45 while(true) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
46 auto mid = (beg+end)/2; |
51
18e7cd6ff057
medcouple.d: narrow computation of topN
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
38
diff
changeset
|
47 topN!((x, y) => x[0] > y[0])(AW[beg..end+1], mid); |
38
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
48 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
49 auto trial = AW[mid][0]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
50 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
51 typeof(n) wleft = 0, wright = 0; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
52 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
53 foreach(aw; AW) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
54 auto a = aw[0]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
55 auto w = aw[1]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
56 if (a > trial) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
57 wleft += w; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
58 else |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
59 wright += w; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
60 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
61 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
62 if (2*wleft > wtot) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
63 end = mid; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
64 else if (2*wright < wtot) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
65 beg = mid; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
66 else |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
67 return trial; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
68 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
69 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
70 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
71 double medcouple(const double[] X, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
72 double eps1 = double.epsilon, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
73 double eps2 = double.min) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
74 { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
75 long n = X.length, n2 = (n-1)/2; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
76 if (n < 3) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
77 return 0; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
78 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
79 auto Z = X.dup; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
80 sort!((a,b) => a > b)(Z); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
81 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
82 auto Zmed = n % 2 == 1 ? Z[n2] : (Z[n2] + Z[n2 + 1])/2; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
83 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
84 // Check if the median is at the edges up to relative epsilon |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
85 if (abs(Z[0] - Zmed) < eps1*(eps1 + abs(Zmed))) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
86 return -1.0; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
87 if (abs(Z[n - 1] - Zmed) < eps1*(eps1 + abs(Zmed))) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
88 return 1.0; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
89 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
90 // Centre Z wrt median, so that median(Z) = 0. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
91 Z[] -= Zmed; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
92 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
93 // Scale inside [-0.5, 0.5], for greater numerical stability. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
94 auto Zden = 2*max(Z[0], -Z[n - 1]); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
95 Z[] /= Zden; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
96 Zmed /= Zden; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
97 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
98 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
99 auto |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
100 Zeps = eps1*(eps1 + abs(Zmed)), |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
101 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
102 // These overlap on the entries that are tied with the median |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
103 Zplus = filter!(z => z >= -Zeps)(Z).array, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
104 Zminus = filter!(z => Zeps >= z)(Z).array; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
105 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
106 long |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
107 n_plus = Zplus.length, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
108 n_minus = Zminus.length; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
109 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
110 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
111 /* |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
112 Kernel function h for the medcouple, closing over the values of |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
113 Zplus and Zminus just defined above. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
114 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
115 In case a and be are within epsilon of the median, the kernel |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
116 is the signum of their position. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
117 */ |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
118 auto h_kern(long i, long j){ |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
119 auto |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
120 a = Zplus[i], |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
121 b = Zminus[j]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
122 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
123 if (abs(a - b) <= 2*eps2) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
124 return signum(n_plus - 1 - i - j); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
125 else |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
126 return (a+b)/(a-b); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
127 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
128 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
129 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
130 auto |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
131 // Init left and right borders |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
132 L = replicate([0L], n_plus), |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
133 R = replicate([n_minus - 1], n_plus), |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
134 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
135 Ltot = 0L, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
136 Rtot = n_minus*n_plus, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
137 medc_idx = Rtot/2; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
138 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
139 // kth pair algorithm (Johnson & Mizoguchi) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
140 while (Rtot - Ltot > n_plus) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
141 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
142 // First, compute the weighted median of row medians inside the |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
143 // given bounds |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
144 auto |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
145 I = filter!(i => L[i] <= R[i])(iota(0, n_plus-1)), |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
146 A = map!(i => h_kern(i, (L[i] + R[i])/2))(I).array, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
147 W = map!(i => R[i] - L[i] + 1)(I).array, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
148 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
149 Am = wmedian(A, W), |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
150 Am_eps = eps1*(eps1 + abs(Am)); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
151 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
152 // Compute new left and right boundaries, based on the weighted |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
153 // median |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
154 auto P = new long[n_plus], Q = new long[n_plus]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
155 { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
156 auto j = 0L; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
157 for (auto i = n_plus - 1; i >= 0; i--) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
158 while (j < n_minus && h_kern(i, j) - Am > Am_eps) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
159 j++; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
160 P[i] = j - 1; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
161 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
162 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
163 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
164 { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
165 auto j = n_minus - 1; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
166 for (auto i = 0; i < n_plus; i++) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
167 while (j >= 0 && h_kern(i, j) - Am < -Am_eps) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
168 j--; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
169 Q[i] = j + 1; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
170 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
171 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
172 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
173 // Discard left or right entries, depending on which side the |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
174 // medcouple is. |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
175 auto |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
176 sumP = sum(P) + n_plus, |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
177 sumQ = sum(Q); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
178 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
179 if (medc_idx <= sumP - 1) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
180 R = P; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
181 Rtot = sumP; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
182 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
183 else { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
184 if (medc_idx > sumQ - 1) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
185 L = Q; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
186 Ltot = sumQ; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
187 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
188 else |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
189 return Am; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
190 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
191 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
192 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
193 // Didn't find the median, but now we have a very small search space |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
194 // to find it in, just between the left and right boundaries. This |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
195 // space is of size Rtot - Ltot which is <= n_plus |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
196 auto |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
197 A = new double[Rtot - Ltot], |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
198 idx = 0L; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
199 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
200 for (auto i = 0L; i < n_plus; i++) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
201 for (auto j = L[i]; j <= R[i]; j++){ |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
202 A[idx] = h_kern(i, j); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
203 ++idx; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
204 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
205 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
206 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
207 topN!((x,y) => x > y)(A, medc_idx - Ltot); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
208 return A[medc_idx - Ltot]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
209 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
210 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
211 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
212 int main(string[] argv) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
213 if (argv.length < 2) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
214 stderr.writeln("Please provide input file."); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
215 return 1; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
216 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
217 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
218 auto fname = argv[1]; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
219 double[] data; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
220 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
221 foreach(line; File(fname).byLine) { |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
222 if (! line.empty) |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
223 data ~= to!(double)(line.strip); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
224 } |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
225 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
226 writefln("%0.16f", medcouple(data)); |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
227 |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
228 return 0; |
45fb52ba3057
Add D implementation of the medcouple
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
229 } |