vSMC
vSMC: 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,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_PARTICLE_HPP
33 #define VSMC_CORE_PARTICLE_HPP
34 
35 #include <vsmc/internal/common.hpp>
37 #include <vsmc/core/weight_set.hpp>
39 #include <vsmc/rng/rng_set.hpp>
40 #include <vsmc/rng/seed.hpp>
42 
43 namespace vsmc {
44 
47 template <typename T>
48 class Particle
49 {
50  public :
51 
53  typedef T value_type;
57  typedef typename rng_set_type::rng_type rng_type;
60 
61  typedef cxx11::function<void (std::size_t, std::size_t,
62  resample_rng_type &, const double *, size_type *)> resample_type;
67 
68  explicit Particle (size_type N) :
69  size_(N), value_(N),
70  weight_set_(static_cast<typename
71  traits::SizeTypeTrait<weight_set_type>::type>(N)),
72  rng_set_(static_cast<typename
73  traits::SizeTypeTrait<rng_set_type>::type>(N)),
74  resample_rng_(Seed::instance().get()) {}
75 
80  Particle<T> clone (bool new_rng) const
81  {
82  Particle<T> particle(*this);
83  if (new_rng) {
84  particle.rng_set().seed();
85  particle.resample_rng().seed(Seed::instance().get());
86  }
87 
88  return particle;
89  }
90 
96  Particle<T> &clone (const Particle<T> &other, bool retain_rng)
97  {
98  if (this != &other) {
99  if (retain_rng) {
100 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
101  rng_set_type rset(cxx11::move(rng_set_));
102  resample_rng_type rrng(cxx11::move(resample_rng_));
103  *this = other;
104  rng_set_ = cxx11::move(rset);
105  resample_rng_ = cxx11::move(rrng);
106 #else
107  using std::swap;
108 
109  rng_set_type rset(0);
110  swap(rset, rng_set_);
111  resample_rng_type rrng(resample_rng_);
112  *this = other;
113  swap(rset, rng_set_);
114  resample_rng_ = rrng;
115 #endif
116  rng_set_.resize(other.size());
117  } else {
118  *this = other;
119  }
120  }
121 
122  return *this;
123  }
124 
125 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
126  Particle<T> &clone (Particle<T> &&other, bool retain_rng)
127  {
128  if (this != &other) {
129  if (retain_rng) {
130  rng_set_type rset(cxx11::move(rng_set_));
131  resample_rng_type rrng(cxx11::move(resample_rng_));
132  *this = cxx11::move(other);
133  rng_set_ = cxx11::move(rset);
134  resample_rng_ = cxx11::move(rrng);
135  rng_set_.resize(other.size());
136  } else {
137  *this = cxx11::move(other);
138  }
139  }
140 
141  return *this;
142  }
143 #endif
144 
146  size_type size () const {return size_;}
147 
149  value_type &value () {return value_;}
150 
152  const value_type &value () const {return value_;}
153 
155  weight_set_type &weight_set () {return weight_set_;}
156 
158  const weight_set_type &weight_set () const {return weight_set_;}
159 
161  rng_set_type &rng_set () {return rng_set_;}
162 
164  const rng_set_type &rng_set () const {return rng_set_;}
165 
167  rng_type &rng (size_type id) {return rng_set_[id];}
168 
170  sp_type sp (size_type id) {return sp_type(id, this);}
171 
173  csp_type sp (size_type id) const {return csp_type(id, this);}
174 
176  csp_type csp (size_type id) {return csp_type(id, this);}
177 
179  csp_type csp (size_type id) const {return csp_type(id, this);}
180 
182  resample_rng_type &resample_rng () {return resample_rng_;}
183 
234  bool resample (const resample_type &op, double threshold)
235  {
236  std::size_t N = static_cast<std::size_t>(weight_set_.resample_size());
237  bool resampled = weight_set_.ess() < threshold * N;
238  if (resampled) {
239  size_type *cptr = VSMC_NULLPTR;
240  const double *wptr = weight_set_.resample_weight_data();
241  if (wptr != VSMC_NULLPTR) {
242  resample_copy_from_.resize(N);
243  resample_replication_.resize(N);
244  cptr = &resample_copy_from_[0];
245  size_type *rptr = &resample_replication_[0];
246  op(N, N, resample_rng_, wptr, rptr);
247  resample_copy_from_replication_(N, N, rptr, cptr);
248  }
249  value_.copy(N, cptr);
250  resample_post_copy_(weight_set_);
251  }
252 
253  return resampled;
254  }
255 
256  private :
257 
258  size_type size_;
259  value_type value_;
260  weight_set_type weight_set_;
261  rng_set_type rng_set_;
262  resample_rng_type resample_rng_;
263 
264  std::vector<size_type, AlignedAllocator<size_type> > resample_copy_from_;
265  std::vector<size_type, AlignedAllocator<size_type> > resample_replication_;
266  resample_copy_from_replication_type resample_copy_from_replication_;
267  resample_post_copy_type resample_post_copy_;
268 }; // class Particle
269 
270 } // namespace vsmc
271 
272 #endif // VSMC_CORE_PARTICLE_HPP
static SeedGenerator< ID, ResultType > & instance()
Definition: seed.hpp:94
Definition: adapter.hpp:37
Particle class representing the whole particle set.
Definition: particle.hpp:48
sp_type sp(size_type id)
Get a SingleParticle.
Definition: particle.hpp:170
internal::RngSetTypeDispatch< T, value >::type type
Definition: rng_set.hpp:128
ConstSingleParticle< T > csp_type
Definition: particle.hpp:59
csp_type sp(size_type id) const
Get a ConstSingleParticle.
Definition: particle.hpp:173
Particle< T > clone(bool new_rng) const
Clone the particle system except the RNG engines.
Definition: particle.hpp:80
value_type & value()
Read and write access to the value collection object.
Definition: particle.hpp:149
traits::RngSetTypeTrait< T >::type rng_set_type
Definition: particle.hpp:55
traits::ResampleRngTypeTrait< T >::type resample_rng_type
Definition: particle.hpp:56
traits::ResamplePostCopyTypeTrait< T >::type resample_post_copy_type
Definition: particle.hpp:66
const weight_set_type & weight_set() const
Read only access to the weight collection object.
Definition: particle.hpp:158
internal::ResampleRngTypeDispatch< T, value >::type type
Definition: common.hpp:193
Particle(size_type N)
Definition: particle.hpp:68
cxx11::function< void(std::size_t, std::size_t, resample_rng_type &, const double *, size_type *)> resample_type
Definition: particle.hpp:62
const value_type & value() const
Read only access to the value collection object.
Definition: particle.hpp:152
Particle< T > & clone(const Particle< T > &other, bool retain_rng)
Clone another particle system except the RNG engines.
Definition: particle.hpp:96
bool resample(const resample_type &op, double threshold)
Performing resampling if ESS/N < threshold.
Definition: particle.hpp:234
SingleParticle< T > sp_type
Definition: particle.hpp:58
traits::ResampleCopyFromReplicationTypeTrait< T >::type resample_copy_from_replication_type
Definition: particle.hpp:64
T & get(Array< T, N > &ary)
Array ADL of get.
Definition: array.hpp:322
csp_type csp(size_type id)
Get a ConstSingleParticle.
Definition: particle.hpp:176
rng_set_type::rng_type rng_type
Definition: particle.hpp:57
internal::WeightSetTypeDispatch< T, value >::type type
Definition: traits.hpp:152
Particle< T > & clone(Particle< T > &&other, bool retain_rng)
Definition: particle.hpp:126
internal::ResamplePostCopyTypeDispatch< T, value >::type type
Definition: common.hpp:203
remove_reference< T >::type && move(T &&t) noexcept
resample_rng_type & resample_rng()
Get the (sequential) RNG used stream for resampling.
Definition: particle.hpp:182
rng_type & rng(size_type id)
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:167
#define VSMC_NULLPTR
nullptr
Definition: defines.hpp:79
void swap(Array< T, N > &ary1, Array< T, N > &ary2)
Array ADL of swap.
Definition: array.hpp:317
rng_set_type & rng_set()
Read and write access to the RNG collection object.
Definition: particle.hpp:161
Seed generator.
Definition: seed.hpp:87
traits::SizeTypeTrait< T >::type size_type
Definition: particle.hpp:52
internal::SizeTypeDispatch< T, value >::type type
Definition: traits.hpp:148
internal::ResampleCopyFromReplicationTypeDispatch< T, value >::type type
Definition: common.hpp:198
traits::WeightSetTypeTrait< T >::type weight_set_type
Definition: particle.hpp:54
size_type size() const
Number of particles.
Definition: particle.hpp:146
A thin wrapper over a complete Particle.
csp_type csp(size_type id) const
Get a ConstSingleParticle.
Definition: particle.hpp:179
weight_set_type & weight_set()
Read and write access to the weight collection object.
Definition: particle.hpp:155
A const variant to SingleParticle.
const rng_set_type & rng_set() const
Read only access to the RNG collection object.
Definition: particle.hpp:164