indigoX
numerics.hpp
Go to the documentation of this file.
1 #ifndef INDIGOX_UTILS_NUMERICS_HPP
2 #define INDIGOX_UTILS_NUMERICS_HPP
3 
4 #include <algorithm>
5 #include <cmath>
6 #include <cstdint>
7 #include <iterator>
8 #include <numeric>
9 #include <string>
10 #include <vector>
11 
12 namespace indigox {
13 
14  template <typename InputIter, typename T>
15  size_t Combinations(InputIter first, InputIter last, size_t r,
16  std::vector<std::vector<T>> &out) {
17  out.clear();
18  std::vector<T> pool(first, last);
19  if (r > pool.size()) return 0;
20  std::vector<size_t> indices(r);
21  std::iota(indices.begin(), indices.end(), 0);
22  out.emplace_back(std::vector<T>());
23  for (size_t i : indices) out.back().emplace_back(pool[i]);
24  std::vector<size_t> tmp(r);
25  std::iota(tmp.begin(), tmp.end(), 0);
26  std::reverse(tmp.begin(), tmp.end());
27  while (true) {
28  size_t i = 0;
29  bool broken = false;
30  for (size_t x : tmp) {
31  if (indices[x] != x + pool.size() - r) {
32  i = x;
33  broken = true;
34  break;
35  }
36  }
37  if (!broken) break;
38  ++indices[i];
39  std::vector<size_t> tmp2(r - i - 1);
40  std::iota(tmp2.begin(), tmp2.end(), i + 1);
41  for (size_t j : tmp2) indices[j] = indices[j - 1] + 1;
42  out.emplace_back(std::vector<T>());
43  for (size_t i : indices) out.back().emplace_back(pool[i]);
44  }
45  return out.size();
46  }
47 
52  template <class Iter> double CalculateMean(Iter begin, Iter end) {
53  double sum = std::accumulate(begin, end, 0.0);
54  return sum / std::distance(begin, end);
55  }
56 
65  template <class RandomIter>
66  double CalculateMedian(RandomIter begin, RandomIter end) {
67  if (begin == end)
68  throw std::runtime_error("Median of empty range is undefined");
69  size_t sz = end - begin;
70  size_t mid = sz / 2;
71  RandomIter target = begin + mid;
72  std::nth_element(begin, target, end);
73 
74  if (sz % 2)
75  return static_cast<double>(*target);
76  else {
77  double x = static_cast<double>(*target);
78  RandomIter next = std::max_element(begin, target);
79  return (x + static_cast<double>(*next)) / 2.0;
80  }
81  }
82 
83  template <class Iter>
84  double CalculateStandardDeviation(Iter begin, Iter end) {
85  double mean = CalculateMean(begin, end);
86  std::vector<double> d(std::distance(begin, end));
87  std::transform(begin, end, d.begin(),
88  [mean](double x) { return x - mean; });
89  double sum_sq = std::inner_product(d.begin(), d.end(), d.begin(), 0.0);
90  return std::sqrt(sum_sq / d.size());
91  }
92 
93 } // namespace indigox
94 
95 #endif /* INDIGOX_UTILS_NUMERICS_HPP */
size_t Combinations(InputIter first, InputIter last, size_t r, std::vector< std::vector< T >> &out)
Definition: numerics.hpp:15
Namespace for all graph related functionality.
Definition: access.hpp:7
double CalculateStandardDeviation(Iter begin, Iter end)
Definition: numerics.hpp:84
double CalculateMean(Iter begin, Iter end)
Calculate the mean of a range of numbers.
Definition: numerics.hpp:52
double CalculateMedian(RandomIter begin, RandomIter end)
Calculate the median of a range of numbers.
Definition: numerics.hpp:66