vSMC  v3.0.0
Scalable Monte Carlo
particle.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/core/particle.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_PARTICLE_HPP
33 #define VSMC_CORE_PARTICLE_HPP
34 
35 #include <vsmc/internal/common.hpp>
37 #include <vsmc/core/weight.hpp>
39 #include <vsmc/rng/rng_set.hpp>
40 #include <vsmc/rng/seed.hpp>
41 
42 #define VSMC_RUNTIME_ASSERT_CORE_PARTICLE_RESIZE_BY_RANGE \
43  VSMC_RUNTIME_ASSERT( \
44  (!internal::is_negative(first) && first < last && last <= size_), \
45  "**Particle::resize_by_range** INDICES OUT OF RANGE")
46 
47 namespace vsmc
48 {
49 
52 template <typename T>
54 {
55  public:
57  typename Particle<T>::size_type end, Particle<T> *pptr)
58  : pptr_(pptr), begin_(begin), end_(end)
59  {
60  }
61 
62  Particle<T> &particle() const { return *pptr_; }
63 
64  Particle<T> *particle_ptr() const { return pptr_; }
65 
66  typename Particle<T>::size_type size() const { return end_ - begin_; }
67 
68  typename Particle<T>::size_type begin() const { return begin_; }
69 
70  typename Particle<T>::size_type end() const { return end_; }
71 
72  typename Particle<T>::rng_type &rng() const { return pptr_->rng(begin_); }
73 
74  private:
75  Particle<T> *pptr_;
76  typename Particle<T>::size_type begin_;
77  typename Particle<T>::size_type end_;
78 }; // class ParticleRange
79 
82 template <typename T>
83 class Particle
84 {
85  public:
87  using state_type = T;
90  using rng_type = typename rng_set_type::rng_type;
93 
94  Particle() : size_(0), state_(0), weight_(0), rng_set_(0)
95  {
96  Seed::instance()(rng_);
97  }
98 
99  template <typename... Args>
100  explicit Particle(size_type N, Args &&... args)
101  : size_(N)
102  , state_(N, std::forward<Args>(args)...)
103  , weight_(static_cast<SizeType<weight_type>>(N))
104  , rng_set_(static_cast<SizeType<rng_set_type>>(N))
105  {
106  Seed::instance()(rng_);
107  }
108 
111  {
112  Particle<T> particle(*this);
113  particle.rng_set_.seed();
114  Seed::instance()(particle.rng_);
115 
116  return particle;
117  }
118 
120  size_type size() const { return size_; }
121 
126  template <typename InputIter>
127  void resize_by_index(size_type N, InputIter index)
128  {
129  resize_by_index(
130  N, index, std::is_convertible<InputIter, const size_type *>());
131  }
132 
141  template <typename ResampleType>
143  {
144  Vector<size_type> rep(static_cast<std::size_t>(size_));
145  Vector<size_type> idx(static_cast<std::size_t>(N));
146  op(static_cast<std::size_t>(size_), static_cast<std::size_t>(N), rng_,
147  weight_.data(), rep.data());
148  resample_trans_rep_index(static_cast<std::size_t>(size_),
149  static_cast<std::size_t>(N), rep.data(), idx.data());
150  resize(N, idx.data());
151  }
152 
162  {
163  weight_.set_equal();
164  resize_by_resample(N, ResampleMultinomial());
165  }
166 
168  state_type &state() { return state_; }
169 
171  const state_type &state() const { return state_; }
172 
174  weight_type &weight() { return weight_; }
175 
177  const weight_type &weight() const { return weight_; }
178 
180  rng_set_type &rng_set() { return rng_set_; }
181 
183  const rng_set_type &rng_set() const { return rng_set_; }
184 
187  {
188  return rng_set_[static_cast<std::size_t>(id)];
189  }
190 
192  const rng_type &rng(size_type id) const
193  {
194  return rng_set_[static_cast<std::size_t>(id)];
195  }
196 
198  rng_type &rng() { return rng_; }
199 
201  const rng_type &rng() const { return rng_; }
202 
204  sp_type sp(size_type id) { return SingleParticle<T>(id, this); }
205 
208  {
209  return ParticleRange<T>(begin, end, this);
210  }
211 
213  range_type range() { return ParticleRange<T>(0, size(), this); }
214 
216  sp_type begin() { return sp(0); }
217 
219  sp_type end() { return sp(size_); }
220 
221  private:
222  static constexpr std::size_t M_ = internal::BufferSize<size_type>::value;
223 
224  size_type size_;
225  state_type state_;
226  weight_type weight_;
227  rng_set_type rng_set_;
228  rng_type rng_;
229 
230  void resize(size_type N, const size_type *idx)
231  {
232  size_ = N;
233  state_.select(N, idx);
234  weight_.resize(static_cast<SizeType<weight_type>>(N));
235  rng_set_.resize(static_cast<SizeType<rng_set_type>>(N));
236  }
237 
238  template <typename InputIter>
239  void resize_by_index(size_type N, InputIter index, std::true_type)
240  {
241  resize(N, static_cast<const size_type *>(index));
242  }
243 
244  template <typename InputIter>
245  void resize_by_index(size_type N, InputIter index, std::false_type)
246  {
247  Vector<size_type> idx(static_cast<std::size_t>(N));
248  std::copy_n(index, N, idx.data());
249  resize(N, idx.data());
250  }
251 
252  template <typename InputIter, typename OutputIter>
253  void resize_copy_index(
254  std::size_t N, std::size_t M, InputIter src, OutputIter dst)
255  {
256  while (N > M) {
257  dst = std::copy_n(src, M, dst);
258  N -= M;
259  }
260  std::copy_n(src, N, dst);
261  }
262 }; // class Particle
263 
264 } // namespace vsmc
265 
266 #endif // VSMC_CORE_PARTICLE_HPP
std::vector< T, Alloc > Vector
std::vector with Allocator as default allocator
ResampleAlgorithm< U01SequenceSorted, false > ResampleMultinomial
Multinomial resampling.
Definition: algorithm.hpp:161
range_type range(size_type begin, size_type end)
Get a ParticleRange<T> object.
Definition: particle.hpp:207
static SeedGenerator< ID, ResultType > & instance()
Definition: seed.hpp:82
Definition: monitor.hpp:48
SizeType< T > size_type
Definition: particle.hpp:86
Particle class representing the whole particle set.
Definition: particle.hpp:83
sp_type sp(size_type id)
Get a SingleParticle<T> object.
Definition: particle.hpp:204
typename rng_set_type::rng_type rng_type
Definition: particle.hpp:90
typename RNGSetTypeTrait< T >::type RNGSetType
Definition: rng_set.hpp:161
const rng_type & rng(size_type id) const
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:192
state_type & state()
Read and write access to the state collection object.
Definition: particle.hpp:168
OutputIter resample_trans_rep_index(std::size_t N, std::size_t M, InputIter replication, OutputIter index)
Transform replication numbers into parent indices.
Definition: transform.hpp:130
range_type range()
Get a ParticleRange<T> object with begin == 0, end == size()
Definition: particle.hpp:213
sp_type end()
Get a SingleParticle<T> object for the first particle.
Definition: particle.hpp:219
void resize_by_index(size_type N, InputIter index)
Resize by selecting according to user supplied index vector.
Definition: particle.hpp:127
const rng_type & rng() const
Get the (sequential) RNG used stream for resampling.
Definition: particle.hpp:201
weight_type & weight()
Read and write access to the weight collection object.
Definition: particle.hpp:174
STL namespace.
const weight_type & weight() const
Read only access to the weight collection object.
Definition: particle.hpp:177
ParticleRange(typename Particle< T >::size_type begin, typename Particle< T >::size_type end, Particle< T > *pptr)
Definition: particle.hpp:56
Particle< T > * particle_ptr() const
Definition: particle.hpp:64
void resize_by_resample(size_type N, ResampleType &&op)
Resize by resampling.
Definition: particle.hpp:142
Particle< T > clone() const
Clone the Particle except the RNG engines.
Definition: particle.hpp:110
const state_type & state() const
Read only access to the state collection object.
Definition: particle.hpp:171
Particle< T >::rng_type & rng() const
Definition: particle.hpp:72
Particle(size_type N, Args &&...args)
Definition: particle.hpp:100
rng_type & rng(size_type id)
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:186
A subset of particles.
Definition: particle.hpp:53
Particle< T >::size_type size() const
Definition: particle.hpp:66
rng_set_type & rng_set()
Read and write access to the RNG collection object.
Definition: particle.hpp:180
typename SizeTypeTrait< T >::type SizeType
Definition: traits.hpp:212
typename WeightTypeTrait< T >::type WeightType
Definition: weight.hpp:360
size_type size() const
Number of particles.
Definition: particle.hpp:120
void resize_by_uniform(size_type N)
Resize by uniformly selecting from all particles.
Definition: particle.hpp:161
Particle< T > & particle() const
Definition: particle.hpp:62
Particle< T >::size_type begin() const
Definition: particle.hpp:68
sp_type begin()
Get a SingleParticle<T> object for the first particle.
Definition: particle.hpp:216
A thin wrapper over a complete Particle.
rng_type & rng()
Get the (sequential) RNG used stream for resampling.
Definition: particle.hpp:198
typename ResampleTypeTrait< Scheme >::type ResampleType
Type of resample class corresponding to ResampleScheme parameter.
Definition: algorithm.hpp:247
Particle< T >::size_type end() const
Definition: particle.hpp:70
const rng_set_type & rng_set() const
Read only access to the RNG collection object.
Definition: particle.hpp:183