vSMC
vSMC: Scalable Monte Carlo
state_matrix.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/core/state_matrix.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_CORE_STATE_MATRIX_HPP
33 #define VSMC_CORE_STATE_MATRIX_HPP
34 
35 #include <vsmc/internal/common.hpp>
37 
38 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_COPY_SIZE_MISMATCH \
39  VSMC_RUNTIME_ASSERT((N == static_cast<size_type>(this->size())), \
40  "**StateMatrix::copy** SIZE MISMATCH")
41 
42 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_DIM_SIZE(dim) \
43  VSMC_RUNTIME_ASSERT((dim >= 1), "**StateMatrix** DIMENSION IS LESS THAN " \
44  "1")
45 
46 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_UNPACK_SIZE(psize, dim) \
47  VSMC_RUNTIME_ASSERT((psize >= dim), \
48  "**StateMatrix::state_unpack** INPUT PACK SIZE TOO SMALL")
49 
50 namespace vsmc
51 {
52 
53 namespace internal
54 {
55 
56 template <std::size_t Dim>
58 {
59  public:
60  static constexpr std::size_t dim() { return Dim; }
61 
62  protected:
64 }; // class StateMatrixDim
65 
66 template <>
68 {
69  public:
70  StateMatrixDim() : dim_(1) {}
71 
72  std::size_t dim() const { return dim_; }
73 
74  protected:
75  void swap(StateMatrixDim<Dynamic> &other) { std::swap(dim_, other.dim_); }
76 
77  void resize_dim(std::size_t dim) { dim_ = dim; }
78 
79  private:
80  std::size_t dim_;
81 }; // class StateMatrixDim
82 
83 } // namespace vsmc::internal
84 
87 template <MatrixLayout Layout, std::size_t Dim, typename T>
89 {
90  public:
91  using size_type = std::size_t;
92  using state_type = T;
94 
95  template <typename S>
97  {
98  public:
100  typename Particle<S>::size_type id, Particle<S> *pptr)
101  : SingleParticleBase<S>(id, pptr)
102  {
103  }
104 
105  std::size_t dim() const { return this->particle().value().dim(); }
106 
107  state_type &state(std::size_t pos) const
108  {
109  return this->particle().value().state(this->id(), pos);
110  }
111  }; // class single_particle_type
112 
113  void resize_dim(std::size_t dim)
114  {
115  static_assert(Dim == Dynamic,
116  "**StateMatrix** OBJECT DECLARED WITH A FIXED DIMENSION");
118 
120  data_.resize(size_ * dim);
121  }
122 
123  size_type size() const { return size_; }
124 
125  state_type *data() { return data_.data(); }
126 
127  const state_type *data() const { return data_.data(); }
128 
130  {
132  std::swap(size_, other.size_);
133  data_.swap(other.data_);
134  }
135 
136  template <typename OutputIter>
137  void read_state(std::size_t pos, OutputIter first) const
138  {
139  const StateMatrix<Layout, Dim, T> *sptr =
140  static_cast<const StateMatrix<Layout, Dim, T> *>(this);
141  for (size_type i = 0; i != size_; ++i, ++first)
142  *first = sptr->state(i, pos);
143  }
144 
145  template <typename OutputIterIter>
146  void read_state_matrix(OutputIterIter first) const
147  {
148  for (std::size_t d = 0; d != this->dim(); ++d, ++first)
149  read_state(d, *first);
150  }
151 
152  template <MatrixLayout RLayout, typename OutputIter>
153  void read_state_matrix(OutputIter first) const
154  {
155  if (RLayout == Layout) {
156  std::copy(data_.begin(), data_.end(), first);
157  } else {
158  const StateMatrix<Layout, Dim, T> *sptr =
159  static_cast<const StateMatrix<Layout, Dim, T> *>(this);
160  if (RLayout == RowMajor) {
161  for (size_type i = 0; i != size_; ++i)
162  for (std::size_t d = 0; d != this->dim(); ++d)
163  *first++ = sptr->state(i, d);
164  } else if (RLayout == ColMajor) {
165  for (std::size_t d = 0; d != this->dim(); ++d)
166  for (size_type i = 0; i != size_; ++i)
167  *first++ = sptr->state(i, d);
168  }
169  }
170  }
171 
172  template <typename CharT, typename Traits>
173  std::basic_ostream<CharT, Traits> &print(
174  std::basic_ostream<CharT, Traits> &os, char sepchar = '\t') const
175  {
176  if (this->dim() == 0 || size_ == 0 || !os.good())
177  return os;
178 
179  const StateMatrix<Layout, Dim, T> *sptr =
180  static_cast<const StateMatrix<Layout, Dim, T> *>(this);
181  for (size_type i = 0; i != size_; ++i) {
182  for (std::size_t d = 0; d != this->dim() - 1; ++d)
183  os << sptr->state(i, d) << sepchar;
184  os << sptr->state(i, this->dim() - 1) << '\n';
185  }
186 
187  return os;
188  }
189 
190  protected:
191  explicit StateMatrixBase(size_type N) : size_(N), data_(N * Dim) {}
192 
193  private:
194  size_type size_;
195  Vector<T> data_;
196 }; // class StateMatrixBase
197 
198 template <typename CharT, typename Traits, MatrixLayout Layout,
199  std::size_t Dim, typename T>
200 inline std::basic_ostream<CharT, Traits> &operator<<(
201  std::basic_ostream<CharT, Traits> &os,
202  const StateMatrixBase<Layout, Dim, T> &smatrix)
203 {
204  return smatrix.print(os);
205 }
206 
209 template <std::size_t Dim, typename T>
210 class StateMatrix<RowMajor, Dim, T> : public StateMatrixBase<RowMajor, Dim, T>
211 {
212  public:
217 
219 
220  T &state(size_type id, std::size_t pos)
221  {
222  return this->data()[id * this->dim() + pos];
223  }
224 
225  const T &state(size_type id, std::size_t pos) const
226  {
227  return this->data()[id * this->dim() + pos];
228  }
229 
230  using state_matrix_base_type::data;
231 
232  state_type *data(size_type id) { return row_data(id); }
233 
234  const state_type *data(size_type id) const { return row_data(id); }
235 
237  {
238  return this->data() + id * this->dim();
239  }
240 
241  const state_type *row_data(size_type id) const
242  {
243  return this->data() + id * this->dim();
244  }
245 
246  template <typename IntType>
247  void copy(size_type N, const IntType *index)
248  {
250 
251  for (size_type dst = 0; dst != N; ++dst)
252  copy_particle(index[dst], dst);
253  }
254 
256  {
257  if (src == dst)
258  return;
259 
260  copy_particle_dispatch(src, dst, std::integral_constant < bool,
261  Dim == Dynamic || 8 < Dim > ());
262  }
263 
265  {
266  state_pack_type pack(this->dim());
267  std::copy(row_data(id), row_data(id) + this->dim(), pack.data());
268 
269  return pack;
270  }
271 
272  void state_unpack(size_type id, const state_pack_type &pack)
273  {
275  pack.size(), this->dim());
276 
277  const state_type *ptr = pack.data();
278  std::copy(ptr, ptr + this->dim(), row_data(id));
279  }
280 
282  {
284  pack.size(), this->dim());
285 
286  const state_type *ptr = pack.data();
287  std::move(ptr, ptr + this->dim(), row_data(id));
288  }
289 
290  private:
291  void copy_particle_dispatch(size_type src, size_type dst, std::true_type)
292  {
293  std::copy(row_data(src), row_data(src) + this->dim(), row_data(dst));
294  }
295 
296  void copy_particle_dispatch(size_type src, size_type dst, std::false_type)
297  {
298  copy_particle_pos<0>(row_data(src), row_data(dst),
299  std::integral_constant<bool, 0 < Dim>());
300  }
301 
302  template <std::size_t D>
303  void copy_particle_pos(const state_type *, state_type *, std::false_type)
304  {
305  }
306 
307  template <std::size_t D>
308  void copy_particle_pos(
309  const state_type *src, state_type *dst, std::true_type)
310  {
311  dst[D] = src[D];
312  copy_particle_pos<D + 1>(
313  src, dst, std::integral_constant<bool, D + 1 < Dim>());
314  }
315 }; // class StateMatrix
316 
319 template <std::size_t Dim, typename T>
320 class StateMatrix<ColMajor, Dim, T> : public StateMatrixBase<ColMajor, Dim, T>
321 {
322  public:
327 
329 
330  T &state(size_type id, std::size_t pos)
331  {
332  return this->data()[pos * this->size() + id];
333  }
334 
335  const T &state(size_type id, std::size_t pos) const
336  {
337  return this->data()[pos * this->size() + id];
338  }
339 
340  using state_matrix_base_type::data;
341 
342  state_type *data(size_type pos) { return col_data(pos); }
343 
344  const state_type *data(size_type pos) const { return col_data(pos); }
345 
346  state_type *col_data(std::size_t pos)
347  {
348  return this->data() + pos * this->size();
349  }
350 
351  const state_type *col_data(std::size_t pos) const
352  {
353  return this->data() + pos * this->size();
354  }
355 
356  template <typename IntType>
357  void copy(size_type N, const IntType *index)
358  {
360 
361  for (std::size_t d = 0; d != this->dim(); ++d)
362  for (size_type dst = 0; dst != N; ++dst)
363  state(dst, d) = state(static_cast<size_type>(index[dst]), d);
364  }
365 
367  {
368  if (src == dst)
369  return;
370 
371  copy_particle_dispatch(src, dst, std::integral_constant < bool,
372  Dim == Dynamic || 8 < Dim > ());
373  }
374 
376  {
377  state_pack_type pack(this->dim());
378  for (std::size_t d = 0; d != this->dim(); ++d)
379  pack[d] = state(id, d);
380 
381  return pack;
382  }
383 
384  void state_unpack(size_type id, const state_pack_type &pack)
385  {
387  pack.size(), this->dim());
388 
389  for (std::size_t d = 0; d != this->dim(); ++d)
390  state(id, d) = pack[d];
391  }
392 
394  {
396  pack.size(), this->dim());
397 
398  for (std::size_t d = 0; d != this->dim(); ++d)
399  state(id, d) = std::move(pack[d]);
400  }
401 
402  private:
403  void copy_particle_dispatch(size_type src, size_type dst, std::true_type)
404  {
405  for (std::size_t d = 0; d != this->dim(); ++d)
406  state(dst, d) = state(src, d);
407  }
408 
409  void copy_particle_dispatch(size_type src, size_type dst, std::false_type)
410  {
411  copy_particle_pos<0>(this->data() + src, this->data() + dst,
412  std::integral_constant<bool, 0 < Dim>());
413  }
414 
415  template <std::size_t D>
416  void copy_particle_pos(const state_type *, state_type *, std::false_type)
417  {
418  }
419 
420  template <std::size_t D>
421  void copy_particle_pos(
422  const state_type *src, state_type *dst, std::true_type)
423  {
424  dst[D * this->size()] = src[D * this->size()];
425  copy_particle_pos<D + 1>(
426  src, dst, std::integral_constant<bool, D + 1 < Dim>());
427  }
428 }; // class StateMatrix
429 
430 } // namespace vsmc
431 
432 #endif // VSMC_CORE_STATE_MATRIX_HPP
single_particle_type(typename Particle< S >::size_type id, Particle< S > *pptr)
T & state(size_type id, std::size_t pos)
Definition: monitor.hpp:49
Particle class representing the whole particle set.
Definition: particle.hpp:48
state_type & state(std::size_t pos) const
state_type * row_data(size_type id)
void read_state_matrix(OutputIter first) const
typename state_matrix_base_type::state_pack_type state_pack_type
Base type of StateMatrix.
state_type * data(size_type id)
void state_unpack(size_type id, const state_pack_type &pack)
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_DIM_SIZE(dim)
MatrixLayout
Matrix layout.
Definition: defines.hpp:49
const T & state(size_type id, std::size_t pos) const
const T & state(size_type id, std::size_t pos) const
state_type * data(size_type pos)
const state_type * col_data(std::size_t pos) const
size_type size() const
typename state_matrix_base_type::size_type size_type
const state_type * row_data(size_type id) const
void copy_particle(size_type src, size_type dst)
void state_unpack(size_type id, state_pack_type &&pack)
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, char sepchar= '\t') const
void copy_particle(size_type src, size_type dst)
const state_type * data() const
typename state_matrix_base_type::state_pack_type state_pack_type
state_pack_type state_pack(size_type id) const
void swap(StateMatrixBase< Layout, Dim, T > &other)
typename state_matrix_base_type::state_type state_type
void read_state(std::size_t pos, OutputIter first) const
static constexpr std::size_t dim()
void state_unpack(size_type id, state_pack_type &&pack)
state_pack_type state_pack(size_type id) const
void copy(size_type N, const IntType *index)
void resize_dim(std::size_t dim)
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Sampler< T > &sampler)
Definition: sampler.hpp:861
StateMatrixBase(size_type N)
void swap(const MKLBase< MKLPtr, Derived > &ptr1, const MKLBase< MKLPtr, Derived > &ptr2)
Swap two MKLBase objects.
Definition: mkl.hpp:139
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_COPY_SIZE_MISMATCH
const state_type * data(size_type pos) const
void read_state_matrix(OutputIterIter first) const
void swap(StateMatrixDim< Dim > &)
A thin wrapper over a complete Particle.
state_type * col_data(std::size_t pos)
typename state_matrix_base_type::state_type state_type
const state_type * data(size_type id) const
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_UNPACK_SIZE(psize, dim)
T & state(size_type id, std::size_t pos)
void swap(StateMatrixDim< Dynamic > &other)
void state_unpack(size_type id, const state_pack_type &pack)
typename state_matrix_base_type::size_type size_type
void copy(size_type N, const IntType *index)