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-2015, 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_STATIC_ASSERT_CORE_STATE_MATRIX_DYNAMIC_DIM_RESIZE(Dim) \
39  VSMC_STATIC_ASSERT((Dim == Dynamic), \
40  "**StateMatrix::resize_dim** USED WITH A FIXED DIMENSION OBJECT")
41 
42 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_COPY_SIZE_MISMATCH \
43  VSMC_RUNTIME_ASSERT((N == static_cast<size_type>(this->size())), \
44  "**StateMatrix::copy** SIZE MISMATCH")
45 
46 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_DIM_SIZE(dim) \
47  VSMC_RUNTIME_ASSERT((dim >= 1), "**StateMatrix** DIMENSION IS LESS THAN " \
48  "1")
49 
50 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_UNPACK_SIZE(psize, dim) \
51  VSMC_RUNTIME_ASSERT((psize >= dim), \
52  "**StateMatrix::state_unpack** INPUT PACK SIZE TOO SMALL")
53 
54 namespace vsmc
55 {
56 
57 namespace internal
58 {
59 
60 template <std::size_t Dim>
62 {
63  public:
64  static constexpr std::size_t dim() { return Dim; }
65 
66  protected:
68 }; // class StateMatrixDim
69 
70 template <>
72 {
73  public:
74  StateMatrixDim() : dim_(1) {}
75 
76  std::size_t dim() const { return dim_; }
77 
78  protected:
79  void swap(StateMatrixDim<Dynamic> &other) { std::swap(dim_, other.dim_); }
80 
81  void resize_dim(std::size_t dim) { dim_ = dim; }
82 
83  private:
84  std::size_t dim_;
85 }; // class StateMatrixDim
86 
87 } // namespace vsmc::internal
88 
91 template <MatrixOrder Order, std::size_t Dim, typename T>
93 {
94  public:
95  using size_type = std::size_t;
96  using state_type = T;
98 
99  template <typename S>
101  {
102  public:
104  typename Particle<S>::size_type id, Particle<S> *pptr)
105  : SingleParticleBase<S>(id, pptr)
106  {
107  }
108 
109  std::size_t dim() const { return this->particle().value().dim(); }
110 
111  state_type &state(std::size_t pos) const
112  {
113  return this->particle().value().state(this->id(), pos);
114  }
115  }; // class single_particle_type
116 
117  void resize_dim(std::size_t dim)
118  {
121 
123  data_.resize(size_ * dim);
124  }
125 
126  size_type size() const { return size_; }
127 
128  state_type *data() { return data_.data(); }
129 
130  const state_type *data() const { return data_.data(); }
131 
133  {
135  std::swap(size_, other.size_);
136  data_.swap(other.data_);
137  }
138 
139  template <typename OutputIter>
140  void read_state(std::size_t pos, OutputIter first) const
141  {
142  const StateMatrix<Order, Dim, T> *sptr =
143  static_cast<const StateMatrix<Order, Dim, T> *>(this);
144  for (size_type i = 0; i != size_; ++i, ++first)
145  *first = sptr->state(i, pos);
146  }
147 
148  template <typename OutputIterIter>
149  void read_state_matrix(OutputIterIter first) const
150  {
151  for (std::size_t d = 0; d != this->dim(); ++d, ++first)
152  read_state(d, *first);
153  }
154 
155  template <MatrixOrder ROrder, typename OutputIter>
156  void read_state_matrix(OutputIter first) const
157  {
158  if (ROrder == Order) {
159  std::copy(data_.begin(), data_.end(), first);
160  } else {
161  const StateMatrix<Order, Dim, T> *sptr =
162  static_cast<const StateMatrix<Order, Dim, T> *>(this);
163  if (ROrder == RowMajor) {
164  for (size_type i = 0; i != size_; ++i)
165  for (std::size_t d = 0; d != this->dim(); ++d)
166  *first++ = sptr->state(i, d);
167  } else if (ROrder == ColMajor) {
168  for (std::size_t d = 0; d != this->dim(); ++d)
169  for (size_type i = 0; i != size_; ++i)
170  *first++ = sptr->state(i, d);
171  }
172  }
173  }
174 
175  template <typename CharT, typename Traits>
176  std::basic_ostream<CharT, Traits> &print(
177  std::basic_ostream<CharT, Traits> &os, char sepchar = '\t') const
178  {
179  if (this->dim() == 0 || size_ == 0 || !os.good())
180  return os;
181 
182  const StateMatrix<Order, Dim, T> *sptr =
183  static_cast<const StateMatrix<Order, Dim, T> *>(this);
184  for (size_type i = 0; i != size_; ++i) {
185  for (std::size_t d = 0; d != this->dim() - 1; ++d)
186  os << sptr->state(i, d) << sepchar;
187  os << sptr->state(i, this->dim() - 1) << '\n';
188  }
189 
190  return os;
191  }
192 
193  protected:
194  explicit StateMatrixBase(size_type N) : size_(N), data_(N * Dim) {}
195 
196  private:
197  size_type size_;
198  Vector<T> data_;
199 }; // class StateMatrixBase
200 
201 template <typename CharT, typename Traits, MatrixOrder Order, std::size_t Dim,
202  typename T>
203 inline std::basic_ostream<CharT, Traits> &operator<<(
204  std::basic_ostream<CharT, Traits> &os,
205  const StateMatrixBase<Order, Dim, T> &smatrix)
206 {
207  return smatrix.print(os);
208 }
209 
212 template <std::size_t Dim, typename T>
213 class StateMatrix<RowMajor, Dim, T> : public StateMatrixBase<RowMajor, Dim, T>
214 {
215  public:
220 
222 
223  T &state(size_type id, std::size_t pos)
224  {
225  return this->data()[id * this->dim() + pos];
226  }
227 
228  const T &state(size_type id, std::size_t pos) const
229  {
230  return this->data()[id * this->dim() + pos];
231  }
232 
233  using state_matrix_base_type::data;
234 
235  state_type *data(size_type id) { return row_data(id); }
236 
237  const state_type *data(size_type id) const { return row_data(id); }
238 
240  {
241  return this->data() + id * this->dim();
242  }
243 
244  const state_type *row_data(size_type id) const
245  {
246  return this->data() + id * this->dim();
247  }
248 
249  template <typename IntType>
250  void copy(size_type N, const IntType *src_idx)
251  {
253 
254  for (size_type dst = 0; dst != N; ++dst)
255  copy_particle(src_idx[dst], dst);
256  }
257 
259  {
260  if (src == dst)
261  return;
262 
263  copy_particle_dispatch(src, dst, std::integral_constant < bool,
264  Dim == Dynamic || 8 < Dim > ());
265  }
266 
268  {
269  state_pack_type pack(this->dim());
270  std::copy(row_data(id), row_data(id) + this->dim(), pack.data());
271 
272  return pack;
273  }
274 
275  void state_unpack(size_type id, const state_pack_type &pack)
276  {
278  pack.size(), this->dim());
279 
280  const state_type *ptr = pack.data();
281  std::copy(ptr, ptr + this->dim(), row_data(id));
282  }
283 
285  {
287  pack.size(), this->dim());
288 
289  const state_type *ptr = pack.data();
290  std::move(ptr, ptr + this->dim(), row_data(id));
291  }
292 
293  private:
294  void copy_particle_dispatch(size_type src, size_type dst, std::true_type)
295  {
296  std::copy(row_data(src), row_data(src) + this->dim(), row_data(dst));
297  }
298 
299  void copy_particle_dispatch(size_type src, size_type dst, std::false_type)
300  {
301  copy_particle_pos<0>(row_data(src), row_data(dst),
302  std::integral_constant<bool, 0 < Dim>());
303  }
304 
305  template <std::size_t D>
306  void copy_particle_pos(const state_type *, state_type *, std::false_type)
307  {
308  }
309 
310  template <std::size_t D>
311  void copy_particle_pos(
312  const state_type *src, state_type *dst, std::true_type)
313  {
314  dst[D] = src[D];
315  copy_particle_pos<D + 1>(
316  src, dst, std::integral_constant<bool, D + 1 < Dim>());
317  }
318 }; // class StateMatrix
319 
322 template <std::size_t Dim, typename T>
323 class StateMatrix<ColMajor, Dim, T> : public StateMatrixBase<ColMajor, Dim, T>
324 {
325  public:
330 
332 
333  T &state(size_type id, std::size_t pos)
334  {
335  return this->data()[pos * this->size() + id];
336  }
337 
338  const T &state(size_type id, std::size_t pos) const
339  {
340  return this->data()[pos * this->size() + id];
341  }
342 
343  using state_matrix_base_type::data;
344 
345  state_type *data(size_type pos) { return col_data(pos); }
346 
347  const state_type *data(size_type pos) const { return col_data(pos); }
348 
349  state_type *col_data(std::size_t pos)
350  {
351  return this->data() + pos * this->size();
352  }
353 
354  const state_type *col_data(std::size_t pos) const
355  {
356  return this->data() + pos * this->size();
357  }
358 
359  template <typename IntType>
360  void copy(size_type N, const IntType *src_idx)
361  {
363 
364  for (std::size_t d = 0; d != this->dim(); ++d)
365  for (size_type dst = 0; dst != N; ++dst)
366  state(dst, d) = state(static_cast<size_type>(src_idx[dst]), d);
367  }
368 
370  {
371  if (src == dst)
372  return;
373 
374  copy_particle_dispatch(src, dst, std::integral_constant < bool,
375  Dim == Dynamic || 8 < Dim > ());
376  }
377 
379  {
380  state_pack_type pack(this->dim());
381  for (std::size_t d = 0; d != this->dim(); ++d)
382  pack[d] = state(id, d);
383 
384  return pack;
385  }
386 
387  void state_unpack(size_type id, const state_pack_type &pack)
388  {
390  pack.size(), this->dim());
391 
392  for (std::size_t d = 0; d != this->dim(); ++d)
393  state(id, d) = pack[d];
394  }
395 
397  {
399  pack.size(), this->dim());
400 
401  for (std::size_t d = 0; d != this->dim(); ++d)
402  state(id, d) = std::move(pack[d]);
403  }
404 
405  private:
406  void copy_particle_dispatch(size_type src, size_type dst, std::true_type)
407  {
408  for (std::size_t d = 0; d != this->dim(); ++d)
409  state(dst, d) = state(src, d);
410  }
411 
412  void copy_particle_dispatch(size_type src, size_type dst, std::false_type)
413  {
414  copy_particle_pos<0>(this->data() + src, this->data() + dst,
415  std::integral_constant<bool, 0 < Dim>());
416  }
417 
418  template <std::size_t D>
419  void copy_particle_pos(const state_type *, state_type *, std::false_type)
420  {
421  }
422 
423  template <std::size_t D>
424  void copy_particle_pos(
425  const state_type *src, state_type *dst, std::true_type)
426  {
427  dst[D * this->size()] = src[D * this->size()];
428  copy_particle_pos<D + 1>(
429  src, dst, std::integral_constant<bool, D + 1 < Dim>());
430  }
431 }; // class StateMatrix
432 
433 } // namespace vsmc
434 
435 #endif // VSMC_CORE_STATE_MATRIX_HPP
T & state(size_type id, std::size_t pos)
Definition: monitor.hpp:49
Particle class representing the whole particle set.
Definition: particle.hpp:48
StateMatrixBase(size_type N)
state_type * row_data(size_type id)
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)
size_type size() const
const state_type * data() const
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_DIM_SIZE(dim)
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
Used to specify a dimension template parameter is dynamic.
Definition: defines.hpp:48
state_type & state(std::size_t pos) 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)
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, char sepchar= '\t') const
void state_unpack(size_type id, state_pack_type &&pack)
void copy(size_type N, const IntType *src_idx)
void copy(size_type N, const IntType *src_idx)
void copy_particle(size_type src, size_type dst)
void copy(std::size_t n, const T *x, std::size_t incx, T *y, std::size_t incy)
Copies vector to another vector.
Definition: cblas.hpp:82
typename state_matrix_base_type::state_pack_type state_pack_type
state_pack_type state_pack(size_type id) const
Data are stored column by column in memory.
Definition: defines.hpp:55
typename state_matrix_base_type::state_type state_type
#define VSMC_STATIC_ASSERT_CORE_STATE_MATRIX_DYNAMIC_DIM_RESIZE(Dim)
void resize_dim(std::size_t dim)
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
Data are stored row by row in memory.
Definition: defines.hpp:54
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Sampler< T > &sampler)
Definition: sampler.hpp:929
void swap(const MKLBase< MKLPtr, Derived > &ptr1, const MKLBase< MKLPtr, Derived > &ptr2)
Swap two MKLBase objects.
Definition: mkl.hpp:170
single_particle_type(typename Particle< S >::size_type id, Particle< S > *pptr)
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_COPY_SIZE_MISMATCH
const state_type * data(size_type pos) const
void swap(StateMatrixDim< Dim > &)
MatrixOrder
Matrix order.
Definition: defines.hpp:53
A thin wrapper over a complete Particle.
void read_state(std::size_t pos, OutputIter first) const
state_type * col_data(std::size_t pos)
typename state_matrix_base_type::state_type state_type
void swap(StateMatrixBase< Order, Dim, T > &other)
void read_state_matrix(OutputIterIter first) const
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 read_state_matrix(OutputIter first) const
void state_unpack(size_type id, const state_pack_type &pack)
typename state_matrix_base_type::size_type size_type