vSMC
vSMC: 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(test, func) \
38  VSMC_RUNTIME_ASSERT( \
39  (test), "**StateIndex::" #func "ITERATION NUMBER OUT OF RANGE")
40 
41 namespace vsmc
42 {
43 
46 template <typename IntType = std::size_t>
48 {
49  public:
50  using size_type = std::size_t;
51  using index_type = IntType;
52 
53  ResampleIndex(size_type N) : size_(N), identity_(N)
54  {
55  for (size_type i = 0; i != N; ++i)
56  identity_[i] = static_cast<index_type>(i);
57  }
58 
59  size_type size() const { return size_; }
60 
62  std::size_t iter_size() const { return iter_size_; }
63 
65  void reset() { iter_size_ = 0; }
66 
68  void clear() { index_.clear(); }
69 
70  void push_back()
71  {
73  (index_.size() >= iter_size_), push_back);
74 
75  ++iter_size_;
76  if (index_.size() < iter_size_)
77  index_.push_back(identity_);
78  else
79  index_[iter_size_ - 1] = identity_;
80  }
81 
82  template <typename InputIter>
83  void push_back(InputIter first)
84  {
85  push_back();
86  std::copy_n(first, size_, index_[iter_size_ - 1].data());
87  }
88 
89  void insert()
90  {
92  (iter_size_ > 0 && index_.size() >= iter_size_), insert);
93 
94  std::copy_n(identity_.data(), size_, index_[iter_size_ - 1].data());
95  }
96 
97  template <typename InputIter>
98  void insert(InputIter first)
99  {
101  (iter_size_ > 0 && index_.size() >= iter_size_), insert);
102 
103  std::copy_n(first, size_, index_[iter_size_ - 1].begin());
104  }
105 
106  template <typename InputIter>
107  void insert(std::size_t iter, InputIter first)
108  {
110  (iter_size_ > iter && index_.size() >= iter_size_), insert);
111 
112  std::copy_n(first, size_, index_[iter].begin());
113  }
114 
121  index_type index(size_type id, std::size_t iter) const
122  {
124  (iter_size_ > iter && index_.size() >= iter_size_), index);
125 
126  std::size_t iter_current = iter_size_ - 1;
127  index_type idx = index_.back()[id];
128  while (iter_current != iter) {
129  --iter_current;
130  idx = index_[iter_current][idx];
131  }
132 
133  return idx;
134  }
135 
136  template <MatrixLayout Layout>
138  {
139  return index_matrix_dispatch(
140  std::integral_constant<MatrixLayout, Layout>());
141  }
142 
143  template <MatrixLayout Layout, typename OutputIter>
144  void read_index_matrix(OutputIter first) const
145  {
146  Vector<index_type> idxmat(index_matrix<Layout>());
147  std::copy(idxmat.begin(), idxmat.end(), first);
148  }
149 
150  private:
151  size_type size_;
152  std::size_t iter_size_;
153  Vector<index_type> identity_;
155 
156  Vector<index_type> index_matrix_dispatch(
157  std::integral_constant<MatrixLayout, RowMajor>) const
158  {
159  Vector<index_type> idxmat(size_ * iter_size_);
160  if (size_ * iter_size_ == 0)
161  return idxmat;
162 
163  index_type *back = idxmat.data() + iter_size_ - 1;
164  for (size_type i = 0; i != size_; ++i, back += iter_size_)
165  *back = index_[iter_size_ - 1][i];
166  if (iter_size_ == 1)
167  return idxmat;
168 
169  for (std::size_t iter = iter_size_ - 1; iter != 0; --iter) {
170  const index_type *idx = index_[iter - 1].data();
171  const index_type *last = idxmat.data() + iter;
172  index_type *next = idxmat.data() + iter - 1;
173  for (size_type i = 0; i != size_; ++i) {
174  *next = idx[static_cast<size_type>(*last)];
175  last += iter_size_;
176  next += iter_size_;
177  }
178  }
179 
180  return idxmat;
181  }
182 
183  Vector<index_type> index_matrix_dispatch(
184  std::integral_constant<MatrixLayout, ColMajor>) const
185  {
186  Vector<index_type> idxmat(size_ * iter_size_);
187  if (size_ * iter_size_ == 0)
188  return idxmat;
189 
190  index_type *back = idxmat.data() + size_ * (iter_size_ - 1);
191  for (size_type i = 0; i != size_; ++i)
192  back[i] = index_[iter_size_ - 1][i];
193  if (iter_size_ == 1)
194  return idxmat;
195 
196  for (std::size_t iter = iter_size_ - 1; iter != 0; --iter) {
197  const index_type *idx = index_[iter - 1].data();
198  const index_type *last = idxmat.data() + size_ * iter;
199  index_type *next = idxmat.data() + size_ * (iter - 1);
200  for (size_type i = 0; i != size_; ++i)
201  next[i] = idx[static_cast<size_type>(last[i])];
202  }
203 
204  return idxmat;
205  }
206 }; // class ResampleIndex
207 
208 } // namespace vsmc
209 
210 #endif // VSMC_RESAMPLE_INDEX_HPP
void read_index_matrix(OutputIter first) const
Definition: index.hpp:144
Definition: monitor.hpp:49
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
void reset()
Reset history.
Definition: index.hpp:65
std::size_t iter_size() const
Number of iterations recorded.
Definition: index.hpp:62
Record and trace resample index.
Definition: index.hpp:47
IntType index_type
Definition: index.hpp:51
size_type size() const
Definition: index.hpp:59
Vector< index_type > index_matrix() const
Definition: index.hpp:137
std::size_t size_type
Definition: index.hpp:50
void insert(InputIter first)
Definition: index.hpp:98
void push_back(InputIter first)
Definition: index.hpp:83
#define VSMC_RUNTIME_ASSERT_RESAMPLE_INDEX_ITER(test, func)
Definition: index.hpp:37
ResampleIndex(size_type N)
Definition: index.hpp:53
void push_back()
Definition: index.hpp:70
void clear()
Release memory.
Definition: index.hpp:68
index_type index(size_type id, std::size_t iter) const
Get the index given the particle ID and iteration number, starting with zero.
Definition: index.hpp:121
void insert(std::size_t iter, InputIter first)
Definition: index.hpp:107