MCKL
Monte Carlo Kernel Library
resample.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/algorithm/resample.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, 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 MCKL_ALGORITHM_RESAMPLE_HPP
33 #define MCKL_ALGORITHM_RESAMPLE_HPP
34 
35 #include <mckl/internal/common.hpp>
36 #include <mckl/core/particle.hpp>
38 
39 namespace mckl {
40 
43 enum class ResampleScheme {
44  Multinomial,
45  Stratified,
46  Systematic,
47  Residual,
50 }; // enum ResampleScheme
51 
58 constexpr ResampleScheme ResidualSystematic =
60 
61 namespace internal {
62 
63 template <std::size_t K, typename RealType>
64 inline void u01_trans_sorted_impl(std::size_t n0, std::size_t n,
65  const RealType *u01, RealType *r, std::size_t N, RealType &lmax)
66 {
67  if (n0 == n) {
68  return;
69  }
70 
71  alignas(MCKL_ALIGNMENT) std::array<RealType, K> s;
72  std::size_t j = 0;
73  std::size_t m = N - n0;
74  log(n - n0, u01, r);
75  for (std::size_t i = n0; i != n; ++i, ++j, --m) {
76  lmax += r[j] / m;
77  s[j] = lmax;
78  }
79  exp(n - n0, s.data(), s.data());
80  sub(n - n0, const_one<RealType>(), s.data(), r);
81 }
82 
83 template <std::size_t K, typename RealType, typename RNGType>
84 inline void u01_rand_sorted_impl(RNGType &rng, std::size_t n0, std::size_t n,
85  RealType *r, std::size_t N, RealType &lmax)
86 {
87  if (n0 == n) {
88  return;
89  }
90 
91  u01_distribution(rng, n - n0, r);
92  u01_trans_sorted_impl<K>(n0, n, r, r, N, lmax);
93 }
94 
95 template <typename RealType>
96 inline void u01_trans_stratified_impl(std::size_t n0, std::size_t n,
97  const RealType *u01, RealType *r, RealType delta)
98 {
99  if (n0 == n) {
100  return;
101  }
102 
103  std::size_t j = 0;
104  for (std::size_t i = n0; i != n; ++i, ++j) {
105  r[j] = u01[j] + static_cast<RealType>(i);
106  }
107  mul(n - n0, delta, r, r);
108 }
109 
110 template <typename RealType, typename RNGType>
112  RNGType &rng, std::size_t n0, std::size_t n, RealType *r, RealType delta)
113 {
114  if (n0 == n) {
115  return;
116  }
117 
118  u01_distribution(rng, n - n0, r);
119  u01_trans_stratified_impl(n0, n, r, r, delta);
120 }
121 
122 template <typename RealType>
124  std::size_t n0, std::size_t n, RealType u, RealType *r, RealType delta)
125 {
126  if (n0 == n) {
127  return;
128  }
129 
130  std::size_t j = 0;
131  for (std::size_t i = n0; i != n; ++i, ++j) {
132  r[j] = static_cast<RealType>(i);
133  }
134  muladd(n - n0, r, delta, u, r);
135 }
136 
137 } // namespace internal
138 
142 template <typename RealType>
143 inline void u01_trans_sorted(std::size_t N, const RealType *u01, RealType *r)
144 {
145  static_assert(std::is_floating_point<RealType>::value,
146  "**u01_trans_sorted** used with RealType other than floating point "
147  "types");
148 
149  if (N == 0) {
150  return;
151  }
152 
153  const std::size_t k = internal::BufferSize<RealType>::value;
154  const std::size_t m = N / k;
155  std::size_t n0 = 0;
156  RealType lmax = 0;
157  for (std::size_t i = 0; i != m; ++i, n0 += k, u01 += k, r += k) {
158  internal::u01_trans_sorted_impl<k>(n0, n0 + k, u01, r, N, lmax);
159  }
160  internal::u01_trans_sorted_impl<k>(n0, N, u01, r, N, lmax);
161 }
162 
166 template <typename RealType>
168  std::size_t N, const RealType *u01, RealType *r)
169 {
170  static_assert(std::is_floating_point<RealType>::value,
171  "**u01_trans_stratified** used with RealType other than floating "
172  "point types");
173 
174  if (N == 0) {
175  return;
176  }
177 
178  const std::size_t k = internal::BufferSize<RealType>::value;
179  const std::size_t m = N / k;
180  std::size_t n0 = 0;
181  const RealType delta = 1 / static_cast<RealType>(N);
182  for (std::size_t i = 0; i != m; ++i, n0 += k, u01 += k, r += k) {
183  internal::u01_trans_stratified_impl(n0, n0 + k, u01, r, delta);
184  }
185  internal::u01_trans_stratified_impl(n0, N, u01, r, delta);
186 }
187 
191 template <typename RealType>
193  std::size_t N, const RealType *u01, RealType *r)
194 {
195  static_assert(std::is_floating_point<RealType>::value,
196  "**u01_trans_systematic** used with RealType other than floating "
197  "point types");
198 
199  if (N == 0) {
200  return;
201  }
202 
203  const std::size_t k = internal::BufferSize<RealType>::value;
204  const std::size_t m = N / k;
205  std::size_t n0 = 0;
206  const RealType delta = 1 / static_cast<RealType>(N);
207  const RealType u = u01[0] * delta;
208  for (std::size_t i = 0; i != m; ++i, n0 += k, r += k) {
209  internal::u01_trans_systematic_impl(n0, n0 + k, u, r, delta);
210  }
211  internal::u01_trans_systematic_impl(n0, N, u, r, delta);
212 }
213 
216 template <typename RealType, typename RNGType>
217 inline void u01_rand_sorted(RNGType &rng, std::size_t N, RealType *r)
218 {
219  static_assert(std::is_floating_point<RealType>::value,
220  "**u01_rand_sorted** used with RealType other than floating point "
221  "types");
222 
223  if (N == 0) {
224  return;
225  }
226 
227  const std::size_t k = internal::BufferSize<RealType>::value;
228  const std::size_t m = N / k;
229  std::size_t n0 = 0;
230  RealType lmax = 0;
231  for (std::size_t i = 0; i != m; ++i, n0 += k, r += k) {
232  internal::u01_rand_sorted_impl<k>(rng, n0, n0 + k, r, N, lmax);
233  }
234  internal::u01_rand_sorted_impl<k>(rng, n0, N, r, N, lmax);
235 }
236 
239 template <typename RealType, typename RNGType>
240 inline void u01_rand_stratified(RNGType &rng, std::size_t N, RealType *r)
241 {
242  static_assert(std::is_floating_point<RealType>::value,
243  "**u01_rand_stratified** used with RealType other than floating point "
244  "types");
245 
246  const std::size_t k = internal::BufferSize<RealType>::value;
247  const std::size_t m = N / k;
248  std::size_t n0 = 0;
249  const RealType delta = 1 / static_cast<RealType>(N);
250  for (std::size_t i = 0; i != m; ++i, n0 += k, r += k) {
251  internal::u01_rand_stratified_impl(rng, n0, n0 + k, r, delta);
252  }
253  internal::u01_rand_stratified_impl(rng, n0, N, r, delta);
254 }
255 
258 template <typename RealType, typename RNGType>
259 inline void u01_rand_systematic(RNGType &rng, std::size_t N, RealType *r)
260 {
261  static_assert(std::is_floating_point<RealType>::value,
262  "**u01_rand_systematic** used with RealType other than floating point "
263  "types");
264 
266  RealType u01 = ru01(rng);
267  u01_trans_systematic(N, &u01, r);
268 }
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_sorted(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_sorted(rng, N, r);
285  }
286 }; // class U01SequenceSorted
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_stratified(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_stratified(rng, N, r);
303  }
304 }; // class U01SequenceStratified
305 
309 {
310  public:
311  template <typename RealType>
312  void operator()(std::size_t N, const RealType *u01, RealType *r) const
313  {
314  u01_trans_systematic(N, u01, r);
315  }
316 
317  template <typename RealType, typename RNG>
318  void operator()(RNG &rng, std::size_t N, RealType *r) const
319  {
320  u01_rand_systematic(rng, N, r);
321  }
322 }; // class U01SequenceSystematic
323 
333 template <typename InputIter, typename OutputIterR, typename OutputIterI>
334 inline std::size_t resample_trans_residual(std::size_t N, std::size_t M,
335  InputIter weight, OutputIterR resid, OutputIterI integ)
336 {
337  using resid_type = typename std::iterator_traits<OutputIterR>::value_type;
338  using integ_type = typename std::iterator_traits<OutputIterI>::value_type;
339 
340  static_assert(std::is_floating_point<resid_type>::value,
341  "**resample_trans_residual** used resid other than floating point "
342  "types");
343 
344  resid_type sum_resid = 0;
345  integ_type sum_integ = 0;
346  OutputIterR resid_i = resid;
347  OutputIterI integ_i = integ;
348  const resid_type coeff = static_cast<resid_type>(M);
349  for (std::size_t i = 0; i != N; ++i, ++weight, ++resid_i, ++integ_i) {
350  const resid_type w = coeff * static_cast<resid_type>(*weight);
351  resid_type integral;
352  *resid_i = std::modf(w, &integral);
353  *integ_i = static_cast<integ_type>(integral);
354  sum_resid += *resid_i;
355  sum_integ += *integ_i;
356  }
357 
358  const resid_type mul_resid = 1 / sum_resid;
359  for (std::size_t i = 0; i != N; ++i, ++resid) {
360  *resid *= mul_resid;
361  }
362 
363  return M - static_cast<std::size_t>(sum_integ);
364 }
365 
374 template <typename InputIter, typename OutputIter, typename U01SeqType>
375 inline OutputIter resample_trans_u01_rep(std::size_t N, std::size_t M,
376  InputIter weight, U01SeqType &&u01seq, OutputIter replication)
377 {
378  using real_type = typename std::iterator_traits<InputIter>::value_type;
379  using rep_type = typename std::iterator_traits<OutputIter>::value_type;
380 
381  if (N == 0) {
382  return replication;
383  }
384 
385  if (N == 1) {
386  *replication++ = static_cast<rep_type>(M);
387  return replication;
388  }
389 
390  OutputIter rep = std::fill_n(replication, N, const_zero<rep_type>());
391  if (M == 0) {
392  return rep;
393  }
394 
395  real_type accw = 0;
396  std::size_t j = 0;
397  for (std::size_t i = 0; i != N - 1; ++i, ++weight, ++replication) {
398  accw += *weight;
399  while (j != M && static_cast<real_type>(u01seq[j]) < accw) {
400  *replication += 1;
401  ++j;
402  }
403  }
404  *replication++ = static_cast<rep_type>(M - j);
405 
406  return replication;
407 }
408 
416 template <typename InputIter, typename OutputIter>
417 inline OutputIter resample_trans_rep_index(
418  std::size_t N, std::size_t M, InputIter replication, OutputIter index)
419 {
420  using rep_type = typename std::iterator_traits<InputIter>::value_type;
421  using idx_type = typename std::iterator_traits<OutputIter>::value_type;
422 
423  if (N == 0 || M == 0) {
424  return index;
425  }
426 
427  const std::size_t K = std::min(N, M);
428  rep_type time = 0;
429  std::size_t src = 0;
430  InputIter rep = replication;
431 
432  auto seek = [N, K, &time, &src, &rep]() {
433  if (src < K && *rep < time + 2) {
434  time = 0;
435  do {
436  ++src;
437  ++rep;
438  } while (src < K && *rep < time + 2);
439  }
440  if (src >= K && *rep < time + 1) {
441  time = 0;
442  do {
443  ++src;
444  ++rep;
445  } while (src < N && *rep < time + 1);
446  }
447  };
448 
449  for (std::size_t dst = 0; dst != K; ++dst, ++replication, ++index) {
450  if (*replication > 0) {
451  *index = static_cast<idx_type>(dst);
452  } else {
453  seek();
454  *index = static_cast<idx_type>(src);
455  ++time;
456  }
457  }
458 
459  for (std::size_t dst = K; dst < M; ++dst, ++index) {
460  seek();
461  *index = static_cast<idx_type>(src);
462  ++time;
463  }
464 
465  return index;
466 }
467 
470 template <typename T>
472 {
473  public:
474  using eval_type = std::function<void(std::size_t, std::size_t,
475  typename Particle<T>::rng_type &, const double *,
477 
478  ResampleEval() = default;
479 
484  explicit ResampleEval(const eval_type &eval) : eval_(eval) {}
485 
487  template <typename Eval>
488  void selection(Eval &&eval)
489  {
490  eval_ = std::forward<Eval>(eval);
491  }
492 
494  void operator()(std::size_t, Particle<T> &particle) const
495  {
496  runtime_assert(static_cast<bool>(eval_),
497  "**ResampleEval::operator()** invalid evaluation object");
498 
499  using size_type = typename Particle<T>::size_type;
500 
501  const std::size_t N = static_cast<std::size_t>(particle.size());
502  Vector<size_type> rep(N);
503  Vector<size_type> idx(N);
504  eval_(N, N, particle.rng(), particle.weight().data(), rep.data());
505  resample_trans_rep_index(N, N, rep.data(), idx.data());
506  particle.select(particle.size(), idx.data());
507  }
508 
509  private:
510  eval_type eval_;
511 }; // class ResampleEval
512 
515 template <typename U01SeqType, bool Residual>
517 {
518  public:
526  template <typename RNGType, typename InputIter, typename OutputIter>
527  void operator()(std::size_t N, std::size_t M, RNGType &rng,
528  InputIter weight, OutputIter replication) const
529  {
530  eval(N, M, rng, weight, replication,
531  std::integral_constant<bool, Residual>());
532  }
533 
534  private:
535  U01SeqType u01seq_;
536 
537  template <typename RNGType, typename InputIter, typename OutputIter>
538  void eval(std::size_t N, std::size_t M, RNGType &rng, InputIter weight,
539  OutputIter replication, std::false_type) const
540  {
541  using real_type = typename std::iterator_traits<InputIter>::value_type;
542 
544  u01seq_(rng, M, u01.data());
545  resample_trans_u01_rep(N, M, weight, u01.data(), replication);
546  }
547 
548  template <typename RNGType, typename InputIter, typename OutputIter>
549  void eval(std::size_t N, std::size_t M, RNGType &rng, InputIter weight,
550  OutputIter replication, std::true_type) const
551  {
552  using real_type = typename std::iterator_traits<InputIter>::value_type;
553  using rep_type = typename std::iterator_traits<OutputIter>::value_type;
554 
555  Vector<real_type> resid(N);
556  Vector<rep_type> integ(N);
557  std::size_t R =
558  resample_trans_residual(N, M, weight, resid.data(), integ.data());
559 
561  u01seq_(rng, R, u01.data());
562  resample_trans_u01_rep(N, R, resid.data(), u01.data(), replication);
563  for (std::size_t i = 0; i != N; ++i, ++replication) {
564  *replication += integ[i];
565  }
566  }
567 }; // class ResampleAlgorithm
568 
572 
576 
580 
584 
589 
594 
597 template <typename IntType = std::size_t>
599 {
600  public:
601  using index_type = IntType;
602 
603  ResampleIndex() : num_iter_(0) {}
604 
606  std::size_t num_iter() const { return num_iter_; }
607 
609  std::size_t size() const
610  {
611  if (index_.size() == 0) {
612  return 0;
613  }
614  return index_.back().size();
615  }
616 
618  std::size_t size(std::size_t iter) const
619  {
620  if (iter >= index_.size()) {
621  return 0;
622  }
623  return index_[iter].size();
624  }
625 
627  void reset() { num_iter_ = 0; }
628 
630  void clear() { index_.clear(); }
631 
633  void push_back(std::size_t N)
634  {
635  ++num_iter_;
636  resize_identity(N);
637  if (index_.size() < num_iter_) {
638  index_.push_back(identity_);
639  } else {
640  index_[num_iter_ - 1] = identity_;
641  }
642  }
643 
645  template <typename InputIter>
646  void push_back(std::size_t N, InputIter first)
647  {
648  ++num_iter_;
649  if (index_.size() < num_iter_) {
650  index_.emplace_back(N);
651  } else {
652  index_[num_iter_ - 1].resize(N);
653  }
654  std::copy_n(first, N, index_[num_iter_ - 1].begin());
655  }
656 
657  index_type index(std::size_t id) const
658  {
659  return index(id, num_iter_ - 1, 0);
660  }
661 
662  index_type index(std::size_t id, std::size_t iter_back) const
663  {
664  return index(id, iter_back, 0);
665  }
666 
669  std::size_t id, std::size_t iter_back, std::size_t iter) const
670  {
671  runtime_assert(iter <= iter_back && iter_back < num_iter(),
672  "**ResampleIndex::index** iteration numbers out of range");
673 
674  index_type idx = index_.back()[id];
675  while (iter_back > iter) {
676  --iter_back;
677  idx = index_[iter_back][idx];
678  }
679 
680  return idx;
681  }
682 
683  std::size_t index_matrix_nrow() const
684  {
685  return index_matrix_nrow(num_iter_ - 1);
686  }
687 
688  std::size_t index_matrix_nrow(std::size_t iter_back) const
689  {
690  runtime_assert(iter_back < num_iter(),
691  "**ResampleIndex::index_matrix_nrow** iteration numbers out of "
692  "range");
693 
694  return index_[iter_back].size();
695  }
696 
697  std::size_t index_matrix_ncol() const
698  {
699  return index_matrix_ncol(num_iter_ - 1, 0);
700  }
701 
702  std::size_t index_matrix_ncol(std::size_t iter_back) const
703  {
704  return index_matrix_ncol(iter_back, 0);
705  }
706 
707  std::size_t index_matrix_ncol(
708  std::size_t iter_back, std::size_t iter) const
709  {
710  runtime_assert(iter <= iter_back && iter_back < num_iter(),
711  "**ResampleIndex::index_matrix_ncol** iteration numbers out of "
712  "range");
713 
714  return iter_back - iter + 1;
715  }
716 
718  {
719  return index_matrix(layout, num_iter_ - 1, 0);
720  }
721 
723  MatrixLayout layout, std::size_t iter_back) const
724  {
725  return index_matrix(layout, iter_back, 0);
726  }
727 
730  MatrixLayout layout, std::size_t iter_back, std::size_t iter) const
731  {
732  runtime_assert(iter <= iter_back && iter_back < num_iter(),
733  "**ResampleIndex::index_matrix** iteration numbers out of range");
734 
735  Vector<index_type> idxmat(
736  index_matrix_nrow(iter_back) * index_matrix_ncol(iter_back, iter));
737  read_index_matrix(layout, idxmat.begin(), iter_back, iter);
738 
739  return idxmat;
740  }
741 
742  template <typename RandomIter>
743  RandomIter read_index_matrix(MatrixLayout layout, RandomIter first) const
744  {
745  return read_index_matrix(layout, first, num_iter_ - 1, 0);
746  }
747 
748  template <typename RandomIter>
749  RandomIter read_index_matrix(
750  MatrixLayout layout, RandomIter first, std::size_t iter_back) const
751  {
752  return read_index_matrix(layout, first, iter_back, 0);
753  }
754 
764  template <typename RandomIter>
765  RandomIter read_index_matrix(MatrixLayout layout, RandomIter first,
766  std::size_t iter_back, std::size_t iter) const
767  {
768  runtime_assert(iter <= iter_back && iter_back < num_iter(),
769  "**ResampleIndex::read_index_matrix** iteration numbers out of "
770  "range");
771 
772  using difference_type =
773  typename std::iterator_traits<RandomIter>::difference_type;
774  const std::size_t N = index_matrix_nrow(iter_back);
775  const std::size_t R = index_matrix_ncol(iter_back, iter);
776 
777  if (layout == RowMajor) {
778  RandomIter back = first + static_cast<difference_type>(R - 1);
779  const index_type *idx = index_[iter_back].data();
780  for (std::size_t i = 0; i != N; ++i) {
781  back[static_cast<difference_type>(i * R)] = idx[i];
782  }
783  for (std::size_t r = 1; r != R; ++r) {
784  const std::size_t j = iter_back - r;
785  RandomIter last = back;
786  --back;
787  idx = index_[j].data();
788  for (std::size_t i = 0; i != N; ++i) {
789  back[static_cast<difference_type>(i * R)] =
790  idx[static_cast<std::size_t>(
791  last[static_cast<difference_type>(i * R)])];
792  }
793  }
794  }
795 
796  if (layout == ColMajor) {
797  RandomIter back =
798  first + static_cast<difference_type>(N * (R - 1));
799  const index_type *idx = index_[iter_back].data();
800  std::copy_n(idx, N, back);
801  for (std::size_t r = 1; r != R; ++r) {
802  const std::size_t j = iter_back - r;
803  RandomIter last = back;
804  back -= static_cast<difference_type>(N);
805  idx = index_[j].data();
806  for (std::size_t i = 0; i != N; ++i) {
807  back[static_cast<difference_type>(i)] =
808  idx[static_cast<std::size_t>(
809  last[static_cast<difference_type>(i)])];
810  }
811  }
812  }
813 
814  return first + static_cast<difference_type>(N * R);
815  }
816 
817  private:
818  std::size_t num_iter_;
819  Vector<index_type> identity_;
821 
822  void resize_identity(std::size_t N)
823  {
824  std::size_t n = identity_.size();
825  identity_.resize(N);
826  if (n < N) {
827  for (std::size_t i = n; i != N; ++i) {
828  identity_[i] = static_cast<index_type>(i);
829  }
830  }
831  }
832 }; // class ResampleIndex
833 
834 } // namespace mckl
835 
836 #endif // MCKL_ALGORITHM_RESAMPLE_HPP
Counter based RNG engine.
Definition: counter.hpp:62
void mul(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:124
void operator()(RNG &rng, std::size_t N, RealType *r) const
Definition: resample.hpp:282
std::size_t index_matrix_ncol(std::size_t iter_back) const
Definition: resample.hpp:702
Residual resampling.
void operator()(std::size_t N, const RealType *u01, RealType *r) const
Definition: resample.hpp:276
Stratified resampling on residuals.
void u01_trans_systematic(std::size_t N, const RealType *u01, RealType *r)
Transform a single standard uniform random number to a systematic sequence.
Definition: resample.hpp:192
void select(size_type n, InputIter index)
Resize by selecting according to user supplied index vector.
Definition: particle.hpp:325
index_type index(std::size_t id, std::size_t iter_back, std::size_t iter) const
Get the index given the particle ID and iteration number.
Definition: resample.hpp:668
void operator()(std::size_t N, const RealType *u01, RealType *r) const
Definition: resample.hpp:312
RandomIter read_index_matrix(MatrixLayout layout, RandomIter first) const
Definition: resample.hpp:743
std::size_t index_matrix_ncol(std::size_t iter_back, std::size_t iter) const
Definition: resample.hpp:707
void clear()
Release memory.
Definition: resample.hpp:630
Stratified resampling.
RandomIter read_index_matrix(MatrixLayout layout, RandomIter first, std::size_t iter_back, std::size_t iter) const
Read the resampling index matrix into an random access iterator.
Definition: resample.hpp:765
Multinomial resampling.
std::size_t size(std::size_t iter) const
The sample size of a given iteration.
Definition: resample.hpp:618
void u01_trans_systematic_impl(std::size_t n0, std::size_t n, RealType u, RealType *r, RealType delta)
Definition: resample.hpp:123
Vector< index_type > index_matrix(MatrixLayout layout) const
Definition: resample.hpp:717
std::size_t num_iter() const
Number of iterations recorded.
Definition: resample.hpp:606
OutputIter resample_trans_rep_index(std::size_t N, std::size_t M, InputIter replication, OutputIter index)
Transform replication numbers into parent indices.
Definition: resample.hpp:417
void u01_rand_stratified_impl(RNGType &rng, std::size_t n0, std::size_t n, RealType *r, RealType delta)
Definition: resample.hpp:111
Sorted of standard uniform numbers.
Definition: resample.hpp:272
ResampleScheme
Resampling schemes.
Definition: resample.hpp:43
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Definition: memory.hpp:435
void operator()(std::size_t, Particle< T > &particle) const
Resample a particle collection.
Definition: resample.hpp:494
void log(std::size_t n, const float *a, float *y)
Definition: vmf.hpp:226
rng_type & rng(size_type i)
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:352
T muladd(T a, T b, T c)
Definition: vmf.hpp:673
RandomIter read_index_matrix(MatrixLayout layout, RandomIter first, std::size_t iter_back) const
Definition: resample.hpp:749
Systematic standard uniform numbers.
Definition: resample.hpp:308
void push_back(std::size_t N)
Append an identity resampling index.
Definition: resample.hpp:633
RealType u01(UIntType u)
Convert uniform unsigned integers to floating points within [0, 1].
Definition: u01.hpp:88
std::function< void(std::size_t, std::size_t, typename Particle< T >::rng_type &, const double *, typename Particle< T >::size_type *)> eval_type
Definition: resample.hpp:476
void u01_trans_sorted(std::size_t N, const RealType *u01, RealType *r)
Tranform a sequence of standard uniform random numbers to sorted sequence.
Definition: resample.hpp:143
Stratified standard uniform numbers.
Definition: resample.hpp:290
Record and trace resampling index.
Definition: resample.hpp:598
index_type index(std::size_t id, std::size_t iter_back) const
Definition: resample.hpp:662
std::size_t index_matrix_nrow(std::size_t iter_back) const
Definition: resample.hpp:688
Systematic resampling on residuals.
void u01_trans_sorted_impl(std::size_t n0, std::size_t n, const RealType *u01, RealType *r, std::size_t N, RealType &lmax)
Definition: resample.hpp:64
void sub(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:121
weight_type & weight()
Read and write access to the weight collection object.
Definition: particle.hpp:340
Systematic resampling.
void u01_rand_sorted(RNGType &rng, std::size_t N, RealType *r)
Generate sorted standard uniform numbers with cost.
Definition: resample.hpp:217
Vector< index_type > index_matrix(MatrixLayout layout, std::size_t iter_back) const
Definition: resample.hpp:722
typename rng_set_type::rng_type rng_type
Definition: particle.hpp:286
void u01_rand_stratified(RNGType &rng, std::size_t N, RealType *r)
Generate stratified standard uniform numbers.
Definition: resample.hpp:240
void modf(std::size_t n, const float *a, float *y, float *z)
Definition: vmf.hpp:314
std::size_t resample_trans_residual(std::size_t N, std::size_t M, InputIter weight, OutputIterR resid, OutputIterI integ)
Transform normalized weights to normalized residual and integrals,.
Definition: resample.hpp:334
Vector< index_type > index_matrix(MatrixLayout layout, std::size_t iter_back, std::size_t iter) const
Get the resampling index matrix.
Definition: resample.hpp:729
void reset()
Reset history.
Definition: resample.hpp:627
SMCSampler<T>::eval_type subtype.
Definition: resample.hpp:471
OutputIter resample_trans_u01_rep(std::size_t N, std::size_t M, InputIter weight, U01SeqType &&u01seq, OutputIter replication)
Transform uniform [0, 1) sequence into replication numbers.
Definition: resample.hpp:375
size_type size() const
The number of particles.
Definition: particle.hpp:318
SizeType< T > size_type
Definition: particle.hpp:282
void push_back(std::size_t N, InputIter first)
Append a resampling index.
Definition: resample.hpp:646
Definition: mcmc.hpp:40
void operator()(RNG &rng, std::size_t N, RealType *r) const
Definition: resample.hpp:300
void exp(std::size_t n, const float *a, float *y)
Definition: vmf.hpp:221
#define MCKL_ALIGNMENT
The default alignment for scalar type.
Definition: config.h:187
void operator()(std::size_t N, const RealType *u01, RealType *r) const
Definition: resample.hpp:294
Standard uniform distribution on [0, 1)
std::size_t index_matrix_nrow() const
Definition: resample.hpp:683
std::size_t size() const
The sample size of the last iteration.
Definition: resample.hpp:609
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. ...
Definition: resample.hpp:167
void operator()(std::size_t N, std::size_t M, RNGType &rng, InputIter weight, OutputIter replication) const
Generate replication numbers from normalized weights.
Definition: resample.hpp:527
void selection(Eval &&eval)
Set a new evaluation object of type eval_type.
Definition: resample.hpp:488
Resampling algorithm.
Definition: resample.hpp:516
std::size_t index_matrix_ncol() const
Definition: resample.hpp:697
Particle system.
Definition: particle.hpp:45
void u01_trans_stratified_impl(std::size_t n0, std::size_t n, const RealType *u01, RealType *r, RealType delta)
Definition: resample.hpp:96
void u01_rand_sorted_impl(RNGType &rng, std::size_t n0, std::size_t n, RealType *r, std::size_t N, RealType &lmax)
Definition: resample.hpp:84
index_type index(std::size_t id) const
Definition: resample.hpp:657
void operator()(RNG &rng, std::size_t N, RealType *r) const
Definition: resample.hpp:318
ResampleEval(const eval_type &eval)
Construct a Sampler::move_type object.
Definition: resample.hpp:484
void runtime_assert(bool cond, const char *msg, bool soft=false)
Definition: assert.hpp:65
MatrixLayout
Matrix layout.
Definition: defines.hpp:46
void u01_rand_systematic(RNGType &rng, std::size_t N, RealType *r)
Generate systematic standard uniform numbers.
Definition: resample.hpp:259
void u01_distribution(RNGType &rng, std::size_t n, RealType *r)