vSMC
vSMC: Scalable Monte Carlo
uniform_bits_distribution.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/uniform_bits_distribution.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2015, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_RNG_UNIFORM_BITS_DISTRIBUTION_HPP
33 #define VSMC_RNG_UNIFORM_BITS_DISTRIBUTION_HPP
34 
36 
37 namespace vsmc
38 {
39 
40 namespace internal
41 {
42 
43 template <typename UIntType, int Bits>
45 {
46  public:
47  template <typename RNGType>
48  static UIntType eval(RNGType &rng)
49  {
50  return eval(rng,
51  std::integral_constant<bool, RNGMinBits<RNGType>::value == 0>(),
52  std::integral_constant<bool, RNGBits<RNGType>::value >= Bits>());
53  }
54 
55  private:
56  template <typename RNGType>
57  static UIntType eval(RNGType &rng, std::true_type, std::true_type)
58  {
59  return static_cast<UIntType>(rng());
60  }
61 
62  template <typename RNGType>
63  static UIntType eval(RNGType &rng, std::false_type, std::true_type)
64  {
65  return static_cast<UIntType>(rng() >> RNGMinBits<RNGType>::value);
66  }
67 
68  template <typename RNGType>
69  static UIntType eval(RNGType &rng, std::true_type, std::false_type)
70  {
71  return static_cast<UIntType>(
72  patch<0, RNGBits<RNGType>::value, RNGMinBits<RNGType>::value>(
73  rng, std::true_type()));
74  }
75 
76  template <typename RNGType>
77  static UIntType eval(RNGType &rng, std::false_type, std::false_type)
78  {
79  return eval(rng, std::true_type(), std::false_type());
80  }
81 
82  template <int, int, int, typename RNGType>
83  static UIntType patch(RNGType &, std::false_type)
84  {
85  return 0;
86  }
87 
88  template <int N, int B, int R, typename RNGType>
89  static UIntType patch(RNGType &rng, std::true_type)
90  {
91  return static_cast<UIntType>((rng() >> R) << (B * N)) +
92  patch<N + 1, B, R>(
93  rng, std::integral_constant<bool, (N * B + B) < Bits>());
94  }
95 }; // class UniformBits
96 
97 } // namespace vsmc::internal
98 
101 template <typename UIntType>
103 {
104  public:
105  using result_type = UIntType;
107 
109  {
110  public:
111  using result_type = UIntType;
113 
114  friend bool operator==(const param_type &, const param_type &)
115  {
116  return true;
117  }
118 
119  friend bool operator!=(const param_type &, const param_type &)
120  {
121  return false;
122  }
123 
124  template <typename CharT, typename Traits>
125  friend std::basic_ostream<CharT, Traits> &operator<<(
126  std::basic_ostream<CharT, Traits> &os, const param_type &)
127  {
128  return os;
129  }
130 
131  template <typename CharT, typename Traits>
132  friend std::basic_istream<CharT, Traits> &operator>>(
133  std::basic_istream<CharT, Traits> &is, param_type &)
134  {
135  return is;
136  }
137  }; // class param_type
138 
140  explicit UniformBitsDistribution(const param_type &) {}
141 
142  result_type min VSMC_MNE() const
143  {
144  return std::numeric_limits<result_type>::min VSMC_MNE();
145  }
146 
147  result_type max VSMC_MNE() const
148  {
149  return std::numeric_limits<result_type>::max VSMC_MNE();
150  }
151 
152  void reset() {}
153 
154  template <typename RNGType>
155  result_type operator()(RNGType &rng)
156  {
157  return internal::UniformBits<UIntType,
159  }
160 
161  template <typename RNGType>
162  result_type operator()(RNGType &rng, const param_type &)
163  {
164  return operator()(rng);
165  }
166 
167  template <typename RNGType>
168  void operator()(RNGType &rng, std::size_t n, result_type *r)
169  {
170  uniform_bits_distribution(rng, n, r);
171  }
172 
173  template <typename RNGType>
175  RNGType &rng, std::size_t n, result_type *r, const param_type &)
176  {
177  uniform_bits_distribution(rng, n, r);
178  }
179 
182  {
183  return true;
184  }
185 
188  {
189  return false;
190  }
191 
192  template <typename CharT, typename Traits>
193  friend std::basic_ostream<CharT, Traits> &operator<<(
194  std::basic_ostream<CharT, Traits> &os,
196  {
197  return os;
198  }
199 
200  template <typename CharT, typename Traits>
201  friend std::basic_istream<CharT, Traits> &operator>>(
202  std::basic_istream<CharT, Traits> &is,
204  {
205  return is;
206  }
207 }; // class UniformBitsDistribution
208 
209 namespace internal
210 {
211 
212 template <typename UIntType, typename RNGType, bool B1, bool B2>
213 inline void uniform_bits_distribution_impl(RNGType &rng, std::size_t n,
214  UIntType *r, std::false_type, std::integral_constant<bool, B1>,
215  std::integral_constant<bool, B2>)
216 {
217  for (std::size_t i = 0; i != n; ++i)
218  r[i] = UniformBits<UIntType, IntBits<UIntType>::value>::eval(rng);
219 }
220 
221 template <typename UIntType, typename RNGType>
222 inline void uniform_bits_distribution_impl(RNGType &rng, std::size_t n,
223  UIntType *r, std::true_type, std::true_type, std::true_type)
224 {
225  rng_rand(rng, n, reinterpret_cast<typename RNGType::result_type *>(r));
226 }
227 
228 template <typename UIntType, typename RNGType>
229 inline void uniform_bits_distribution_impl(RNGType &rng, std::size_t n,
230  UIntType *r, std::true_type, std::true_type, std::false_type)
231 {
232  const std::size_t k =
233  sizeof(typename RNGType::result_type) / sizeof(UIntType);
234  const std::size_t m = n / k;
235  const std::size_t l = n % k;
236  rng_rand(rng, m, reinterpret_cast<typename RNGType::result_type *>(r));
237  n -= m * k;
238  r += m * k;
239  for (std::size_t i = 0; i != l; ++i)
240  r[i] = UniformBits<UIntType, IntBits<UIntType>::value>::eval(rng);
241 }
242 
243 template <typename UIntType, typename RNGType>
244 inline void uniform_bits_distribution_impl(RNGType &rng, std::size_t n,
245  UIntType *r, std::true_type, std::false_type, std::true_type)
246 {
247  const std::size_t k =
248  sizeof(UIntType) / sizeof(typename RNGType::result_type);
249  const std::size_t m = n * k;
250  rng_rand(rng, m, reinterpret_cast<typename RNGType::result_type *>(r));
251 }
252 
253 template <typename UIntType, typename RNGType>
254 inline void uniform_bits_distribution_impl(RNGType &rng, std::size_t n,
255  UIntType *r, std::true_type, std::false_type, std::false_type)
256 {
257  for (std::size_t i = 0; i != n; ++i)
258  r[i] = UniformBits<UIntType, IntBits<UIntType>::value>::eval(rng);
259 }
260 
261 } // namespace vsmc::rng_type
262 
263 template <typename UIntType, typename RNGType>
264 inline void uniform_bits_distribution(RNGType &rng, std::size_t n, UIntType *r)
265 {
266  const int mbits = internal::RNGMinBits<RNGType>::value;
267  const int rbits = internal::RNGBits<RNGType>::value;
268  const int ubits = internal::IntBits<UIntType>::value;
270  std::integral_constant<bool, mbits == 0>(),
271  std::integral_constant < bool,
272  rbits >= ubits && rbits % ubits == 0 > (),
273  std::integral_constant < bool,
274  ubits >= rbits && ubits % rbits == 0 > ());
275 }
276 
277 template <typename UIntType, typename RNGType>
278 inline void rng_rand(RNGType &rng, UniformBitsDistribution<UIntType> &dist,
279  std::size_t n, UIntType *r)
280 {
281  dist(rng, n, r);
282 }
283 
284 } // namespace vsmc
285 
286 #endif // VSMC_RNG_UNIFORM_BITS_DISTRIBUTION_HPP
Definition: monitor.hpp:49
result_type operator()(RNGType &rng, const param_type &)
void rng_rand(RNGType &rng, BernoulliDistribution< IntType > &dist, std::size_t n, IntType *r)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, param_type &)
#define VSMC_MNE
Definition: defines.hpp:38
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const param_type &)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const UniformBitsDistribution< UIntType > &)
static UIntType eval(RNGType &rng)
void uniform_bits_distribution_impl(RNGType &rng, std::size_t n, UIntType *r, std::false_type, std::integral_constant< bool, B1 >, std::integral_constant< bool, B2 >)
friend bool operator!=(const UniformBitsDistribution< UIntType > &, const UniformBitsDistribution< UIntType > &)
friend bool operator==(const UniformBitsDistribution< UIntType > &, const UniformBitsDistribution< UIntType > &)
friend bool operator!=(const param_type &, const param_type &)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, UniformBitsDistribution< UIntType > &)
void uniform_bits_distribution(RNGType &, std::size_t, UIntType *)
void operator()(RNGType &rng, std::size_t n, result_type *r, const param_type &)
Uniform bits distribution.
Definition: common.hpp:461
void operator()(RNGType &rng, std::size_t n, result_type *r)
friend bool operator==(const param_type &, const param_type &)