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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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