vSMC  v3.0.0
Scalable Monte Carlo
transform.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/resample/transform.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_RESAMPLE_TRANSFORM_HPP
33 #define VSMC_RESAMPLE_TRANSFORM_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 namespace vsmc
38 {
39 
49 template <typename InputIter, typename OutputIterR, typename OutputIterI>
50 inline std::size_t resample_trans_residual(std::size_t N, std::size_t M,
51  InputIter weight, OutputIterR resid, OutputIterI integ)
52 {
53  using resid_type = typename std::iterator_traits<OutputIterR>::value_type;
54  using integ_type = typename std::iterator_traits<OutputIterI>::value_type;
55 
56  static_assert(std::is_floating_point<resid_type>::value,
57  "**resample_trans_residual** OUTPUT resid IS NOT OF FLOATING POINT "
58  "TYPES");
59 
60  resid_type sum_resid = 0;
61  integ_type sum_integ = 0;
62  OutputIterR resid_i = resid;
63  OutputIterI integ_i = integ;
64  const resid_type coeff = static_cast<resid_type>(M);
65  for (std::size_t i = 0; i != N; ++i, ++weight, ++resid_i, ++integ_i) {
66  resid_type w = coeff * static_cast<resid_type>(*weight);
67  resid_type integral;
68  *resid_i = std::modf(w, &integral);
69  *integ_i = static_cast<integ_type>(integral);
70  sum_resid += *resid_i;
71  sum_integ += *integ_i;
72  }
73 
74  const resid_type mul_resid = 1 / sum_resid;
75  for (std::size_t i = 0; i != N; ++i, ++resid)
76  *resid *= mul_resid;
77 
78  return M - static_cast<std::size_t>(sum_integ);
79 }
80 
89 template <typename InputIter, typename OutputIter, typename U01SeqType>
90 inline OutputIter resample_trans_u01_rep(std::size_t N, std::size_t M,
91  InputIter weight, U01SeqType &&u01seq, OutputIter replication)
92 {
93  using real_type = typename std::iterator_traits<InputIter>::value_type;
94  using rep_type = typename std::iterator_traits<OutputIter>::value_type;
95 
96  if (N == 0)
97  return replication;
98 
99  if (N == 1) {
100  *replication++ = static_cast<rep_type>(M);
101  return replication;
102  }
103 
104  OutputIter rep = std::fill_n(replication, N, static_cast<rep_type>(0));
105  if (M == 0)
106  return rep;
107 
108  real_type accw = 0;
109  std::size_t j = 0;
110  for (std::size_t i = 0; i != N - 1; ++i, ++weight, ++replication) {
111  accw += *weight;
112  while (j != M && static_cast<real_type>(u01seq[j]) < accw) {
113  *replication += 1;
114  ++j;
115  }
116  }
117  *replication++ = static_cast<rep_type>(M - j);
118 
119  return replication;
120 }
121 
129 template <typename InputIter, typename OutputIter>
130 inline OutputIter resample_trans_rep_index(
131  std::size_t N, std::size_t M, InputIter replication, OutputIter index)
132 {
133  using rep_type = typename std::iterator_traits<InputIter>::value_type;
134  using idx_type = typename std::iterator_traits<OutputIter>::value_type;
135 
136  if (N == 0 || M == 0)
137  return index;
138 
139  const std::size_t K = std::min(N, M);
140  rep_type time = 0;
141  std::size_t src = 0;
142  InputIter rep = replication;
143 
144  auto seek = [N, K, &time, &src, &rep]() {
145  if (src < K && *rep < time + 2) {
146  time = 0;
147  do {
148  ++src;
149  ++rep;
150  } while (src < K && *rep < time + 2);
151  }
152  if (src >= K && *rep < time + 1) {
153  time = 0;
154  do {
155  ++src;
156  ++rep;
157  } while (src < N && *rep < time + 1);
158  }
159  };
160 
161  for (std::size_t dst = 0; dst != K; ++dst, ++replication, ++index) {
162  if (*replication > 0) {
163  *index = static_cast<idx_type>(dst);
164  } else {
165  seek();
166  *index = static_cast<idx_type>(src);
167  ++time;
168  }
169  }
170 
171  for (std::size_t dst = K; dst < M; ++dst, ++index) {
172  seek();
173  *index = static_cast<idx_type>(src);
174  ++time;
175  }
176 
177  return index;
178 }
179 
180 } // namespace vsmc
181 
182 #endif // VSMC_RESAMPLE_TRANSFORM_HPP
Definition: monitor.hpp:48
OutputIter resample_trans_rep_index(std::size_t N, std::size_t M, InputIter replication, OutputIter index)
Transform replication numbers into parent indices.
Definition: transform.hpp:130
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: transform.hpp:50
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: transform.hpp:90
void modf(std::size_t n, const float *a, float *y, float *z)
Definition: vmath.hpp:159