ztsdb
align_funcs.hpp
1 // (C) 2016 Leonardo Silvestri
2 //
3 // This file is part of ztsdb.
4 //
5 // ztsdb is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // ztsdb is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with ztsdb. If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 #ifndef ALIGN_FUNCS_HPP
20 #define ALIGN_FUNCS_HPP
21 
22 
23 #include <queue>
24 #include "globals.hpp"
25 
26 
27 namespace ztsdb {
28 
29  template <typename FIter, typename T>
30  struct mean_element {
31  static T f(FIter b, FIter e) {
32  if (e-b == 0) return Global::ZNAN;
33  return std::accumulate(b, e, static_cast<T>(0)) / (e-b);
34  }
35  };
36 
37  template <typename FIter, typename T>
38  struct max_element {
39  static T f(FIter b, FIter e) {
40  if (e-b == 0) return Global::ZNAN;
41  return *std::max_element(b, e);
42  }
43  };
44 
45  template <typename FIter, typename T>
46  struct min_element {
47  static T f(FIter b, FIter e) {
48  if (e-b == 0) return Global::ZNAN;
49  return *std::min_element(b, e);
50  }
51  };
52 
53  template <typename FIter, typename T>
54  struct count_element {
55  static T f(FIter b, FIter e) {
56  if (e-b == 0) return 0;
57  return e-b;
58  }
59  };
60 
61  template <typename FIter, typename T>
62  struct median_element {
63  static T f(FIter b, FIter e) {
64  if (e-b == 0) return Global::ZNAN;
65 
66  std::priority_queue<double> left;
67  std::priority_queue<
68  double,
69  std::priority_queue<double>::container_type,
70  std::greater<double>
71  > right;
72 
73  for (auto i=b; i!=e; ++i) {
74  if (left.size() == right.size()) {
75  if (!left.size() || *i < left.top()) {
76  left.push(*i);
77  }
78  else {
79  right.push(*i);
80  }
81  }
82  else if (left.size() < right.size()) {
83  if (*i < right.top()) {
84  left.push(*i);
85  }
86  else {
87  left.push(right.top());
88  right.pop();
89  right.push(*i);
90  }
91  }
92  else { // left.size() > right.size()
93  if (*i > left.top()) {
94  right.push(*i);
95  }
96  else {
97  right.push(left.top());
98  left.pop();
99  left.push(*i);
100  }
101  }
102  }
103 
104  if (left.size() == right.size()) return (left.top() + right.top())/2.0;
105  if (left.size() < right.size()) return right.top();
106  else return left.top();
107  }
108  };
109 
110 
111  template <typename FIter, typename F>
112  struct applyd {
113  static void f(double d, FIter b, FIter e) {
114  std::for_each(b, e, [d](double &n){ n = F()(n, d); });
115  }
116  };
117 
118 } // end namespace ztsdb
119 
120 
121 #endif
ztsdb::median_element
Definition: align_funcs.hpp:62
ztsdb::applyd
Definition: align_funcs.hpp:112
ztsdb::max_element
Definition: align_funcs.hpp:38
ztsdb::mean_element
Definition: align_funcs.hpp:30
ztsdb::min_element
Definition: align_funcs.hpp:46
ztsdb::count_element
Definition: align_funcs.hpp:54