AIToolbox
A library that offers tools for AI problem solving.
Core.hpp
Go to the documentation of this file.
1 #ifndef AI_TOOLBOX_UTILS_CORE_HEADER_FILE
2 #define AI_TOOLBOX_UTILS_CORE_HEADER_FILE
3 
4 #include <cmath>
5 #include <limits>
6 #include <compare>
7 
8 #include <AIToolbox/Types.hpp>
9 
10 #include <boost/functional/hash.hpp>
11 
12 namespace AIToolbox {
14  constexpr auto equalToleranceSmall = 0.000001;
18  constexpr auto equalToleranceGeneral = 0.00000000001;
19 
30  inline unsigned ceil(unsigned x, unsigned y) {
31  return (x + y - 1) / y;
32  }
33 
45  inline bool checkEqualSmall(const double a, const double b) {
46  return ( std::fabs(a - b) <= equalToleranceSmall );
47  }
48 
60  inline bool checkDifferentSmall(const double a, const double b) {
61  return !checkEqualSmall(a,b);
62  }
63 
74  inline bool checkEqualGeneral(const double a, const double b) {
75  if ( checkEqualSmall(a,b) ) return true;
76  return ( std::fabs(a - b) <= std::min(std::fabs(a), std::fabs(b)) * equalToleranceGeneral );
77  }
78 
89  inline bool checkDifferentGeneral(const double a, const double b) {
90  return !checkEqualGeneral(a,b);
91  }
92 
100  template <typename V>
101  bool checkEqualSmall(const V & v, const double d) {
102  for (decltype(v.size()) i = 0; i < v.size(); ++i)
103  if (!checkEqualSmall(v[i], d)) return false;
104 
105  return true;
106  }
107 
113  template <typename V>
114  bool checkDifferentSmall(const V & v, const double d) {
115  return !checkEqualSmall(v, d);
116  }
117 
125  template <typename V>
126  bool checkEqualGeneral(const V & v, const double d) {
127  for (decltype(v.size()) i = 0; i < v.size(); ++i)
128  if (!checkEqualGeneral(v[i], d)) return false;
129 
130  return true;
131  }
132 
138  template <typename V>
139  bool checkDifferentGeneral(const V & v, const double d) {
140  return !checkEqualGeneral(v, d);
141  }
142 
157  template <typename V>
158  std::strong_ordering veccmp(const V & lhs, const V & rhs) {
159  assert(lhs.size() == rhs.size());
160  for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i) {
161  // We can't use spaceship here to support floating points.
162  if (lhs[i] == rhs[i]) continue;
163  return lhs[i] > rhs[i] ? std::strong_ordering::greater : std::strong_ordering::less;
164  }
165  return std::strong_ordering::equal;
166  }
167 
181  template <typename V>
182  std::partial_ordering veccmpSmall(const V & lhs, const V & rhs) {
183  assert(lhs.size() == rhs.size());
184  for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i) {
185  if (checkEqualSmall(lhs[i], rhs[i])) continue;
186  return lhs[i] <=> rhs[i];
187  }
188  return std::partial_ordering::equivalent;
189  }
190 
204  template <typename V>
205  std::partial_ordering veccmpGeneral(const V & lhs, const V & rhs) {
206  assert(lhs.size() == rhs.size());
207  for (decltype(lhs.size()) i = 0; i < lhs.size(); ++i) {
208  if (checkEqualGeneral(lhs[i], rhs[i])) continue;
209  return lhs[i] <=> rhs[i];
210  }
211  return std::partial_ordering::equivalent;
212  }
213 
227  template <typename It>
228  It sequential_sorted_find(It begin, It end, const typename std::iterator_traits<It>::value_type & elem) {
229  while (begin != end && *begin < elem) ++begin;
230  return begin;
231  }
232 
246  template <typename It>
247  bool sequential_sorted_contains(It begin, It end, const typename std::iterator_traits<It>::value_type & elem) {
248  const auto it = sequential_sorted_find(begin, end, elem);
249  if (it != end && *it == elem) return true;
250  return false;
251  }
252 
265  template <typename V>
266  bool sequential_sorted_contains(const V & v, const V & elems) {
267  assert(elems.size() <= v.size());
268 
269  if (v.size() == elems.size())
270  return veccmp(v, elems) == 0;
271 
272  decltype(v.size()) i = 0, j = 0;
273  while (j < elems.size()) {
274  while (i < v.size() && v[i] < elems[j]) ++i;
275  if (i == v.size() || v[i] > elems[j]) return false;
276  ++i, ++j;
277  }
278  return j == elems.size();
279  }
280 
287  template <typename T>
288  void set_union_inplace(std::vector<T> & lhs, const std::vector<T> & rhs) {
289  const auto mid = lhs.size();
290  lhs.reserve(lhs.size() + rhs.size());
291  std::set_difference(std::begin(rhs), std::end(rhs),
292  std::begin(lhs), std::end(lhs), std::back_inserter(lhs));
293  std::inplace_merge(std::begin(lhs), std::begin(lhs)+mid, std::end(lhs));
294  }
295 
315  template <typename It, typename F>
316  auto max_element_unary(It begin, const It end, F unary_converter) {
317  if (begin == end) return std::make_pair(end, 0.0);
318  auto retval = begin;
319  double max = std::invoke(unary_converter, *begin);
320 
321  while (++begin != end) {
322  auto newV = std::invoke(unary_converter, *begin);
323  if (newV > max) {
324  retval = begin;
325  max = newV;
326  }
327  }
328  return std::make_pair(retval, max);
329  }
330 
349  template <typename T, typename U>
350  void copyDumb3D(const T & in, U & out, const size_t d1, const size_t d2, const size_t d3) {
351  for ( size_t i = 0; i < d1; ++i )
352  for ( size_t j = 0; j < d2; ++j )
353  for ( size_t x = 0; x < d3; ++x )
354  out[i][j][x] = in[i][j][x];
355  }
356 }
357 
358 namespace Eigen {
362  inline size_t hash_value(const AIToolbox::Vector & v) {
363  return boost::hash_range(v.data(), v.data() + v.size());
364  }
365 }
366 
367 #endif
AIToolbox::checkDifferentSmall
bool checkDifferentSmall(const double a, const double b)
This function checks if two doubles near [0,1] are reasonably different.
Definition: Core.hpp:60
AIToolbox::checkDifferentGeneral
bool checkDifferentGeneral(const double a, const double b)
This function checks if two doubles are reasonably different.
Definition: Core.hpp:89
Eigen::hash_value
size_t hash_value(const AIToolbox::Vector &v)
This function enables hashing of Vectors with boost::hash.
Definition: Core.hpp:362
Eigen
Definition: Core.hpp:358
AIToolbox::sequential_sorted_find
It sequential_sorted_find(It begin, It end, const typename std::iterator_traits< It >::value_type &elem)
This function returns an iterator to the position where the input should be in a sorted range,...
Definition: Core.hpp:228
AIToolbox::veccmpSmall
std::partial_ordering veccmpSmall(const V &lhs, const V &rhs)
This function compares two general vectors of equal size lexicographically.
Definition: Core.hpp:182
AIToolbox::veccmp
std::strong_ordering veccmp(const V &lhs, const V &rhs)
This function compares two general vectors of equal size lexicographically.
Definition: Core.hpp:158
AIToolbox::copyDumb3D
void copyDumb3D(const T &in, U &out, const size_t d1, const size_t d2, const size_t d3)
Copies a 3d container into another 3d container.
Definition: Core.hpp:350
AIToolbox::veccmpGeneral
std::partial_ordering veccmpGeneral(const V &lhs, const V &rhs)
This function compares two general vectors of equal size lexicographically.
Definition: Core.hpp:205
AIToolbox::Vector
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
Definition: Types.hpp:16
AIToolbox::equalToleranceSmall
constexpr auto equalToleranceSmall
This is the max absolute difference for which two values can be considered equal.
Definition: Core.hpp:14
AIToolbox::equalToleranceGeneral
constexpr auto equalToleranceGeneral
Definition: Core.hpp:18
AIToolbox
Definition: Experience.hpp:6
AIToolbox::sequential_sorted_contains
bool sequential_sorted_contains(It begin, It end, const typename std::iterator_traits< It >::value_type &elem)
This function returns whether a sorted range contains a given element, via sequential scan.
Definition: Core.hpp:247
AIToolbox::checkEqualSmall
bool checkEqualSmall(const double a, const double b)
This function checks if two doubles near [0,1] are reasonably equal.
Definition: Core.hpp:45
Types.hpp
AIToolbox::set_union_inplace
void set_union_inplace(std::vector< T > &lhs, const std::vector< T > &rhs)
This function performs an inplace union of two sorted sets.
Definition: Core.hpp:288
AIToolbox::ceil
unsigned ceil(unsigned x, unsigned y)
This function returns a fast ceiling between two unsigned ints.
Definition: Core.hpp:30
AIToolbox::max_element_unary
auto max_element_unary(It begin, const It end, F unary_converter)
This function is equivalent to std::max_element, but takes a unary function.
Definition: Core.hpp:316
AIToolbox::checkEqualGeneral
bool checkEqualGeneral(const double a, const double b)
This function checks if two doubles are reasonably equal.
Definition: Core.hpp:74