Empirical
stats.h
Go to the documentation of this file.
1 
12 #ifndef EMP_STATS_H
13 #define EMP_STATS_H
14 
15 #include <type_traits>
16 #include <map>
17 #include <unordered_map>
18 #include <cmath>
19 #include <vector>
20 #include <set>
21 #include <unordered_set>
22 #include <functional>
23 
24 #include "../base/vector.h"
25 #include "../meta/type_traits.h"
26 
27 namespace emp {
28 
31  template <typename C>
32  typename std::enable_if<!emp::is_ptr_type<typename C::value_type>::value && std::is_scalar<typename C::value_type>::value, typename C::value_type>::type
33  Sum(C & elements) {
34 
35  double total = 0;
36  for (auto element : elements) {
37  total += element;
38  }
39 
40  return total;
41  }
42 
45  template <typename C>
46  typename std::enable_if<emp::is_ptr_type<typename C::value_type>::value && std::is_scalar<typename emp::remove_ptr_type<typename C::value_type>::type >::value, typename emp::remove_ptr_type<typename C::value_type>::type >::type
47  Sum(C & elements) {
48 
49  double total = 0;
50  for (auto element : elements) {
51  total += *element;
52  }
53 
54  return total;
55  }
56 
57 
59  template <typename C>
60  typename std::enable_if<!emp::is_ptr_type<typename C::value_type>::value, double>::type
61  ShannonEntropy(C & elements) {
62 
63  // Count number of each value present
64  std::map<typename C::value_type, int> counts;
65  for (auto element : elements) {
66  if (counts.find(element) != counts.end()) {
67  counts[element]++;
68  } else {
69  counts[element] = 1;
70  }
71  }
72 
73  // Shannon entropy calculation
74  double result = 0;
75  for (auto element : counts) {
76  double p = double(element.second)/elements.size();
77  result += p * Log2(p);
78  }
79 
80  return -1 * result;
81  }
82 
84  template <typename C>
85  typename std::enable_if<emp::is_ptr_type<typename C::value_type>::value, double>::type
86  ShannonEntropy(C & elements) {
87  // std::cout<< "In se" << std::endl;
88  using pointed_at = typename emp::remove_ptr_type<typename C::value_type>::type;
89  // Count number of each value present
90  std::map<pointed_at, int> counts;
91  for (auto element : elements) {
92  if (counts.find(*element) != counts.end()) {
93  counts[*element]++;
94  } else {
95  counts[*element] = 1;
96  }
97 
98  }
99  // Shannon entropy calculation
100  double result = 0;
101  for (auto element : counts) {
102  double p = double(element.second)/elements.size();
103  result += p * log2(p);
104  }
105  // std::cout<< "leaving se" << std::endl;
106  return -1 * result;
107  }
108 
111  template <typename C>
112  typename std::enable_if<!emp::is_ptr_type<typename C::value_type>::value && std::is_scalar<typename C::value_type>::value, double>::type
113  Variance(C & elements) {
114 
115  double var = 0;
116  double mean = (double)Sum(elements)/elements.size();
117  for (auto element : elements) {
118  var += emp::Pow(element - mean, 2);
119  }
120  return var/elements.size();
121  }
122 
125  template <typename C>
126  typename std::enable_if<emp::is_ptr_type<typename C::value_type>::value && std::is_scalar<typename emp::remove_ptr_type<typename C::value_type>::type >::value, double>::type
127  Variance(C & elements) {
128 
129  double var = 0;
130  double mean = (double)Sum(elements)/elements.size();
131  for (auto element : elements) {
132  var += emp::Pow(*element - mean, 2);
133  }
134  return var/elements.size();
135  }
136 
140  template <typename C>
142  Mean(C & elements) {
143  return (double)Sum(elements)/elements.size();
144  }
145 
149  template <typename C>
151  StandardDeviation(C & elements) {
152  return sqrt(Variance(elements));
153  }
154 
156  template <typename C>
157  typename std::enable_if<!emp::is_ptr_type<typename C::value_type>::value, int>::type
158  UniqueCount(C & elements) {
159  // Converting to a set will remove duplicates leaving only unique values
160  std::set<typename C::value_type> unique_elements(elements.begin(),
161  elements.end());
162  return unique_elements.size();
163  }
164 
167  template <typename C>
168  typename std::enable_if<emp::is_ptr_type<typename C::value_type>::value, int>::type
169  UniqueCount(C & elements) {
170  // Converting to a set will remove duplicates leaving only unique values
171  using pointed_at = typename emp::remove_ptr_type<typename C::value_type>::type;
172  std::set<pointed_at> unique_elements;
173  for (auto element : elements) {
174  unique_elements.insert(*element);
175  }
176 
177  return unique_elements.size();
178  }
179 
181  template <typename C, typename RET_TYPE, typename ARG_TYPE>
182  RET_TYPE MaxResult(std::function<RET_TYPE(ARG_TYPE)> & fun, C & elements){
183  auto best = fun(elements.front()); // @CAO Technically, front is processed twice...
184  for (auto element : elements){
185  auto result = fun(element);
186  if (result > best) best = result;
187  }
188  return best;
189  }
190 
192  template <typename C, typename RET_TYPE, typename ARG_TYPE>
193  RET_TYPE MinResult(std::function<RET_TYPE(ARG_TYPE)> & fun, C & elements){
194  auto best = fun(elements.front()); // @CAO Technically, front is processed twice...
195  for (auto element : elements){
196  auto result = fun(element);
197  if (result < best) best = result;
198  }
199  return best;
200  }
201 
204  template <typename C, typename RET_TYPE, typename ARG_TYPE>
205  typename std::enable_if<std::is_scalar<RET_TYPE>::value, double>::type
206  MeanResult(std::function<RET_TYPE(ARG_TYPE)> & fun, C & elements){
207  double cumulative_value = 0;
208  double count = 0;
209  for (auto element : elements){
210  ++count;
211  cumulative_value += fun(element);
212  }
213  return (cumulative_value / count);
214  }
215 
217  template <typename C, typename RET_TYPE, typename ARG_TYPE>
218  emp::vector<RET_TYPE> ApplyFunction(std::function<RET_TYPE(ARG_TYPE)> & fun, C & elements) {
219  emp::vector<RET_TYPE> results;
220  for (auto element : elements){
221  results.push_back(fun(element));
222  }
223  return results;
224  }
225 
226  // This variant is actually super confusing because the value_type of world
227  // and population managers are pointers whereas the type that they're templated
228  // on is not. Also because the insert method for emp::vectors doesn't take an
229  // additional argument?
230 
231  /* template <template <typename> class C, typename RET_TYPE, typename T>
232  C<RET_TYPE> RunFunctionOnContainer(std::function<RET_TYPE(T)> fun, C<T> & elements) {
233  C<RET_TYPE> results;
234  for (auto element : elements){
235  results.insert(fun(element), results.back());
236  }
237  return results;
238  } */
239 
240 }
241 
242 #endif
243 
244 //Base class outputs most recent
245 //Write derived class
RET_TYPE MinResult(std::function< RET_TYPE(ARG_TYPE)> &fun, C &elements)
Run the provided function on every member of a container and return the MINIMUM result.
Definition: stats.h:193
RET_TYPE MaxResult(std::function< RET_TYPE(ARG_TYPE)> &fun, C &elements)
Run the provided function on every member of a container and return the MAXIMUM result.
Definition: stats.h:182
REAL_TYPE sfinae_decoy
Definition: meta.h:93
std::enable_if<!emp::is_ptr_type< typename C::value_type >::value, int >::type UniqueCount(C &elements)
Count the number of unique elements in a container.
Definition: stats.h:158
std::enable_if<!emp::is_ptr_type< typename C::value_type >::value, double >::type ShannonEntropy(C &elements)
Calculate Shannon Entropy of the members of the container passed.
Definition: stats.h:61
emp::sfinae_decoy< double, typename C::value_type > StandardDeviation(C &elements)
Definition: stats.h:151
void push_back(PB_Ts &&...args)
Definition: vector.h:189
emp::vector< RET_TYPE > ApplyFunction(std::function< RET_TYPE(ARG_TYPE)> &fun, C &elements)
Run the provided function on every member of a container and return a vector of ALL results...
Definition: stats.h:218
emp::sfinae_decoy< double, typename C::value_type > Mean(C &elements)
Definition: stats.h:142
static constexpr double Log2(double x)
Compile-time log base 2 calculator.
Definition: math.h:120
std::enable_if< std::is_scalar< RET_TYPE >::value, double >::type MeanResult(std::function< RET_TYPE(ARG_TYPE)> &fun, C &elements)
Definition: stats.h:206
static constexpr type_if< T, std::is_integral > Pow(T base, T p)
A fast (O(log p)) integral-power command.
Definition: math.h:150
T type
Definition: type_traits.h:30
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
std::enable_if<!emp::is_ptr_type< typename C::value_type >::value &&std::is_scalar< typename C::value_type >::value, double >::type Variance(C &elements)
Definition: stats.h:113
std::enable_if<!emp::is_ptr_type< typename C::value_type >::value &&std::is_scalar< typename C::value_type >::value, typename C::value_type >::type Sum(C &elements)
Definition: stats.h:33