SolidUtils
Sort.hpp
Go to the documentation of this file.
1 
29 #ifndef SOLIDUTILS_SORT_HPP
30 #define SOLIDUTILS_SORT_HPP
31 
32 #include "VectorMath.hpp"
33 #include "Random.hpp"
34 
35 #include <memory>
36 #include <vector>
37 #include <algorithm>
38 
39 namespace sl
40 {
41 
42 class Sort
43 {
44  public:
56  template<typename K, typename I>
57  static std::unique_ptr<I[]> fixedKeys(
58  K const * const keys,
59  size_t const num)
60  {
61  static_assert(std::is_integral<K>::value, "Must by integral type.");
62  static_assert(std::is_integral<I>::value, "Must by integral type.");
63 
64  std::vector<size_t> counts(num+1,0);
65  counts.reserve(num);
66 
67  /* avoid having to do offsets in each iteration */
68  for (size_t i = 0; i < num; ++i) {
69  ++counts[keys[i]];
70  }
71 
72  sl::VectorMath::prefixSumExclusive(counts.data(), counts.size());
73 
74  std::unique_ptr<I[]> out(new I[num]);
75 
76  for (size_t i = 0; i < num; ++i) {
77  out[counts[keys[i]]++] = i;
78  }
79 
80  return out;
81  }
82 
94  template<typename K, typename I, typename URBG>
95  static std::unique_ptr<I[]> fixedKeysRandom(
96  K const * const keys,
97  size_t const num,
98  URBG&& rng)
99  {
100  static_assert(std::is_integral<K>::value, "Must by integral type.");
101  static_assert(std::is_integral<I>::value, "Must by integral type.");
102 
103  std::vector<size_t> counts(num+1,0);
104  counts.reserve(num);
105 
106  /* avoid having to do offsets in each iteration */
107  for (size_t i = 0; i < num; ++i) {
108  ++counts[keys[i]];
109  }
110 
111  sl::VectorMath::prefixSumExclusive(counts.data(), counts.size());
112 
113  std::unique_ptr<I[]> out(new I[num]);
114 
115  for (size_t i = 0; i < num; ++i) {
116  out[counts[keys[i]]++] = i;
117  }
118 
119  // randomize each bucket
120  size_t start = 0;
121  for (size_t i = 0; start < num; ++i) {
122  sl::Random::pseudoShuffle(out.get()+start, counts[i] - start, rng);
123  start = counts[i];
124  }
125 
126  return out;
127  }
128 
129 
130 };
131 
132 
133 }
134 
135 #endif
136 
Definition: Alloc.hpp:40
static std::unique_ptr< I[]> fixedKeys(K const *const keys, size_t const num)
Generate a permutation for a given set of keys. The range of the keys must be limited to [0...
Definition: Sort.hpp:57
The Random class.
static void pseudoShuffle(T *const data, size_t const num, URBG &&rng) noexcept
Re-order the elements in array in a randomly. This is less random than std::shuffle, but is significantly faster for large arrays.
Definition: Random.hpp:143
Definition: Sort.hpp:42
static std::unique_ptr< I[]> fixedKeysRandom(K const *const keys, size_t const num, URBG &&rng)
Generate a permutation for a given set of keys. The range of the keys must be limited to [0...
Definition: Sort.hpp:95
The VectorMath class.
static void prefixSumExclusive(T *const data, size_t const size) noexcept
Perform a prefix sum on an array.
Definition: VectorMath.hpp:105