take_while_kld.hpp
Go to the documentation of this file.
1 // Copyright 2023-2024 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef BELUGA_VIEWS_TAKE_WHILE_KLD_HPP
16 #define BELUGA_VIEWS_TAKE_WHILE_KLD_HPP
17 
18 #include <cmath>
19 #include <unordered_set>
20 
21 #include <range/v3/view/take.hpp>
22 #include <range/v3/view/take_while.hpp>
23 
25 
31 namespace beluga {
32 
33 namespace detail {
34 
36 constexpr double kDefaultKldZ = 3.;
37 
38 } // namespace detail
39 
41 
72 inline auto kld_condition(std::size_t min, double epsilon, double z = beluga::detail::kDefaultKldZ) {
73  auto target_size = [two_epsilon = 2 * epsilon, z](std::size_t k) {
74  if (k <= 2U) {
75  return std::numeric_limits<std::size_t>::max();
76  }
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));
81  };
82 
83  return [=, count = 0ULL, buckets = std::unordered_set<std::size_t>{}](std::size_t hash) mutable {
84  count++;
85  buckets.insert(hash);
86  return count <= min || count <= target_size(buckets.size());
87  };
88 }
89 
90 namespace views {
91 
92 namespace detail {
93 
97 
111  template <class Range, class Hasher, std::enable_if_t<ranges::range<Range>, int> = 0>
112  constexpr auto operator()(
113  Range&& range,
114  Hasher hasher,
115  std::size_t min,
116  std::size_t max,
117  double epsilon,
118  double z = beluga::detail::kDefaultKldZ) const {
119  static_assert(ranges::input_range<Range>);
120 
121  auto proj = [&hasher]() {
122  if constexpr (std::is_invocable_r_v<std::size_t, Hasher, ranges::range_value_t<Range>>) {
123  // Try to invoke the hasher with the range values by default.
124  return std::move(hasher);
125  } else {
126  // If the above is not possible, assume this is a particle range and invoke
127  // the hasher with the state element of each particle.
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>>>);
130  return ranges::compose(std::move(hasher), beluga::state);
131  }
132  }();
133 
134  return ranges::views::all(std::forward<Range>(range)) | //
135  ranges::views::take_while(beluga::kld_condition(min, epsilon, z), std::move(proj)) | //
136  ranges::views::take(max);
137  }
138 
140 
148  template <class Hasher>
149  constexpr auto operator()(
150  Hasher hasher,
151  std::size_t min,
152  std::size_t max,
153  double epsilon,
154  double z = beluga::detail::kDefaultKldZ) const {
155  return ranges::make_view_closure(ranges::bind_back(take_while_kld_fn{}, std::move(hasher), min, max, epsilon, z));
156  }
157 };
158 
159 } // namespace detail
160 
163 
171 
172 } // namespace views
173 
174 } // namespace beluga
175 
176 #endif
result
result[0]
beluga::kld_condition
auto kld_condition(std::size_t min, double epsilon, double z=beluga::detail::kDefaultKldZ)
Returns a callable object that verifies if the KLD condition is being satisfied.
Definition: take_while_kld.hpp:72
beluga::state
constexpr state_detail::state_fn state
Customization point object for accessing the state of a particle.
Definition: primitives.hpp:163
beluga::views::detail::take_while_kld_fn::operator()
constexpr auto operator()(Hasher hasher, std::size_t min, std::size_t max, double epsilon, double z=beluga::detail::kDefaultKldZ) const
Overload that returns a view closure to compose with other views.
Definition: take_while_kld.hpp:149
beluga::views::detail::take_while_kld_fn
Implementation detail for a take_while_kld range adaptor object.
Definition: take_while_kld.hpp:95
particle_traits.hpp
Implementation of traits for particle types, see the Particle named requirements.
beluga::detail::kDefaultKldZ
constexpr double kDefaultKldZ
Default upper standard normal quantile, P = 0.999.
Definition: take_while_kld.hpp:36
beluga::views::take_while_kld
constexpr detail::take_while_kld_fn take_while_kld
Definition: take_while_kld.hpp:170
beluga::state_t
typename particle_traits< T >::state_type state_t
Type trait that returns the state type given a particle type.
Definition: particle_traits.hpp:40
beluga::views::detail::take_while_kld_fn::operator()
constexpr auto operator()(Range &&range, Hasher hasher, std::size_t min, std::size_t max, double epsilon, double z=beluga::detail::kDefaultKldZ) const
Overload that implements the take_while_kld algorithm.
Definition: take_while_kld.hpp:112
proj
def proj(v)
beluga::Hasher
Definition: test_sparse_value_grid.cpp:37
beluga
The main Beluga namespace.
Definition: 3d_embedding.hpp:21


beluga
Author(s):
autogenerated on Tue Jul 16 2024 02:59:53