Mercurial > hg > medcouple
annotate jmedcouple.c++ @ 35:6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 19 Jan 2015 10:20:22 -0500 |
parents | 2e277129e81b |
children | 4fb3b87b8610 |
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 |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
12 template <typename T> |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
13 int signum(T val) { |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
14 return (T(0) < val) - (val < T(0)); |
25
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()); |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
20 } |
25
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, |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
27 const vector<long>& W) |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
28 { |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
29 typedef pair<double, long> aw_t; |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
30 |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
31 long n = A.size(); |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
32 vector<aw_t> AW(n); |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
33 for (long i = 0; i < n; i ++) |
25
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 |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
38 long beg = 0; |
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
39 long end = n - 1; |
25
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) { |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
42 long mid = (beg + end)/2; |
25
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 long wleft = 0, wright = 0; |
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 for (aw_t& aw: AW ) { |
35
6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
30
diff
changeset
|
49 double a; |
6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
30
diff
changeset
|
50 long w; |
6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
30
diff
changeset
|
51 tie(a, w) = move(aw); |
6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
30
diff
changeset
|
52 if (a > trial) |
6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
30
diff
changeset
|
53 wleft += w; |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
54 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
55 // This also includes a == trial, i.e. the "middle" weight. |
35
6c264f2053bc
jmedcouple: use std::tie and std::move for tuple unpacking
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
30
diff
changeset
|
56 wright += w; |
25
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 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
59 if (2*wleft > wtot) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
60 end = mid; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
61 else if (2*wright < wtot) |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
62 beg = mid; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
63 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
64 return trial; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
65 } |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
66 |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
67 return 0; |
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 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
70 double medcouple(const std::vector<double>& X, |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
71 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
|
72 double eps2 = numeric_limits<double>::min()) |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
73 { |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
74 long n = X.size(), n2 = (n - 1)/2; |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
75 |
25
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; |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
83 if (n % 2 == 1) |
25
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; |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
93 |
25
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; |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
106 copy_if(Z.begin(), Z.end(), back_inserter(Zplus), |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
107 [=](double z){return z >= -Zeps;}); |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
108 copy_if(Z.begin(), Z.end(), back_inserter(Zminus), |
25
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 |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
111 long |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
112 n_plus = Zplus.size(), |
25
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 */ |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
122 auto h_kern = [&](long i, long j) { |
25
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 }; |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
134 |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
135 // Init left and right borders |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
136 vector<long> L(n_plus, 0); |
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
137 vector<long> R(n_plus, n_minus - 1); |
25
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; |
27
40cbfb64e952
jmedcouple: change type of medc_idx to long
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
25
diff
changeset
|
141 long medc_idx = Rtot/2; |
25
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) { |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
145 |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
146 // 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
|
147 vector<double> A; |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
148 vector<long> W; |
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
149 for (long i = 0; i < n_plus; i++) { |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
150 if (L[i] <= R[i]) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
151 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
|
152 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
|
153 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
154 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
155 double Am = wmedian(A, W); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
156 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
157 double Am_eps = eps1*(eps1 + abs(Am)); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
158 |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
159 // Compute new left and right boundaries, based on the weighted |
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
160 // median |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
161 vector<long> P(n_plus), Q(n_plus); |
25
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 { |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
164 long j = 0; |
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
165 for (long i = n_plus - 1; i >= 0; i--) { |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
166 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
|
167 j++; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
168 P[i] = j - 1; |
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 { |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
173 long j = n_minus - 1; |
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
174 for (long i = 0; i < n_plus; i++) { |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
175 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
|
176 j--; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
177 Q[i] = j + 1; |
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 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
181 long |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
182 sumP = sum(P) + n_plus, |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
183 sumQ = sum(Q); |
30
2e277129e81b
jmedcouple: whitespace fixes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
29
diff
changeset
|
184 |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
185 if (medc_idx <= sumP - 1) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
186 R = P; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
187 Rtot = sumP; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
188 } |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
189 else { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
190 if (medc_idx > sumQ - 1) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
191 L = Q; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
192 Ltot = sumQ; |
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 else |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
195 return Am; |
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 |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
199 // 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
|
200 // 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
|
201 // 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
|
202 vector<double> A; |
29
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
203 for (long i = 0; i < n_plus; i++) { |
cf8c8c825c6d
jmedcouple: change all ints to long, to avoid overflow
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
28
diff
changeset
|
204 for (long j = L[i]; j <= R[i]; j++) |
25
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
205 A.push_back(h_kern(i, j)); |
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 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
|
208 [](double x, double y) {return x > y;}); |
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 double Am = A[medc_idx - Ltot]; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
211 return Am; |
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 ifstream ifs(fname); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
230 if (not ifs) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
231 cerr << "File " << fname << " not found." << endl; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
232 return 1; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
233 } |
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 vector<double> data; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
236 double datum; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
237 while (ifs >> datum) { |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
238 data.push_back(datum); |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
239 } |
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 cout << setprecision(16) |
28
65f6fad65f49
jmedcouple: get rid of unused trace_lev parameter
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
27
diff
changeset
|
242 << medcouple(data, eps1, eps2) << endl; |
25
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 return 0; |
518ef922033e
Add C++ translation of Python code
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
245 } |