vSMC  v3.0.0
Scalable Monte Carlo
u01_sequence.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/u01_sequence.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, 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_U01_SEQUENCE_HPP
33 #define VSMC_RNG_U01_SEQUENCE_HPP
34 
37 
38 #define VSMC_RUNTIME_ASSERT_RNG_U01_SEQUENCE(Method) \
39  VSMC_RUNTIME_ASSERT((n < N_ && (n == n_ || n == n_ + 1 || n_ == N_)), \
40  "**U01Sequence" #Method "::operator[]** INVALID INDEX")
41 
42 namespace vsmc
43 {
44 
45 namespace internal
46 {
47 
48 template <std::size_t K, typename RealType>
49 inline void u01_trans_sorted_impl(std::size_t n0, std::size_t n,
50  const RealType *u01, RealType *r, std::size_t N, RealType &lmax)
51 {
52  if (n0 == n)
53  return;
54 
56  std::size_t j = 0;
57  std::size_t m = N - n0;
58  log(n - n0, u01, r);
59  for (std::size_t i = n0; i != n; ++i, ++j, --m) {
60  lmax += r[j] / m;
61  s[j] = lmax;
62  }
63  exp(n - n0, s.data(), s.data());
64  sub(n - n0, static_cast<RealType>(1), s.data(), r);
65 }
66 
67 template <std::size_t K, typename RealType, typename RNGType>
68 inline void u01_rand_sorted_impl(RNGType &rng, std::size_t n0, std::size_t n,
69  RealType *r, std::size_t N, RealType &lmax)
70 {
71  if (n0 == n)
72  return;
73 
74  u01_distribution(rng, n - n0, r);
75  u01_trans_sorted_impl<K>(n0, n, r, r, N, lmax);
76 }
77 
78 template <typename RealType>
79 inline void u01_trans_stratified_impl(std::size_t n0, std::size_t n,
80  const RealType *u01, RealType *r, RealType delta)
81 {
82  if (n0 == n)
83  return;
84 
85  std::size_t j = 0;
86  for (std::size_t i = n0; i != n; ++i, ++j)
87  r[j] = u01[j] + static_cast<RealType>(i);
88  mul(n - n0, delta, r, r);
89 }
90 
91 template <typename RealType, typename RNGType>
93  RNGType &rng, std::size_t n0, std::size_t n, RealType *r, RealType delta)
94 {
95  if (n0 == n)
96  return;
97 
98  u01_distribution(rng, n - n0, r);
99  u01_trans_stratified_impl(n0, n, r, r, delta);
100 }
101 
102 template <typename RealType>
104  std::size_t n0, std::size_t n, RealType u, RealType *r, RealType delta)
105 {
106  if (n0 == n)
107  return;
108 
109  std::size_t j = 0;
110  for (std::size_t i = n0; i != n; ++i, ++j)
111  r[j] = static_cast<RealType>(i);
112  fma(n - n0, r, delta, u, r);
113 }
114 
115 } // namespace vsmc::internal
116 
120 template <typename RealType>
121 inline void u01_trans_sorted(std::size_t N, const RealType *u01, RealType *r)
122 {
123  static_assert(std::is_floating_point<RealType>::value,
124  "**u01_trans_sorted** USED WITH RealType OTHER THAN FLOATING POINT "
125  "TYPES");
126 
127  if (N == 0)
128  return;
129 
130  const std::size_t k = internal::BufferSize<RealType>::value;
131  if (N <= k) {
132  if (u01 != r)
133  std::copy_n(u01, N, r);
134  std::sort(r, r + N);
135  return;
136  }
137 
138  const std::size_t m = N / k;
139  std::size_t n0 = 0;
140  RealType lmax = 0;
141  for (std::size_t i = 0; i != m; ++i, n0 += k, u01 += k, r += k)
142  internal::u01_trans_sorted_impl<k>(n0, n0 + k, u01, r, N, lmax);
143  internal::u01_trans_sorted_impl<k>(n0, N, u01, r, N, lmax);
144 }
145 
149 template <typename RealType>
151  std::size_t N, const RealType *u01, RealType *r)
152 {
153  static_assert(std::is_floating_point<RealType>::value,
154  "**u01_trans_stratified** USED WITH RealType OTHER THAN FLOATING "
155  "POINT TYPES");
156 
157  if (N == 0)
158  return;
159 
160  const std::size_t k = internal::BufferSize<RealType>::value;
161  const std::size_t m = N / k;
162  std::size_t n0 = 0;
163  const RealType delta = 1 / static_cast<RealType>(N);
164  for (std::size_t i = 0; i != m; ++i, n0 += k, u01 += k, r += k)
165  internal::u01_trans_stratified_impl(n0, n0 + k, u01, r, delta);
166  internal::u01_trans_stratified_impl(n0, N, u01, r, delta);
167 }
168 
172 template <typename RealType>
174  std::size_t N, const RealType *u01, RealType *r)
175 {
176  static_assert(std::is_floating_point<RealType>::value,
177  "**u01_trans_systematic** USED WITH RealType OTHER THAN FLOATING "
178  "POINT TYPES");
179 
180  if (N == 0)
181  return;
182 
183  const std::size_t k = internal::BufferSize<RealType>::value;
184  const std::size_t m = N / k;
185  std::size_t n0 = 0;
186  const RealType delta = 1 / static_cast<RealType>(N);
187  const RealType u = u01[0] * delta;
188  for (std::size_t i = 0; i != m; ++i, n0 += k, r += k)
189  internal::u01_trans_systematic_impl(n0, n0 + k, u, r, delta);
190  internal::u01_trans_systematic_impl(n0, N, u, r, delta);
191 }
192 
195 template <typename RealType, typename RNGType>
196 inline void u01_rand_sorted(RNGType &rng, std::size_t N, RealType *r)
197 {
198  static_assert(std::is_floating_point<RealType>::value,
199  "**u01_rand_sorted** USED WITH RealType OTHER THAN FLOATING POINT "
200  "TYPES");
201 
202  if (N == 0)
203  return;
204 
205  const std::size_t k = internal::BufferSize<RealType>::value;
206  if (N <= k) {
207  u01_distribution(rng, N, r);
208  std::sort(r, r + N);
209  return;
210  }
211 
212  const std::size_t m = N / k;
213  std::size_t n0 = 0;
214  RealType lmax = 0;
215  for (std::size_t i = 0; i != m; ++i, n0 += k, r += k)
216  internal::u01_rand_sorted_impl<k>(rng, n0, n0 + k, r, N, lmax);
217  internal::u01_rand_sorted_impl<k>(rng, n0, N, r, N, lmax);
218 }
219 
222 template <typename RealType, typename RNGType>
223 inline void u01_rand_stratified(RNGType &rng, std::size_t N, RealType *r)
224 {
225  static_assert(std::is_floating_point<RealType>::value,
226  "**u01_rand_stratified** USED WITH RealType OTHER THAN FLOATING POINT "
227  "TYPES");
228 
229  const std::size_t k = internal::BufferSize<RealType>::value;
230  const std::size_t m = N / k;
231  std::size_t n0 = 0;
232  const RealType delta = 1 / static_cast<RealType>(N);
233  for (std::size_t i = 0; i != m; ++i, n0 += k, r += k)
234  internal::u01_rand_stratified_impl(rng, n0, n0 + k, r, delta);
235  internal::u01_rand_stratified_impl(rng, n0, N, r, delta);
236 }
237 
240 template <typename RealType, typename RNGType>
241 inline void u01_rand_systematic(RNGType &rng, std::size_t N, RealType *r)
242 {
243  static_assert(std::is_floating_point<RealType>::value,
244  "**u01_rand_systematic** USED WITH RealType OTHER THAN FLOATING POINT "
245  "TYPES");
246 
248  RealType u01 = ru01(rng);
249  u01_trans_systematic(N, &u01, r);
250 }
251 
255 {
256  public:
257  template <typename RealType>
258  void operator()(std::size_t N, const RealType *u01, RealType *r) const
259  {
260  u01_trans_sorted(N, u01, r);
261  }
262 
263  template <typename RealType, typename RNG>
264  void operator()(RNG &rng, std::size_t N, RealType *r) const
265  {
266  u01_rand_sorted(rng, N, r);
267  }
268 }; // U01SequenceSorted
269 
273 {
274  public:
275  template <typename RealType>
276  void operator()(std::size_t N, const RealType *u01, RealType *r) const
277  {
278  u01_trans_stratified(N, u01, r);
279  }
280 
281  template <typename RealType, typename RNG>
282  void operator()(RNG &rng, std::size_t N, RealType *r) const
283  {
284  u01_rand_stratified(rng, N, r);
285  }
286 }; // class U01SequenceStratified
287 
291 {
292  public:
293  template <typename RealType>
294  void operator()(std::size_t N, const RealType *u01, RealType *r) const
295  {
296  u01_trans_systematic(N, u01, r);
297  }
298 
299  template <typename RealType, typename RNG>
300  void operator()(RNG &rng, std::size_t N, RealType *r) const
301  {
302  u01_rand_systematic(rng, N, r);
303  }
304 }; // class U01SequenceSystematic
305 
306 } // namespace vsmc
307 
308 #endif // VSMC_RNG_U01_SEQUENCE_HPP
Definition: monitor.hpp:48
void mul(std::size_t n, const float *a, const float *b, float *y)
Definition: vmath.hpp:77
Stratified standard uniform numbers.
void operator()(std::size_t N, const RealType *u01, RealType *r) const
void operator()(RNG &rng, std::size_t N, RealType *r) const
void operator()(RNG &rng, std::size_t N, RealType *r) const
Systematic standard uniform numbers.
Counter based RNG engine.
Definition: counter.hpp:187
void u01_trans_systematic(std::size_t N, const RealType *u01, RealType *r)
Transform a single standard uniform random number to a systematic sequence.
void u01_distribution(RNGType &, std::size_t, RealType *)
Generate standard uniform random variates.
void u01_trans_systematic_impl(std::size_t n0, std::size_t n, RealType u, RealType *r, RealType delta)
void u01_trans_stratified_impl(std::size_t n0, std::size_t n, const RealType *u01, RealType *r, RealType delta)
void u01_trans_sorted(std::size_t N, const RealType *u01, RealType *r)
Tranform a sequence of standard uniform random numbers to sorted sequence.
RealType u01(UIntType u) noexcept
Convert uniform unsigned integers to floating points within [0, 1].
Definition: u01.hpp:213
void u01_rand_sorted(RNGType &rng, std::size_t N, RealType *r)
Generate sorted standard uniform numbers with cost.
void operator()(std::size_t N, const RealType *u01, RealType *r) const
void exp(std::size_t n, const float *a, float *y)
Definition: vmath.hpp:115
Sorted of standard uniform numbers.
void u01_rand_stratified(RNGType &rng, std::size_t N, RealType *r)
Generate stratified standard uniform numbers.
void sub(std::size_t n, const float *a, const float *b, float *y)
Definition: vmath.hpp:75
void fma(std::size_t n, const T *a, const T *b, const T *c, T *y)
For , compute .
Definition: vmath.hpp:361
void u01_rand_sorted_impl(RNGType &rng, std::size_t n0, std::size_t n, RealType *r, std::size_t N, RealType &lmax)
void u01_trans_stratified(std::size_t N, const RealType *u01, RealType *r)
Transform a sequence of standard uniform random numbers to a stratified sequence. ...
void u01_rand_systematic(RNGType &rng, std::size_t N, RealType *r)
Generate systematic standard uniform numbers.
void operator()(RNG &rng, std::size_t N, RealType *r) const
std::array with proper alignment
void u01_trans_sorted_impl(std::size_t n0, std::size_t n, const RealType *u01, RealType *r, std::size_t N, RealType &lmax)
void operator()(std::size_t N, const RealType *u01, RealType *r) const
void u01_rand_stratified_impl(RNGType &rng, std::size_t n0, std::size_t n, RealType *r, RealType delta)
void log(std::size_t n, const float *a, float *y)
Definition: vmath.hpp:117