annotate jmedcouple.c++ @ 25:518ef922033e

Add C++ translation of Python code
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Sun, 18 Jan 2015 19:43:51 -0500
parents
children 40cbfb64e952
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 <sstream>
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
8 #include <algorithm>
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
9 #include <utility>
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
10
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
11 using namespace std;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
12
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
13 template <typename T>
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
14 int signum(T val) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
15 return (T(0) < val) - (val < T(0));
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
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
18 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
19 Out sum(const Container& C) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
20 return accumulate(C.begin(), C.end(), Out());
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 /*
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
24 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
25 weights W.
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
26 */
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
27 double wmedian(const vector<double>& A,
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
28 const vector<int>& W)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
29 {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
30 typedef pair<double,int> aw_t;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
31
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
32 int n = A.size();
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
33 vector<aw_t> AW(n);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
34 for (int i = 0; i < n; i ++)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
35 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
36
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
37 long wtot = sum(W);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
38
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
39 int beg = 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
40 int end = n - 1;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
41
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
42 while (true) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
43 int mid = (beg + end)/2;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
44 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
45 [](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
46 double trial = AW[mid].first;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
47
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
48 long wleft = 0, wright = 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
49
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
50 for (aw_t& aw: AW ) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
51 if (aw.first > trial)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
52 wleft += aw.second;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
53 else
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
54 // 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
55 wright += aw.second;
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
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
58 if (2*wleft > wtot)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
59 end = mid;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
60 else if (2*wright < wtot)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
61 beg = mid;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
62 else
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
63 return trial;
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
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
66 return 0;
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
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
69 double medcouple(const std::vector<double>& X,
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
70 double eps1 = numeric_limits<double>::epsilon(),
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
71 double eps2 = numeric_limits<double>::min(),
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
72 int trace_lev = 0)
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 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
75
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
76 if (n < 3)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
77 return 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
78
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
79 vector<double> Z = X;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
80 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
81
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
82 double Zmed;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
83 if (n % 2 == 1)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
84 Zmed = Z[n2];
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
85 else
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
86 Zmed = (Z[n2] + Z[n2 + 1])/2;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
87
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
88 // 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
89 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
90 return -1.0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
91 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
92 return 1.0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
93
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
94 // 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
95 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
96
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
97 // 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
98 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
99 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
100 Zmed /= Zden;
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 double Zeps = eps1*(eps1 + abs(Zmed));
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
103
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
104 // 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
105 vector<double> Zplus, Zminus;
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(Zplus),
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
107 [=](double z){return z >= -Zeps;});
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
108 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
109 [=](double z){return Zeps >= z;});
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
110
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
111 size_t
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
112 n_plus = Zplus.size(),
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
113 n_minus = Zminus.size();
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
114
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
115 /*
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
116 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
117 Zplus and Zminus just defined above.
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
118
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
119 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
120 is the signum of their position.
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
121 */
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
122 auto h_kern = [&](int i, int j) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
123 double a = Zplus[i];
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
124 double b = Zminus[j];
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
125
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
126 double h;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
127 if (abs(a - b) <= 2*eps2)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
128 h = signum(n_plus - 1 - i - j);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
129 else
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
130 h = (a + b)/(a - b);
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 return h;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
133 };
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
134
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
135 // Init left and right borders
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
136 vector<int> L(n_plus, 0);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
137 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
138
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
139 long Ltot = 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
140 long Rtot = n_minus*n_plus;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
141 int medc_idx = Rtot/2;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
142
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
143 // kth pair algorithm (Johnson & Mizoguchi)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
144 while (Rtot - Ltot > n_plus) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
145 // 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
146 vector<double> A;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
147 vector<int> W;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
148 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
149 if (L[i] <= R[i]) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
150 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
151 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
152 }
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 = wmedian(A, W);
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 double Am_eps = eps1*(eps1 + abs(Am));
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
157
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
158 //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
159 //median
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
160 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
161
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
162 {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
163 int j = 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
164 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
165 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
166 j++;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
167 P[i] = j - 1;
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
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
171 {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
172 int j = n_minus - 1;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
173 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
174 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
175 j--;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
176 Q[i] = j + 1;
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 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
179
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
180 long
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
181 sumP = sum(P) + n_plus,
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
182 sumQ = sum(Q);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
183
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
184 if (medc_idx <= sumP - 1) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
185 R = P;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
186 Rtot = sumP;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
187 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
188 else {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
189 if (medc_idx > sumQ - 1) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
190 L = Q;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
191 Ltot = sumQ;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
192 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
193 else
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
194 return Am;
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 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
197
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
198 // 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
199 // 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
200 // 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
201 vector<double> A;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
202 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
203 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
204 A.push_back(h_kern(i, j));
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
205 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
206 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
207 [](double x, double y) {return x > y;});
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
208
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
209 double Am = A[medc_idx - Ltot];
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
210 return Am;
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
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
214
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
215 int main(int argc, char** argv) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
216 double
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
217 eps1 = numeric_limits<double>::epsilon(),
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
218 eps2 = numeric_limits<double>::min();
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
219
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
220 string fname;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
221 if (argc > 1) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
222 fname = argv[1];
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
223 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
224 else {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
225 cerr << "Please provide input file." << endl;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
226 return 1;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
227 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
228
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
229 double trace_lev = 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
230 if(argc > 2) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
231 stringstream ss;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
232 ss << argv[2];
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
233 ss >> trace_lev;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
234 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
235
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
236 ifstream ifs(fname);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
237 if (not ifs) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
238 cerr << "File " << fname << " not found." << endl;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
239 return 1;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
240 }
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 vector<double> data;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
243 double datum;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
244 while (ifs >> datum) {
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
245 data.push_back(datum);
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
246 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
247
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
248 cout << setprecision(16)
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
249 << medcouple(data, eps1, eps2, trace_lev) << endl;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
250
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
251 return 0;
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
252 }
518ef922033e Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
253