Mercurial > hg > medcouple
annotate jmedcouple.c++ @ 28:65f6fad65f49
jmedcouple: get rid of unused trace_lev parameter
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Sun, 18 Jan 2015 20:41:04 -0500 |
parents | 40cbfb64e952 |
children | cf8c8c825c6d |
rev | line source |
---|---|
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
1 #include <vector> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
2 #include <limits> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
3 #include <iostream> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
4 #include <string> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
5 #include <fstream> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
6 #include <iomanip> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
7 #include <algorithm> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
8 #include <utility> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
9 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
10 using namespace std; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
11 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
12 template <typename T> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
13 int signum(T val) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
14 return (T(0) < val) - (val < T(0)); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
15 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
16 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
17 template <typename Container, typename Out = typename Container::value_type> |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
18 Out sum(const Container& C) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
19 return accumulate(C.begin(), C.end(), Out()); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
20 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
21 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
22 /* |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
23 This computes the weighted median of array A with corresponding |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
24 weights W. |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
25 */ |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
26 double wmedian(const vector<double>& A, |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
27 const vector<int>& W) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
28 { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
29 typedef pair<double,int> aw_t; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
30 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
31 int n = A.size(); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
32 vector<aw_t> AW(n); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
33 for (int i = 0; i < n; i ++) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
34 AW[i] = make_pair(A[i], W[i]); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
35 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
36 long wtot = sum(W); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
37 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
38 int beg = 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
39 int end = n - 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
40 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
41 while (true) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
42 int mid = (beg + end)/2; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
43 nth_element(AW.begin(), AW.begin() + mid, AW.end(), |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
44 [](const aw_t& l, const aw_t& r){return l.first > r.first;}); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
45 double trial = AW[mid].first; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
46 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
47 long wleft = 0, wright = 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
48 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
49 for (aw_t& aw: AW ) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
50 if (aw.first > trial) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
51 wleft += aw.second; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
52 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
53 // This also includes a == trial, i.e. the "middle" weight. |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
54 wright += aw.second; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
55 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
56 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
57 if (2*wleft > wtot) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
58 end = mid; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
59 else if (2*wright < wtot) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
60 beg = mid; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
61 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
62 return trial; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
63 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
64 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
65 return 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
66 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
67 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
68 double medcouple(const std::vector<double>& X, |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
69 double eps1 = numeric_limits<double>::epsilon(), |
28
65f6fad65f49
jmedcouple: get rid of unused trace_lev parameter
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
27
diff
changeset
|
70 double eps2 = numeric_limits<double>::min()) |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
71 { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
72 size_t n = X.size(), n2 = (n - 1)/2; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
73 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
74 if (n < 3) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
75 return 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
76 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
77 vector<double> Z = X; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
78 sort(Z.begin(), Z.end(), std::greater<double>()); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
79 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
80 double Zmed; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
81 if (n % 2 == 1) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
82 Zmed = Z[n2]; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
83 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
84 Zmed = (Z[n2] + Z[n2 + 1])/2; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
85 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
86 // Check if the median is at the edges up to relative epsilon |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
87 if (abs(Z[0] - Zmed) < eps1*(eps1 + abs(Zmed))) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
88 return -1.0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
89 if (abs(Z[n - 1] - Zmed) < eps1*(eps1 + abs(Zmed))) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
90 return 1.0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
91 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
92 // Centre Z wrt median, so that median(Z) = 0. |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
93 for_each(Z.begin(), Z.end(), [&](double& z){ z -= Zmed;}); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
94 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
95 // Scale inside [-0.5, 0.5], for greater numerical stability. |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
96 double Zden = 2*max(Z[0], -Z[n - 1]); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
97 for_each(Z.begin(), Z.end(), [&](double& z){z /= Zden;}); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
98 Zmed /= Zden; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
99 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
100 double Zeps = eps1*(eps1 + abs(Zmed)); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
101 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
102 // These overlap on the entries that are tied with the median |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
103 vector<double> Zplus, Zminus; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
104 copy_if(Z.begin(), Z.end(), back_inserter(Zplus), |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
105 [=](double z){return z >= -Zeps;}); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
106 copy_if(Z.begin(), Z.end(), back_inserter(Zminus), |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
107 [=](double z){return Zeps >= z;}); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
108 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
109 size_t |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
110 n_plus = Zplus.size(), |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
111 n_minus = Zminus.size(); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
112 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
113 /* |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
114 Kernel function h for the medcouple, closing over the values of |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
115 Zplus and Zminus just defined above. |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
116 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
117 In case a and be are within epsilon of the median, the kernel |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
118 is the signum of their position. |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
119 */ |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
120 auto h_kern = [&](int i, int j) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
121 double a = Zplus[i]; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
122 double b = Zminus[j]; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
123 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
124 double h; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
125 if (abs(a - b) <= 2*eps2) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
126 h = signum(n_plus - 1 - i - j); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
127 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
128 h = (a + b)/(a - b); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
129 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
130 return h; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
131 }; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
132 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
133 // Init left and right borders |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
134 vector<int> L(n_plus, 0); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
135 vector<int> R(n_plus, n_minus - 1); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
136 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
137 long Ltot = 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
138 long Rtot = n_minus*n_plus; |
27
40cbfb64e952
jmedcouple: change type of medc_idx to long
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
25
diff
changeset
|
139 long medc_idx = Rtot/2; |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
140 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
141 // kth pair algorithm (Johnson & Mizoguchi) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
142 while (Rtot - Ltot > n_plus) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
143 // First, compute the median inside the given bounds |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
144 vector<double> A; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
145 vector<int> W; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
146 for (int i = 0; i < n_plus; i++) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
147 if (L[i] <= R[i]) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
148 A.push_back(h_kern(i, (L[i] + R[i])/2)); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
149 W.push_back(R[i] - L[i] + 1); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
150 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
151 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
152 double Am = wmedian(A, W); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
153 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
154 double Am_eps = eps1*(eps1 + abs(Am)); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
155 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
156 //Compute new left and right boundaries, based on the weighted |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
157 //median |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
158 vector<int> P(n_plus), Q(n_plus); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
159 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
160 { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
161 int j = 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
162 for (int i = n_plus - 1; i >= 0; i--) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
163 while (j < n_minus and h_kern(i, j) - Am > Am_eps) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
164 j++; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
165 P[i] = j - 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
166 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
167 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
168 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
169 { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
170 int j = n_minus - 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
171 for (int i = 0; i < n_plus; i++) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
172 while (j >= 0 and h_kern(i, j) - Am < -Am_eps) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
173 j--; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
174 Q[i] = j + 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
175 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
176 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
177 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
178 long |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
179 sumP = sum(P) + n_plus, |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
180 sumQ = sum(Q); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
181 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
182 if (medc_idx <= sumP - 1) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
183 R = P; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
184 Rtot = sumP; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
185 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
186 else { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
187 if (medc_idx > sumQ - 1) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
188 L = Q; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
189 Ltot = sumQ; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
190 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
191 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
192 return Am; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
193 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
194 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
195 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
196 // Didn't find the median, but now we have a very small search space |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
197 // to find it in, just between the left and right boundaries. This |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
198 // space is of size Rtot - Ltot which is <= n_plus |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
199 vector<double> A; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
200 for (int i = 0; i < n_plus; i++) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
201 for (int j = L[i]; j <= R[i]; j++) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
202 A.push_back(h_kern(i, j)); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
203 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
204 nth_element(A.begin(), A.begin() + medc_idx - Ltot, A.end(), |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
205 [](double x, double y) {return x > y;}); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
206 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
207 double Am = A[medc_idx - Ltot]; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
208 return Am; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
209 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
210 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
211 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
212 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
213 int main(int argc, char** argv) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
214 double |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
215 eps1 = numeric_limits<double>::epsilon(), |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
216 eps2 = numeric_limits<double>::min(); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
217 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
218 string fname; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
219 if (argc > 1) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
220 fname = argv[1]; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
221 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
222 else { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
223 cerr << "Please provide input file." << endl; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
224 return 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
225 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
226 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
227 ifstream ifs(fname); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
228 if (not ifs) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
229 cerr << "File " << fname << " not found." << endl; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
230 return 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
231 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
232 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
233 vector<double> data; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
234 double datum; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
235 while (ifs >> datum) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
236 data.push_back(datum); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
237 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
238 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
239 cout << setprecision(16) |
28
65f6fad65f49
jmedcouple: get rid of unused trace_lev parameter
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
27
diff
changeset
|
240 << medcouple(data, eps1, eps2) << endl; |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
241 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
242 return 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
243 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
244 |