vSMC  v3.0.0
Scalable Monte Carlo
index.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/resample/index.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_INDEX_HPP
33 #define VSMC_RESAMPLE_INDEX_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #define VSMC_RUNTIME_ASSERT_RESAMPLE_INDEX_ITER(iter, iter_back, func) \
38  VSMC_RUNTIME_ASSERT((iter <= iter_back && iter_back < iter_size()), \
39  "**ResampleIndex::" #func "** ITERATION NUMBERS OUT OF RANGE")
40 
41 namespace vsmc
42 {
43 
46 template <typename IntType = std::size_t>
48 {
49  public:
50  using index_type = IntType;
51 
52  ResampleIndex() : iter_size_(0) {}
53 
55  std::size_t iter_size() const { return iter_size_; }
56 
58  std::size_t size() const
59  {
61 
62  return index_.back().size();
63  }
64 
66  std::size_t size(std::size_t iter) const
67  {
69 
70  return index_[iter].size();
71  }
72 
74  void reset() { iter_size_ = 0; }
75 
77  void clear() { index_.clear(); }
78 
80  void push_back(std::size_t N)
81  {
82  ++iter_size_;
83  resize_identity(N);
84  if (index_.size() < iter_size_)
85  index_.push_back(identity_);
86  else
87  index_[iter_size_ - 1] = identity_;
88  }
89 
91  template <typename InputIter>
92  void push_back(std::size_t N, InputIter first)
93  {
94  ++iter_size_;
95  if (index_.size() < iter_size_)
96  index_.push_back(Vector<index_type>(N));
97  else
98  index_[iter_size_ - 1].resize(N);
99  std::copy_n(first, N, index_[iter_size_ - 1].begin());
100  }
101 
103  void insert(std::size_t N)
104  {
106 
107  resize_identity(N);
108  index_[iter_size_ - 1].resize(N);
109  std::copy_n(identity_.begin(), N, index_[iter_size_ - 1].begin());
110  }
111 
113  template <typename InputIter>
114  void insert(std::size_t N, InputIter first)
115  {
117 
118  index_[iter_size_ - 1].resize(N);
119  std::copy_n(first, N, index_[iter_size_ - 1].begin());
120  }
121 
123  template <typename InputIter>
124  void insert(std::size_t N, std::size_t iter, InputIter first)
125  {
127 
128  index_[iter].resize(N);
129  std::copy_n(first, N, index_[iter].begin());
130  }
131 
132  index_type index(std::size_t id) const
133  {
134  return index(id, iter_size_ - 1, 0);
135  }
136 
137  index_type index(std::size_t id, std::size_t iter_back) const
138  {
139  return index(id, iter_back, 0);
140  }
141 
144  std::size_t id, std::size_t iter_back, std::size_t iter) const
145  {
147 
148  index_type idx = index_.back()[id];
149  while (iter_back > iter) {
150  --iter_back;
151  idx = index_[iter_back][idx];
152  }
153 
154  return idx;
155  }
156 
157  std::size_t index_matrix_nrow() const
158  {
159  return index_matrix_nrow(iter_size_ - 1);
160  }
161 
162  std::size_t index_matrix_nrow(std::size_t iter_back) const
163  {
164  VSMC_RUNTIME_ASSERT_RESAMPLE_INDEX_ITER(iter_back, iter_back, insert);
165 
166  return index_[iter_back].size();
167  }
168 
169  std::size_t index_matrix_ncol() const
170  {
171  return index_matrix_ncol(iter_size_ - 1, 0);
172  }
173 
174  std::size_t index_matrix_ncol(std::size_t iter_back) const
175  {
176  return index_matrix_ncol(iter_back, 0);
177  }
178 
179  std::size_t index_matrix_ncol(
180  std::size_t iter_back, std::size_t iter) const
181  {
183 
184  return iter_back - iter + 1;
185  }
186 
188  {
189  return index_matrix(layout, iter_size_ - 1, 0);
190  }
191 
193  MatrixLayout layout, std::size_t iter_back) const
194  {
195  return index_matrix(layout, iter_back, 0);
196  }
197 
200  MatrixLayout layout, std::size_t iter_back, std::size_t iter) const
201  {
203 
204  Vector<index_type> idxmat(
205  index_matrix_nrow(iter_back) * index_matrix_ncol(iter_back, iter));
206  read_index_matrix(layout, idxmat.begin(), iter_back, iter);
207 
208  return idxmat;
209  }
210 
211  template <typename RandomIter>
212  RandomIter read_index_matrix(MatrixLayout layout, RandomIter first) const
213  {
214  return read_index_matrix(layout, first, iter_size_ - 1, 0);
215  }
216 
217  template <typename RandomIter>
218  RandomIter read_index_matrix(
219  MatrixLayout layout, RandomIter first, std::size_t iter_back) const
220  {
221  return read_index_matrix(layout, first, iter_back, 0);
222  }
223 
233  template <typename RandomIter>
234  RandomIter read_index_matrix(MatrixLayout layout, RandomIter first,
235  std::size_t iter_back, std::size_t iter) const
236  {
238 
239  using difference_type =
240  typename std::iterator_traits<RandomIter>::difference_type;
241  const std::size_t N = index_matrix_nrow(iter_back);
242  const std::size_t R = index_matrix_ncol(iter_back, iter);
243 
244  if (layout == RowMajor) {
245  RandomIter back = first + static_cast<difference_type>(R - 1);
246  const index_type *idx = index_[iter_back].data();
247  for (std::size_t i = 0; i != N; ++i)
248  back[static_cast<difference_type>(i * R)] = idx[i];
249  for (std::size_t r = 1; r != R; ++r) {
250  const std::size_t j = iter_back - r;
251  RandomIter last = back;
252  --back;
253  idx = index_[j].data();
254  for (std::size_t i = 0; i != N; ++i) {
255  back[static_cast<difference_type>(i * R)] =
256  idx[static_cast<std::size_t>(
257  last[static_cast<difference_type>(i * R)])];
258  }
259  }
260  }
261 
262  if (layout == ColMajor) {
263  RandomIter back =
264  first + static_cast<difference_type>(N * (R - 1));
265  const index_type *idx = index_[iter_back].data();
266  std::copy_n(idx, N, back);
267  for (std::size_t r = 1; r != R; ++r) {
268  const std::size_t j = iter_back - r;
269  RandomIter last = back;
270  back -= static_cast<difference_type>(N);
271  idx = index_[j].data();
272  for (std::size_t i = 0; i != N; ++i) {
273  back[static_cast<difference_type>(i)] =
274  idx[static_cast<std::size_t>(
275  last[static_cast<difference_type>(i)])];
276  }
277  }
278  }
279 
280  return first + static_cast<difference_type>(N * R);
281  }
282 
283  private:
284  std::size_t iter_size_;
285  Vector<index_type> identity_;
287 
288  void resize_identity(std::size_t N)
289  {
290  std::size_t n = identity_.size();
291  identity_.resize(N);
292  if (n < N)
293  for (std::size_t i = n; i != N; ++i)
294  identity_[i] = static_cast<index_type>(i);
295  }
296 }; // class ResampleIndex
297 
298 } // namespace vsmc
299 
300 #endif // VSMC_RESAMPLE_INDEX_HPP
std::vector< T, Alloc > Vector
std::vector with Allocator as default allocator
Definition: monitor.hpp:48
std::size_t size(std::size_t iter) const
The sample size of a given iteration.
Definition: index.hpp:66
void push_back(std::size_t N, InputIter first)
Append a resampling index.
Definition: index.hpp:92
void insert(std::size_t N, std::size_t iter, InputIter first)
Insert at a given iteration a resampling index.
Definition: index.hpp:124
void push_back(std::size_t N)
Append an identity resampling index.
Definition: index.hpp:80
MatrixLayout
Matrix layout.
Definition: defines.hpp:51
index_type index(std::size_t id, std::size_t iter_back) const
Definition: index.hpp:137
std::size_t index_matrix_ncol(std::size_t iter_back) const
Definition: index.hpp:174
void reset()
Reset history.
Definition: index.hpp:74
std::size_t iter_size() const
Number of iterations recorded.
Definition: index.hpp:55
void insert(std::size_t N, InputIter first)
Insert at last iteration an identity resampling index.
Definition: index.hpp:114
Vector< index_type > index_matrix(MatrixLayout layout, std::size_t iter_back, std::size_t iter) const
Get the resampling index matrix.
Definition: index.hpp:199
Record and trace resampling index.
Definition: index.hpp:47
IntType index_type
Definition: index.hpp:50
RandomIter read_index_matrix(MatrixLayout layout, RandomIter first) const
Definition: index.hpp:212
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: index.hpp:234
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: index.hpp:143
std::size_t index_matrix_nrow(std::size_t iter_back) const
Definition: index.hpp:162
Vector< index_type > index_matrix(MatrixLayout layout) const
Definition: index.hpp:187
std::size_t index_matrix_ncol(std::size_t iter_back, std::size_t iter) const
Definition: index.hpp:179
index_type index(std::size_t id) const
Definition: index.hpp:132
Vector< index_type > index_matrix(MatrixLayout layout, std::size_t iter_back) const
Definition: index.hpp:192
void clear()
Release memory.
Definition: index.hpp:77
#define VSMC_RUNTIME_ASSERT_RESAMPLE_INDEX_ITER(iter, iter_back, func)
Definition: index.hpp:37
std::size_t index_matrix_nrow() const
Definition: index.hpp:157
void insert(std::size_t N)
Insert at last iteration an identity resampling index.
Definition: index.hpp:103
RandomIter read_index_matrix(MatrixLayout layout, RandomIter first, std::size_t iter_back) const
Definition: index.hpp:218
std::size_t index_matrix_ncol() const
Definition: index.hpp:169
std::size_t size() const
The sample size of the last iteration.
Definition: index.hpp:58