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,2014, 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>
38 #include <vsmc/utility/array.hpp>
39 
40 #define VSMC_STATIC_ASSERT_CORE_STATE_MATRIX_DYNAMIC_DIM_RESIZE(Dim) \
41  VSMC_STATIC_ASSERT((Dim == Dynamic), \
42  USE_METHOD_resize_dim_WITH_A_FIXED_SIZE_StateMatrix_OBJECT)
43 
44 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_COPY_SIZE_MISMATCH \
45  VSMC_RUNTIME_ASSERT((N == static_cast<size_type>(this->size())), \
46  ("**StateMatrix::copy** SIZE MISMATCH"))
47 
48 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_DIM_SIZE(dim) \
49  VSMC_RUNTIME_ASSERT((dim >= 1), \
50  ("**StateMatrix** DIMENSION IS LESS THAN 1"))
51 
52 #define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_UNPACK_SIZE(psize, dim) \
53  VSMC_RUNTIME_ASSERT((psize >= dim), \
54  ("**StateMatrix::state_unpack** INPUT PACK SIZE TOO SMALL"))
55 
56 namespace vsmc {
57 
60 template <MatrixOrder Order, std::size_t Dim, typename T>
61 class StateMatrixBase : public traits::DimTrait<Dim>
62 {
63  public :
64 
65  typedef std::size_t size_type;
66  typedef T state_type;
67  typedef typename cxx11::conditional<Dim == Dynamic,
69 
70  template <typename S>
72  {
75  SingleParticleBase<S>(id, particle_ptr) {}
76 
77  std::size_t dim () const {return this->particle_ptr()->value().dim();}
78 
79  state_type &state (std::size_t pos) const
80  {return this->mutable_particle_ptr()->value().state(this->id(), pos);}
81 
82  template <std::size_t Pos>
83  state_type &state (Position<Pos>) const
84  {return this->state(Pos);}
85 
86  template <std::size_t Pos>
87  state_type &state () const
88  {return this->state(Pos);}
89  }; // struct single_particle_type
90 
91  template <typename S>
93  {
95  const Particle<S> *particle_ptr) :
96  ConstSingleParticleBase<S>(id, particle_ptr) {}
97 
98  std::size_t dim () const {return this->particle_ptr()->value().dim();}
99 
100  const state_type &state (std::size_t pos) const
101  {return this->particle_ptr()->value().state(this->id(), pos);}
102 
103  template <std::size_t Pos>
104  const state_type &state (Position<Pos>) const
105  {return this->state(Pos);}
106 
107  template <std::size_t Pos>
108  const state_type &state () const
109  {return this->state(Pos);}
110  }; // struct const_single_particle_type
111 
112  void resize_dim (std::size_t dim)
113  {
116 
118  data_.resize(size_ * dim);
119  }
120 
121  size_type size () const {return size_;}
122 
123  state_type &operator() (std::size_t i, std::size_t pos)
124  {
125  return static_cast<StateMatrix<Order, Dim, T> *>(this)->
126  state(i, pos);
127  }
128 
129  const state_type &operator() (std::size_t i, std::size_t pos) const
130  {
131  return static_cast<const StateMatrix<Order, Dim, T> *>(this)->
132  state(i, pos);
133  }
134 
135  T *data () {return &data_[0];}
136 
137  const T *data () const {return &data_[0];}
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 <std::size_t Pos, typename OutputIter>
149  void read_state (Position<Pos>, OutputIter first) const
150  {read_state(Pos, first);}
151 
152  template <std::size_t Pos, typename OutputIter>
153  void read_state (OutputIter first) const
154  {read_state(Pos, first);}
155 
156  template <typename OutputIterIter>
157  void read_state_matrix (OutputIterIter first) const
158  {
159  for (std::size_t d = 0; d != this->dim(); ++d, ++first)
160  read_state(d, *first);
161  }
162 
163  template <MatrixOrder ROrder, typename OutputIter>
164  void read_state_matrix (OutputIter first) const
165  {
166  if (ROrder == Order) {
167  std::copy(data_.begin(), data_.end(), first);
168  } else {
169  const StateMatrix<Order, Dim, T> *sptr =
170  static_cast<const StateMatrix<Order, Dim, T> *>(this);
171  if (ROrder == RowMajor) {
172  for (size_type i = 0; i != size_; ++i) {
173  for (std::size_t d = 0; d != this->dim(); ++d) {
174  *first = sptr->state(i, d);
175  ++first;
176  }
177  }
178  } else if (ROrder == ColMajor) {
179  for (std::size_t d = 0; d != this->dim(); ++d) {
180  for (size_type i = 0; i != size_; ++i) {
181  *first = sptr->state(i, d);
182  ++first;
183  }
184  }
185  }
186  }
187  }
188 
189  template <typename CharT, typename Traits>
190  std::basic_ostream<CharT, Traits> &print (
191  std::basic_ostream<CharT, Traits> &os, char sepchar = '\t') const
192  {
193  if (this->dim() == 0 || size_ == 0 || !os.good())
194  return os;
195 
196  const StateMatrix<Order, Dim, T> *sptr =
197  static_cast<const StateMatrix<Order, Dim, T> *>(this);
198  for (size_type i = 0; i != size_; ++i) {
199  for (std::size_t d = 0; d != this->dim() - 1; ++d)
200  os << sptr->state(i, d) << sepchar;
201  os << sptr->state(i, this->dim() - 1) << '\n';
202  }
203 
204  return os;
205  }
206 
207  protected :
208 
209  explicit StateMatrixBase (size_type N) : size_(N), data_(N * Dim) {}
210 
211  state_pack_type create_pack () const
212  {
213  return create_pack_dispatch(
215  }
216 
217  private :
218 
219  size_type size_;
221  std::vector<T, AlignedAllocator<T> >,
222  std::vector<T> >::type data_;
223 
224  private :
225 
226  std::vector<T> create_pack_dispatch (cxx11::true_type) const
227  {return std::vector<T>(this->dim());}
228 
229  Array<T, Dim> create_pack_dispatch (cxx11::false_type) const
230  {return Array<T, Dim>();}
231 }; // class StateMatrixBase
232 
233 template <typename CharT, typename Traits,
234  MatrixOrder Order, std::size_t Dim, typename T>
235 inline std::basic_ostream<CharT, Traits> &operator<< (
236  std::basic_ostream<CharT, Traits> &os,
237  const StateMatrixBase<Order, Dim, T> &smatrix)
238 {return smatrix.print(os);}
239 
242 template <std::size_t Dim, typename T>
243 class StateMatrix<RowMajor, Dim, T> : public StateMatrixBase<RowMajor, Dim, T>
244 {
245  public :
246 
250 
251  explicit StateMatrix (size_type N) : state_matrix_base_type(N) {}
252 
253  T &state (size_type id, std::size_t pos)
254  {return this->data()[id * this->dim() + pos];}
255 
256  const T &state (size_type id, std::size_t pos) const
257  {return this->data()[id * this->dim() + pos];}
258 
259  template <std::size_t Pos>
260  T &state (size_type id, Position<Pos>)
261  {return state(id, Pos);}
262 
263  template <std::size_t Pos>
264  const T &state (size_type id, Position<Pos>) const
265  {return state(id, Pos);}
266 
267  template <std::size_t Pos>
268  T &state (size_type id)
269  {return state(id, Pos);}
270 
271  template <std::size_t Pos>
272  const T &state (size_type id) const
273  {return state(id, Pos);}
274 
275  T *row_data (size_type id)
276  {return this->data() + id * this->dim();}
277 
278  const T *row_data (size_type id) const
279  {return this->data() + id * this->dim();}
280 
281  template <typename IntType>
282  void copy (size_type N, const IntType *copy_from)
283  {
285 
286  for (size_type to = 0; to != N; ++to)
287  copy_particle(copy_from[to], to);
288  }
289 
290  void copy_particle (size_type from, size_type to)
291  {
292  if (from == to)
293  return;
294 
295  std::copy(row_data(from), row_data(from + 1), row_data(to));
296  }
297 
298  state_pack_type state_pack (size_type id) const
299  {
300  state_pack_type pack(this->create_pack());
301  std::copy(row_data(id), row_data(id + 1), &pack[0]);
302 
303  return pack;
304  }
305 
306  void state_unpack (size_type id, const state_pack_type &pack)
307  {
309  pack.size(), this->dim());
310 
311  const T *ptr = &pack[0];
312  std::copy(ptr, ptr + this->dim(), row_data(id));
313  }
314 
315 #if VSMC_HAS_CXX11_RVALUE_REFERENCES && VSMC_HAS_CXX11LIB_ALGORITHM
316  void state_unpack (size_type id, state_pack_type &&pack)
317  {
319  pack.size(), this->dim());
320 
321  const T *ptr = &pack[0];
322  std::move(ptr, ptr + this->dim(), row_data(id));
323  }
324 #endif
325 }; // class StateMatrix
326 
329 template <std::size_t Dim, typename T>
330 class StateMatrix<ColMajor, Dim, T> : public StateMatrixBase<ColMajor, Dim, T>
331 {
332  public :
333 
337 
338  explicit StateMatrix (size_type N) : state_matrix_base_type(N) {}
339 
340  T &state (size_type id, std::size_t pos)
341  {return this->data()[pos * this->size() + id];}
342 
343  const T &state (size_type id, std::size_t pos) const
344  {return this->data()[pos * this->size() + id];}
345 
346  template <std::size_t Pos>
347  T &state (size_type id, Position<Pos>)
348  {return state(id, Pos);}
349 
350  template <std::size_t Pos>
351  const T &state (size_type id, Position<Pos>) const
352  {return state(id, Pos);}
353 
354  template <std::size_t Pos>
355  T &state (size_type id)
356  {return state(id, Pos);}
357 
358  template <std::size_t Pos>
359  const T &state (size_type id) const
360  {return state(id, Pos);}
361 
362  T *col_data (std::size_t pos)
363  {return this->data() + pos * this->size();}
364 
365  const T *col_data (std::size_t pos) const
366  {return this->data() + pos * this->size();}
367 
368  template <typename IntType>
369  void copy (size_type N, const IntType *copy_from)
370  {
372 
373  for (size_type to = 0; to != N; ++to)
374  copy_particle(copy_from[to], to);
375  }
376 
377  void copy_particle (size_type from, size_type to)
378  {
379  if (from == to)
380  return;
381 
382  for (std::size_t d = 0; d != this->dim(); ++d)
383  state(to, d) = state(from, d);
384  }
385 
386  state_pack_type state_pack (size_type id) const
387  {
388  state_pack_type pack(this->create_pack());
389  for (std::size_t d = 0; d != this->dim(); ++d)
390  pack[d] = state(id, d);
391 
392  return pack;
393  }
394 
395  void state_unpack (size_type id, const state_pack_type &pack)
396  {
398  pack.size(), this->dim());
399 
400  for (std::size_t d = 0; d != this->dim(); ++d)
401  state(id, d) = pack[d];
402  }
403 
404 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
405  void state_unpack (size_type id, state_pack_type &&pack)
406  {
408  pack.size(), this->dim());
409 
410  for (std::size_t d = 0; d != this->dim(); ++d)
411  state(id, d) = cxx11::move(pack[d]);
412  }
413 #endif
414 }; // class StateMatrix
415 
416 } // namespace vsmc
417 
418 #endif // VSMC_CORE_STATE_MATRIX_HPP
const Particle< S > * particle_ptr() const
T & state(size_type id, std::size_t pos)
Definition: adapter.hpp:37
Particle class representing the whole particle set.
Definition: particle.hpp:48
StateMatrixBase(size_type N)
Particle< S > * mutable_particle_ptr() const
Base type of StateTuple.
state_matrix_base_type::state_pack_type state_pack_type
void state_unpack(size_type id, const state_pack_type &pack)
size_type size() const
state_type & state(std::size_t pos) const
const T & state(size_type id, std::size_t pos) const
const T & state(size_type id, std::size_t pos) const
StateMatrixBase< RowMajor, Dim, T > state_matrix_base_type
state_pack_type create_pack() const
value_type & value()
Read and write access to the value collection object.
Definition: particle.hpp:149
const T * data() const
const T & state(size_type id) const
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_UNPACK_SIZE(psize, dim)
void copy_particle(size_type from, size_type to)
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, char sepchar= '\t') const
state_matrix_base_type::size_type size_type
StateMatrixBase< ColMajor, Dim, T > state_matrix_base_type
static constexpr std::size_t dim()
Definition: traits.hpp:214
integral_constant< bool, false > false_type
Function template argument used for position.
Definition: defines.hpp:126
state_pack_type state_pack(size_type id) const
void read_state(OutputIter first) const
Data are stored column by column in memory.
Definition: defines.hpp:104
state_type & operator()(std::size_t i, std::size_t pos)
void resize_dim(std::size_t dim)
Used to specify a dimension template parameter is dynamic.
Definition: defines.hpp:97
void state_unpack(size_type id, state_pack_type &&pack)
state_pack_type state_pack(size_type id) const
Dimension trait for StateMatrix and StateCL (fixed dimension)
Definition: traits.hpp:214
state_matrix_base_type::size_type size_type
const state_type & state(Position< Pos >) const
cxx11::conditional< Dim==Dynamic, std::vector< T >, Array< T, Dim > >::type state_pack_type
Data are stored row by row in memory.
Definition: defines.hpp:103
remove_reference< T >::type && move(T &&t) noexcept
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Sampler< T > &sampler)
Definition: sampler.hpp:884
A const variant to SingleParticle.
state_type & state(Position< Pos >) const
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_COPY_SIZE_MISMATCH
const_single_particle_type(typename Particle< S >::size_type id, const Particle< S > *particle_ptr)
const T & state(size_type id, Position< Pos >) const
const T * row_data(size_type id) const
MatrixOrder
Matrix order.
Definition: defines.hpp:102
A thin wrapper over a complete Particle.
T & state(size_type id, Position< Pos >)
#define VSMC_RUNTIME_ASSERT_CORE_STATE_MATRIX_DIM_SIZE(dim)
void read_state(std::size_t pos, OutputIter first) const
void copy_particle(size_type from, size_type to)
T & state(size_type id, Position< Pos >)
void copy(size_type N, const IntType *copy_from)
void read_state_matrix(OutputIterIter first) const
const T & state(size_type id, Position< Pos >) const
single_particle_type(typename Particle< S >::size_type id, Particle< S > *particle_ptr)
const Particle< S > * particle_ptr() const
const T * col_data(std::size_t pos) const
T & state(size_type id, std::size_t pos)
Static array.
Definition: array.hpp:79
void copy(size_type N, const IntType *copy_from)
void read_state(Position< Pos >, OutputIter first) const
void read_state_matrix(OutputIter first) const
state_matrix_base_type::state_pack_type state_pack_type
const T & state(size_type id) const
void state_unpack(size_type id, const state_pack_type &pack)
#define VSMC_STATIC_ASSERT_CORE_STATE_MATRIX_DYNAMIC_DIM_RESIZE(Dim)
static constexpr size_type size()
Definition: array.hpp:161
const state_type & state(std::size_t pos) const