3 #ifndef FORPY_UTIL_SAMPLING_H_ 4 #define FORPY_UTIL_SAMPLING_H_ 6 #include <cereal/access.hpp> 7 #include <cereal/types/polymorphic.hpp> 11 #include <type_traits> 15 #include "../global.h" 16 #include "./serialization/basics.h" 30 static int64_t
ibinom(
const int &n,
int k) {
35 if (0 == k || n == k)
return 1LL;
36 if (k > n)
return 0LL;
38 if (k > (n - k)) k = n - k;
39 if (1 == k)
return static_cast<int64_t
>(n);
42 for (i = 1; i <= k; ++i) {
44 if (b < 0)
return -1LL;
71 dist = std::uniform_int_distribution<size_t>(0, max -
min);
87 "Tried to redraw without replacement " 88 "from a limited set where the num of remaining examples was 0.");
92 dist.param(std::uniform_int_distribution<size_t>::param_type(
101 stream <<
"forpy::SamplingWithoutReplacement[" <<
self.min
102 <<
" (inc):" << (
self.min +
self.indices.size() - 1) <<
" (inc), " 103 << (
self.
indices.size() -
self.index) <<
" available]";
115 friend class cereal::access;
116 template <
class Archive>
124 std::uniform_int_distribution<T>
dist;
155 template <
typename T>
157 std::mt19937 *random_engine,
158 bool return_sorted =
false) {
159 static_assert(std::is_integral<T>::value,
"T must be integral!");
161 if (num > max - min + 1)
163 std::vector<T> result(num);
164 if (num == max - min + 1) {
166 std::iota(result.begin(), result.end(), min);
168 std::geometric_distribution<T> dist;
169 if (num + 1 < max - min + 1) {
175 dist = std::geometric_distribution<T>(
static_cast<float>(num + 1) /
176 static_cast<float>(max - min + 1));
183 r = (max - min + 1 - i);
187 result[num - i - 1] = min;
190 result[num - i - 1] = min +=
191 std::min<T>(dist(*random_engine) + 1, r - 1);
196 if (!return_sorted) {
197 std::shuffle(result.begin(), result.end(), *random_engine);
202 #endif // FORPY_UTIL_SAMPLING_H_
SamplingWithoutReplacement()
T get_next()
Gets the next sample.
A lazy evaluation sampling without replacement.
bool operator==(const SamplingWithoutReplacement< T > &rhs) const
#define FASSERT(condition)
std::shared_ptr< std::mt19937 > random_engine
static std::vector< T > unique_indices(T num, T min, const T &max, std::mt19937 *random_engine, bool return_sorted=false)
Sampling without replacement.
void serialize(Archive &ar, const uint &)
SamplingWithoutReplacement(const T &min, const T &max, const std::shared_ptr< std::mt19937 > &random_engine)
static int64_t ibinom(const int &n, int k)
Integer binomial with overflow detection.
unsigned int uint
Convenience typedef for unsigned int.
friend std::ostream & operator<<(std::ostream &stream, const SamplingWithoutReplacement &self)
bool sample_available() const
Returns true if a sample can be drawn without raising an exception.
std::uniform_int_distribution< T > dist