$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 
25 #include <cmath> // for sqrt
26 #include <map> // for map<>
27 #include <string> // for string
28 
29 #include <fable/json.hpp> // for Json
30 
31 namespace cloe {
32 namespace utility {
33 
34 template <typename T>
35 class Pie {
36  public:
37  Pie() {}
38 
39  void reset() {
40  n_ = 0;
41  map_.clear();
42  }
43 
44  void push_back(T key) {
45  n_++;
46  map_[key]++;
47  }
48 
49  uint64_t count() const { return n_; }
50 
51  uint64_t count(T key) const { return map_.count(key) ? map_.at(key) : 0; }
52 
53  T mode() const {
54  T mode;
55  uint64_t max = 0;
56  for (auto& kv : map_) {
57  if (kv.second > max) {
58  mode = kv.first;
59  max = kv.second;
60  }
61  }
62  return mode;
63  }
64 
65  double proportion(T key) const {
66  return static_cast<double>(count(key)) / static_cast<double>(n_);
67  }
68 
69  std::map<T, double> proportions() const {
70  const double nd = static_cast<double>(n_);
71  std::map<T, double> prop;
72  for (auto& kv : map_) {
73  prop[kv.first] = static_cast<double>(kv.second) / nd;
74  }
75  return prop;
76  }
77 
78  // TODO(ben): Maybe specialize this for types that are directly supported by to_json.
79  // Alternatively, specialize on the nlohmann end of the story.
80  friend void to_json(fable::Json& j, const Pie<T>& pie) {
81  j = fable::Json{{"count", pie.n_}};
82 
83  // Distribution of values:
84  std::map<std::string, uint64_t> dist;
85  for (auto& kv : pie.map_) {
86  dist[to_string(kv.first)] = kv.second;
87  }
88  j["distribution"] = dist;
89 
90  // Proportions of values:
91  std::map<std::string, double> prop;
92  for (auto& kv : pie.proportions()) {
93  prop[to_string(kv.first)] = kv.second;
94  }
95  j["proportions"] = prop;
96  }
97 
98  private:
99  uint64_t n_{0};
100  std::map<T, uint64_t> map_;
101 };
102 
110 class Accumulator {
111  public:
112  Accumulator() { reset(); }
113 
119  void reset() {
120  n_ = 0;
121  mean_ = 0;
122  var_ = 0;
123  max_ = -INFINITY;
124  min_ = INFINITY;
125  }
126 
132  void push_back(double x) {
133  if (n_ == 0) {
134  n_ = 1;
135  mean_ = x;
136  var_ = 0;
137  min_ = x;
138  max_ = x;
139  return;
140  }
141 
142  n_++;
143  if (max_ < x) {
144  max_ = x;
145  }
146  if (min_ > x) {
147  min_ = x;
148  }
149  double m = mean_ + (x - mean_) / static_cast<double>(n_);
150  var_ = var_ + (x - mean_) * (x - m);
151  mean_ = m;
152  }
153 
157  uint64_t count() const { return n_; }
158 
162  double max() const { return max_; }
163 
167  double min() const { return min_; }
168 
172  double mean() const { return mean_; }
173 
180  double variance(bool sample = false) const {
181  if (n_ <= 1) {
182  if (n_ == 0) {
183  return NAN;
184  }
185  return 0;
186  }
187  if (sample) {
188  return var_ / static_cast<double>(n_ - 1);
189  } else {
190  return var_ / static_cast<double>(n_);
191  }
192  }
193 
200  double std_dev(bool sample = false) const { return std::sqrt(variance(sample)); }
201 
205  friend void to_json(fable::Json& j, const Accumulator& a) {
206  j = fable::Json{
207  {"count", a.n_},
208  {"min", a.min_},
209  {"max", a.max_},
210  {"mean", a.mean_},
211  {"variance", a.variance()},
212  {"std_deviation", a.std_dev()},
213  {"sample_variance", a.variance(true)},
214  {"sample_std_deviation", a.std_dev(true)},
215  };
216  }
217 
218  private:
219  uint64_t n_;
220  double mean_;
221  double var_;
222  double max_;
223  double min_;
224 };
225 
226 } // namespace utility
227 } // namespace cloe
Definition: statistics.hpp:110
double min() const
Definition: statistics.hpp:167
double max() const
Definition: statistics.hpp:162
double std_dev(bool sample=false) const
Definition: statistics.hpp:200
void reset()
Definition: statistics.hpp:119
double mean() const
Definition: statistics.hpp:172
uint64_t count() const
Definition: statistics.hpp:157
double variance(bool sample=false) const
Definition: statistics.hpp:180
friend void to_json(fable::Json &j, const Accumulator &a)
Definition: statistics.hpp:205
void push_back(double x)
Definition: statistics.hpp:132
Definition: statistics.hpp:35
nlohmann::json Json
Definition: fable_fwd.hpp:35