crawlserv++  [under development]
Application for crawling and analyzing textual content of websites.
Math.hpp
Go to the documentation of this file.
1 /*
2  *
3  * ---
4  *
5  * Copyright (C) 2020 Anselm Schmidt (ans[ät]ohai.su)
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version in addition to the terms of any
11  * licences already herein identified.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  *
21  * ---
22  *
23  * Math.hpp
24  *
25  * Namespace for global math functions.
26  *
27  * Created on: Nov 13, 2020
28  * Author: ans
29  */
30 
31 #ifndef HELPER_MATH_HPP_
32 #define HELPER_MATH_HPP_
33 
34 #include <algorithm> // std::nth_element
35 #include <cmath> // std::fabs
36 #include <cstddef> // std::size_t
37 #include <limits> // std::numeric_limits
38 #include <memory> // std::allocator
39 #include <numeric> // std::accumulate
40 #include <type_traits> // std::enable_if
41 #include <vector> // std::vector
42 
45 
48 
58  template<typename R, typename T, template<typename, typename> class Container>
59  R avg(const Container<T, std::allocator<T>>& values) {
60  return static_cast<R>(
61  std::accumulate(values.begin(), values.end(), 0ULL) //NOLINT(bugprone-fold-init-type)
62  ) / values.size();
63  }
64 
74  template<typename R, typename T, template<typename, typename> class Container>
75  R median(Container<T, std::allocator<T>>& values) {
76  if(values.empty()) {
77  return R{};
78  }
79 
80  if(values.size() % 2 == 0) {
81  const auto iterator1{
82  values.begin() + values.size() / 2 - 1
83  };
84  const auto iterator2{
85  values.begin() + values.size() / 2
86  };
87 
88  std::nth_element(values.begin(), iterator1 , values.end());
89 
90  const auto value1{*iterator1};
91 
92  std::nth_element(values.begin(), iterator2 , values.end());
93 
94  const auto value2{*iterator2};
95 
96  return static_cast<R>((value1 + value2) / 2); //NOLINT(bugprone-integer-division)
97  }
98 
99  const auto iterator{
100  values.begin() + values.size() / 2
101  };
102 
103  std::nth_element(values.begin(), iterator, values.end());
104 
105  return *iterator;
106  }
107 
109 
121  template<typename R, typename T, template<typename, typename> class Container>
122  R variance(R mean, Container<T, std::allocator<T>>& values) {
123  R sum{};
124 
125  for(const auto value : values) {
126  sum += (value - mean) * (value - mean);
127  }
128 
129  return sum / values.size();
130  }
131 
143  template<typename R, typename T, template<typename, typename> class Container>
144  R variance(Container<T, std::allocator<T>>& values) {
145  const auto mean{avg(values)};
146 
147  return variance(mean, values);
148  }
149 
153 
155 
161  template<typename T> typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
162  almostEqual(T x, T y, int ulp) {
163  // the machine epsilon has to be scaled to the magnitude of the values used
164  // and multiplied by the desired precision in ULPs (units in the last place)
165  return std::fabs(x - y) <= std::numeric_limits<T>::epsilon() * std::fabs(x + y) * ulp
166  // unless the result is subnormal
167  || std::fabs(x - y) < std::numeric_limits<T>::min();
168  }
169 
171 
172 } /* namespace crawlservpp::Helper::Math */
173 
174 #endif /* HELPER_MATH_HPP_ */
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type almostEqual(T x, T y, int ulp)
Compares two floating-point values using epsilon.
Definition: Math.hpp:162
Namespace for global math functions.
Definition: Math.hpp:44
R avg(const Container< T, std::allocator< T >> &values)
Definition: Math.hpp:59
R median(Container< T, std::allocator< T >> &values)
Definition: Math.hpp:75
R variance(R mean, Container< T, std::allocator< T >> &values)
Calculates the variance from the given mean of all elements in the given container.
Definition: Math.hpp:122