MCKL
Monte Carlo Kernel Library
state_matrix.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/core/state_matrix.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, 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 MCKL_CORE_STATE_MATRIX_HPP
33 #define MCKL_CORE_STATE_MATRIX_HPP
34 
35 #include <mckl/internal/common.hpp>
36 #include <mckl/core/matrix.hpp>
37 #include <mckl/core/particle.hpp>
38 
39 namespace mckl {
40 
52 template <MatrixLayout Layout, typename T, std::size_t Dim = 0>
53 class StateMatrix : public Matrix<T, Layout>
54 {
55  using layout_dispatch = std::integral_constant<MatrixLayout, Layout>;
56  using row_major = std::integral_constant<MatrixLayout, RowMajor>;
57  using col_major = std::integral_constant<MatrixLayout, ColMajor>;
58 
59  public:
65  using pointer = typename matrix_type::pointer;
66 
68  template <typename S>
70  {
71  public:
77 
78  particle_index_type() = default;
79 
81  typename Particle<S>::size_type i, Particle<S> *pptr)
82  : ParticleIndexBase<S>(i, pptr)
83  {
84  }
85 
87  iterator begin() const { return this->state().row_begin(this->i()); }
88 
91  {
92  return this->state().row_cbegin(this->i());
93  }
94 
96  iterator end() const { return this->state().row_end(this->i()); }
97 
100  {
101  return this->state().row_cend(this->i());
102  }
103 
106  {
107  return this->state().row_rbegin(this->i());
108  }
109 
112  {
113  return this->state().row_crbegin(this->i());
114  }
115 
118  {
119  return this->state().row_rend(this->i());
120  }
121 
124  {
125  return this->state().row_crend(this->i());
126  }
127 
130  {
131  return this->state().at(this->i(), j);
132  }
133 
136  {
137  return this->state()(this->i(), j);
138  }
139 
141  pointer data() const { return this->state().row_data(this->i()); }
142 
144  size_type stride() const { return this->state().row_stride(); }
145 
147  bool empty() const { return this->state().empty(); }
148 
150  size_type dim() const { return this->state().dim(); }
151  }; // class particle_index_type
152 
154  explicit StateMatrix(size_type N = 0) : matrix_type(N, Dim) {}
155 
158  {
159  static_assert(Dim == 0,
160  "**StateMatrix::StateMatrix** used with an object with fixed "
161  "dimension");
162  }
163 
165  size_type size() const { return this->nrow(); }
166 
168  size_type dim() const { return this->ncol(); }
169 
170  using matrix_type::reserve;
171 
173  void reserve(size_type N) { this->reserve(N, dim()); }
174 
175  using matrix_type::resize;
176 
178  void resize(size_type N) { this->resize(N, dim()); }
179 
193  template <typename InputIter>
194  void select(size_type n, InputIter index)
195  {
196  select_dispatch(n, index, layout_dispatch());
197  }
198 
208  {
209  if (src == dst) {
210  return;
211  }
212 
213  duplicate_dispatch(src, dst, layout_dispatch(),
214  std::integral_constant<bool, (Dim == 0 || 8 < Dim)>());
215  }
216 
217  private:
218  template <typename InputIter>
219  void select_dispatch(size_type n, InputIter index, row_major)
220  {
221  if (size() == 0 || internal::is_nullptr(index)) {
222  resize(n);
223  return;
224  }
225 
226  if (n > size()) {
227  resize(n);
228  }
229 
230  for (size_type dst = 0; dst != n; ++dst, ++index) {
231  duplicate(static_cast<size_type>(*index), dst);
232  }
233 
234  if (n < size()) {
235  resize(n);
236  }
237  }
238 
239  template <typename InputIter>
240  void select_dispatch(size_type n, InputIter index, col_major)
241  {
242  if (size() == 0 || internal::is_nullptr(index)) {
243  resize(n);
244  return;
245  }
246 
247  InputIter idx = index;
248  if (n == size()) {
249  for (size_type j = 0; j != dim(); ++j) {
250  idx = index;
251  const value_type *src = this->col_data(j);
252  value_type *dst = this->col_data(j);
253  for (size_type i = 0; i != n; ++i, ++idx) {
254  dst[i] = src[*idx];
255  }
256  }
257  } else {
258  Matrix<T, ColMajor> tmp(n, dim());
259  for (size_type j = 0; j != dim(); ++j) {
260  idx = index;
261  const value_type *src = this->col_data(j);
262  value_type *dst = tmp.col_data(j);
263  for (size_type i = 0; i != n; ++i, ++idx) {
264  dst[i] = src[*idx];
265  }
266  }
267  Matrix<T, ColMajor>::operator=(std::move(tmp));
268  }
269  }
270 
271  void duplicate_dispatch(
272  size_type src, size_type dst, row_major, std::true_type)
273  {
274  std::copy_n(this->row_data(src), dim(), this->row_data(dst));
275  }
276 
277  void duplicate_dispatch(
278  size_type src, size_type dst, row_major, std::false_type)
279  {
280  duplicate_j<0>(this->row_data(src), this->row_data(dst), row_major(),
281  std::integral_constant<bool, 0 < Dim>());
282  }
283 
284  template <std::size_t>
285  void duplicate_j(
286  const value_type *, value_type *, row_major, std::false_type)
287  {
288  }
289 
290  template <std::size_t D>
291  void duplicate_j(
292  const value_type *src, value_type *dst, row_major, std::true_type)
293  {
294  dst[D] = src[D];
295  duplicate_j<D + 1>(src, dst, row_major(),
296  std::integral_constant<bool, D + 1 < Dim>());
297  }
298 
299  void duplicate_dispatch(
300  size_type src, size_type dst, col_major, std::true_type)
301  {
302  for (size_type d = 0; d != dim(); ++d) {
303  this->operator()(dst, d) = this->operator()(src, d);
304  }
305  }
306 
307  void duplicate_dispatch(
308  size_type src, size_type dst, col_major, std::false_type)
309  {
310  duplicate_j<0>(this->row_data(src), this->col_data(dst), col_major(),
311  std::integral_constant<bool, 0 < Dim>());
312  }
313 
314  template <std::size_t>
315  void duplicate_j(
316  const value_type *, value_type *, col_major, std::false_type)
317  {
318  }
319 
320  template <std::size_t D>
321  void duplicate_j(
322  const value_type *src, value_type *dst, col_major, std::true_type)
323  {
324  dst[D * size()] = src[D * size()];
325  duplicate_j<D + 1>(
326  src, dst, std::integral_constant<bool, D + 1 < Dim>());
327  }
328 }; // class StateMatrix
329 
330 } // namespace mckl
331 
332 #endif // MCKL_CORE_STATE_MATRIX_HPP
iterator end() const
this->state().row_end(this->i())
std::conditional_t< Layout==RowMajor, const_pointer, StepIterator< const_pointer > > const_row_iterator
Definition: matrix.hpp:75
void resize(size_type N)
Matrix::resize(N, dim())
std::reverse_iterator< const_row_iterator > const_reverse_row_iterator
Definition: matrix.hpp:78
const_reverse_iterator crbegin() const
this->state().row_crbegin(this->i())
StateMatrix(size_type N=0)
Matrix::Matrix(N, Dim)
size_type ncol() const
The number of columns.
Definition: matrix.hpp:488
Particle< S >::size_type i() const
Definition: particle.hpp:66
void resize(size_type nrow, size_type ncol)
Resize the matrix.
Definition: matrix.hpp:506
bool empty() const
this->state().empty()
void select(size_type n, InputIter index)
Select samples in-place.
void duplicate(size_type src, size_type dst)
Duplicate a sample.
iterator begin() const
this->state().row_begin(this->i())
const_reverse_iterator crend() const
this->state().row_crend(this->i())
Matrix container.
Definition: matrix.hpp:49
reference at(size_type j) const
this->state().at(this->i(), j)
void reserve(size_type N)
Matrix::reserve(N, dim())
typename matrix_type::reverse_row_iterator reverse_iterator
value_type * pointer
Definition: matrix.hpp:64
typename matrix_type::reference reference
std::reverse_iterator< row_iterator > reverse_row_iterator
Definition: matrix.hpp:76
pointer row_data(size_type i)
Pointer to the first element of a row.
Definition: matrix.hpp:443
std::size_t size_type
Definition: matrix.hpp:60
pointer col_data(size_type j)
Pointer to the beginning of a column.
Definition: matrix.hpp:461
ParticleIndex base class.
size_type size() const
Matrix::nrow()
const_iterator cend() const
this->state().row_cend(this->i())
bool is_nullptr(T ptr, std::true_type)
Definition: assert.hpp:144
typename matrix_type::const_reverse_row_iterator const_reverse_iterator
typename matrix_type::row_iterator iterator
typename matrix_type::size_type size_type
particle_index_type(typename Particle< S >::size_type i, Particle< S > *pptr)
size_type dim() const
this->state().dim()
const_iterator cbegin() const
this->state().row_cbegin(this->i())
reference operator()(size_type j) const
this->state()(this->i(), j)
value_type & reference
Definition: matrix.hpp:62
reverse_iterator rend() const
this->state().row_rend(this->i())
size_type stride() const
this->state().row_stride()
Particle::state_type subtype.
typename matrix_type::pointer pointer
typename matrix_type::const_row_iterator const_iterator
pointer data() const
this->state().row_data(this->i())
Definition: mcmc.hpp:40
size_type dim() const
Matrix::ncol()
StateMatrix(size_type N, size_type dim)
Matrix::Matrix(N, dim)
void reserve(size_type n, size_type m)
Reserve storage space for the matrix.
Definition: matrix.hpp:497
size_type nrow() const
The number of rows.
Definition: matrix.hpp:485
reverse_iterator rbegin() const
this->state().row_rbegin(this->i())
std::ptrdiff_t difference_type
Definition: matrix.hpp:61
std::conditional_t< Layout==RowMajor, pointer, StepIterator< pointer > > row_iterator
Definition: matrix.hpp:73
Particle system.
Definition: particle.hpp:45
Matrix & operator=(const Matrix &)=default
Copy assignment operator.
A thin wrapper over a complete Particle.
Definition: particle.hpp:50
typename matrix_type::difference_type difference_type
typename matrix_type::value_type value_type