15 #ifndef BELUGA_VIEWS_TAKE_WHILE_KLD_HPP
16 #define BELUGA_VIEWS_TAKE_WHILE_KLD_HPP
19 #include <unordered_set>
21 #include <range/v3/view/take.hpp>
22 #include <range/v3/view/take_while.hpp>
73 auto target_size = [two_epsilon = 2 * epsilon, z](std::size_t k) {
75 return std::numeric_limits<std::size_t>::max();
77 const double common = 2. /
static_cast<double>(9 * (k - 1));
78 const double base = 1. - common + std::sqrt(common) * z;
79 const double result = (
static_cast<double>(k - 1) / two_epsilon) * base * base * base;
80 return static_cast<std::size_t
>(std::ceil(
result));
83 return [=, count = 0ULL, buckets = std::unordered_set<std::size_t>{}](std::size_t hash)
mutable {
86 return count <= min || count <= target_size(buckets.size());
111 template <
class Range,
class Hasher, std::enable_if_t<ranges::range<Range>,
int> = 0>
119 static_assert(ranges::input_range<Range>);
121 auto proj = [&hasher]() {
122 if constexpr (std::is_invocable_r_v<std::size_t,
Hasher, ranges::range_value_t<Range>>) {
124 return std::move(hasher);
128 static_assert(is_particle_range_v<Range>);
129 static_assert(std::is_invocable_r_v<std::size_t,
Hasher,
beluga::state_t<ranges::range_value_t<Range>>>);
134 return ranges::views::all(std::forward<Range>(range)) |
136 ranges::views::take(max);
148 template <
class Hasher>
155 return ranges::make_view_closure(ranges::bind_back(
take_while_kld_fn{}, std::move(hasher), min, max, epsilon, z));