$darkmode
statistics.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
23 #pragma once
24 #ifndef CLOE_UTILITY_STATISTICS_HPP_
25 #define CLOE_UTILITY_STATISTICS_HPP_
26 
27 #include <cmath> // for sqrt
28 #include <map> // for map<>
29 #include <string> // for string
30 
31 #include <fable/json.hpp> // for Json
32 
33 namespace cloe {
34 namespace utility {
35 
36 template <typename T>
37 class Pie {
38  public:
39  Pie() {}
40 
41  void reset() {
42  n_ = 0;
43  map_.clear();
44  }
45 
46  void push_back(T key) {
47  n_++;
48  map_[key]++;
49  }
50 
51  uint64_t count() const { return n_; }
52 
53  uint64_t count(T key) const { return map_.count(key) ? map_.at(key) : 0; }
54 
55  T mode() const {
56  T mode;
57  uint64_t max = 0;
58  for (auto& kv : map_) {
59  if (kv.second > max) {
60  mode = kv.first;
61  max = kv.second;
62  }
63  }
64  return mode;
65  }
66 
67  double proportion(T key) const {
68  return static_cast<double>(count(key)) / static_cast<double>(n_);
69  }
70 
71  std::map<T, double> proportions() const {
72  const double nd = static_cast<double>(n_);
73  std::map<T, double> prop;
74  for (auto& kv : map_) {
75  prop[kv.first] = static_cast<double>(kv.second) / nd;
76  }
77  return prop;
78  }
79 
80  // TODO(ben): Maybe specialize this for types that are directly supported by to_json.
81  // Alternatively, specialize on the nlohmann end of the story.
82  friend void to_json(fable::Json& j, const Pie<T>& pie) {
83  j = fable::Json{{"count", pie.n_}};
84 
85  // Distribution of values:
86  std::map<std::string, uint64_t> dist;
87  for (auto& kv : pie.map_) {
88  dist[to_string(kv.first)] = kv.second;
89  }
90  j["distribution"] = dist;
91 
92  // Proportions of values:
93  std::map<std::string, double> prop;
94  for (auto& kv : pie.proportions()) {
95  prop[to_string(kv.first)] = kv.second;
96  }
97  j["proportions"] = prop;
98  }
99 
100  private:
101  uint64_t n_{0};
102  std::map<T, uint64_t> map_;
103 };
104 
112 class Accumulator {
113  public:
114  Accumulator() { reset(); }
115 
121  void reset() {
122  n_ = 0;
123  mean_ = 0;
124  var_ = 0;
125  max_ = -INFINITY;
126  min_ = INFINITY;
127  }
128 
134  void push_back(double x) {
135  if (n_ == 0) {
136  n_ = 1;
137  mean_ = x;
138  var_ = 0;
139  min_ = x;
140  max_ = x;
141  return;
142  }
143 
144  n_++;
145  if (max_ < x) {
146  max_ = x;
147  }
148  if (min_ > x) {
149  min_ = x;
150  }
151  double m = mean_ + (x - mean_) / static_cast<double>(n_);
152  var_ = var_ + (x - mean_) * (x - m);
153  mean_ = m;
154  }
155 
159  uint64_t count() const { return n_; }
160 
164  double max() const { return max_; }
165 
169  double min() const { return min_; }
170 
174  double mean() const { return mean_; }
175 
182  double variance(bool sample = false) const {
183  if (n_ <= 1) {
184  if (n_ == 0) {
185  return NAN;
186  }
187  return 0;
188  }
189  if (sample) {
190  return var_ / static_cast<double>(n_ - 1);
191  } else {
192  return var_ / static_cast<double>(n_);
193  }
194  }
195 
202  double std_dev(bool sample = false) const { return std::sqrt(variance(sample)); }
203 
207  friend void to_json(fable::Json& j, const Accumulator& a) {
208  j = fable::Json{
209  {"count", a.n_},
210  {"min", a.min_},
211  {"max", a.max_},
212  {"mean", a.mean_},
213  {"variance", a.variance()},
214  {"std_deviation", a.std_dev()},
215  {"sample_variance", a.variance(true)},
216  {"sample_std_deviation", a.std_dev(true)},
217  };
218  }
219 
220  private:
221  uint64_t n_;
222  double mean_;
223  double var_;
224  double max_;
225  double min_;
226 };
227 
228 } // namespace utility
229 } // namespace cloe
230 
231 #endif // CLOE_UTILITY_STATISTICS_HPP_
double max() const
Definition: statistics.hpp:164
void reset()
Definition: statistics.hpp:121
friend void to_json(fable::Json &j, const Accumulator &a)
Definition: statistics.hpp:207
double variance(bool sample=false) const
Definition: statistics.hpp:182
double mean() const
Definition: statistics.hpp:174
nlohmann::json Json
Definition: json.hpp:62
void push_back(double x)
Definition: statistics.hpp:134
double std_dev(bool sample=false) const
Definition: statistics.hpp:202
Definition: coordinator.hpp:36
uint64_t count() const
Definition: statistics.hpp:159
double min() const
Definition: statistics.hpp:169
Definition: statistics.hpp:112
Definition: statistics.hpp:37