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-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 namespace vsmc
43 {
44 
47 template <typename T>
48 class Particle
49 {
50  public:
52  using value_type = T;
55  using rng_type = typename rng_set_type::rng_type;
56  using resample_type = std::function<void(
57  std::size_t, std::size_t, rng_type &, const double *, size_type *)>;
59 
60  explicit Particle(size_type N)
61  : size_(N)
62  , value_(N)
63  , weight_(static_cast<SizeType<weight_type>>(N))
64  , rng_set_(static_cast<SizeType<rng_set_type>>(N))
65  {
66  Seed::instance().seed_rng(rng_);
67  }
68 
73  Particle<T> clone(bool new_rng) const
74  {
75  Particle<T> particle(*this);
76  if (new_rng) {
77  particle.rng_set().seed();
78  Seed::instance().seed_rng(particle.rng());
79  }
80 
81  return particle;
82  }
83 
89  Particle<T> &clone(const Particle<T> &other, bool retain_rng)
90  {
91  if (this != &other) {
92  size_ = other.size_;
93  value_ = other.value_;
94  weight_ = other.weight_;
95 
96  if (!retain_rng) {
97  rng_set_ = other.rng_set_;
98  rng_ = other.rng_;
99  }
100  }
101 
102  return *this;
103  }
104 
105  Particle<T> &clone(Particle<T> &&other, bool retain_rng)
106  {
107  if (this != &other) {
108  size_ = other.size_;
109  value_ = std::move(other.value_);
110  weight_ = std::move(other.weight_);
111 
112  if (!retain_rng) {
113  rng_set_ = other.rng_set_;
114  rng_ = other.rng_;
115  }
116  }
117 
118  return *this;
119  }
120 
122  size_type size() const { return size_; }
123 
125  value_type &value() { return value_; }
126 
128  const value_type &value() const { return value_; }
129 
131  weight_type &weight() { return weight_; }
132 
134  const weight_type &weight() const { return weight_; }
135 
137  rng_set_type &rng_set() { return rng_set_; }
138 
140  const rng_set_type &rng_set() const { return rng_set_; }
141 
143  rng_type &rng(size_type id) { return rng_set_[id]; }
144 
146  const rng_type &rng(size_type id) const { return rng_set_[id]; }
147 
149  rng_type &rng() { return rng_; }
150 
152  const rng_type &rng() const { return rng_; }
153 
155  sp_type sp(size_type id) { return SingleParticle<T>(id, this); }
156 
158  sp_type begin() { return sp(0); }
159 
161  sp_type end() { return sp(size_); }
162 
170  bool resample(const resample_type &op, double threshold)
171  {
172  std::size_t N = static_cast<std::size_t>(weight_.resample_size());
173  bool resampled = weight_.ess() < threshold * N;
174  if (resampled) {
175  const double *const rwptr = weight_.resample_data();
176  if (rwptr != nullptr) {
177 #if VSMC_USE_TBB
178  Vector<size_type> &rep = rep_.local();
179  Vector<size_type> &idx = idx_.local();
180  rep.resize(N);
181  idx.resize(N);
182 #else // VSMC_USE_TBB
183  Vector<size_type> rep(N);
184  Vector<size_type> idx(N);
185 #endif // VSMC_USE_TBB
186 
187  op(N, N, rng_, rwptr, rep.data());
188  resample_trans_rep_index(N, N, rep.data(), idx.data());
189  value_.copy(N, idx.data());
190  } else {
191  value_.copy(N, static_cast<const size_type *>(nullptr));
192  }
193  weight_.set_equal();
194  }
195 
196  return resampled;
197  }
198 
199  private:
200  size_type size_;
201  value_type value_;
202  weight_type weight_;
203  rng_set_type rng_set_;
204  rng_type rng_;
205 #if VSMC_USE_TBB
206  ::tbb::combinable<Vector<size_type>> rep_;
207  ::tbb::combinable<Vector<size_type>> idx_;
208 #endif
209 }; // class Particle
210 
211 } // namespace vsmc
212 
213 #endif // VSMC_CORE_PARTICLE_HPP
static SeedGenerator< ID, ResultType > & instance()
Definition: seed.hpp:100
Definition: monitor.hpp:49
Particle class representing the whole particle set.
Definition: particle.hpp:48
sp_type sp(size_type id)
Get a SingleParticle<T> object.
Definition: particle.hpp:155
typename rng_set_type::rng_type rng_type
Definition: particle.hpp:55
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
typename RNGSetTypeTrait< T >::type RNGSetType
Definition: rng_set.hpp:164
const rng_type & rng(size_type id) const
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:146
sp_type end()
Get a SingleParticle<T> object for the first particle.
Definition: particle.hpp:161
Particle< T > clone(bool new_rng) const
Clone the particle system except the RNG engines.
Definition: particle.hpp:73
value_type & value()
Read and write access to the value collection object.
Definition: particle.hpp:125
const rng_type & rng() const
Get the (sequential) RNG used stream for resampling.
Definition: particle.hpp:152
weight_type & weight()
Read and write access to the weight collection object.
Definition: particle.hpp:131
const weight_type & weight() const
Read only access to the weight collection object.
Definition: particle.hpp:134
Particle(size_type N)
Definition: particle.hpp:60
const value_type & value() const
Read only access to the value collection object.
Definition: particle.hpp:128
Particle< T > & clone(const Particle< T > &other, bool retain_rng)
Clone another particle system except the RNG engines.
Definition: particle.hpp:89
bool resample(const resample_type &op, double threshold)
Performing resampling if ESS/N < threshold.
Definition: particle.hpp:170
void resample_trans_rep_index(std::size_t M, std::size_t N, const IntType1 *replication, IntType2 *index)
Transform replication numbers into parent indices.
Definition: transform.hpp:100
std::function< void(std::size_t, std::size_t, rng_type &, const double *, size_type *)> resample_type
Definition: particle.hpp:57
Particle< T > & clone(Particle< T > &&other, bool retain_rng)
Definition: particle.hpp:105
rng_type & rng(size_type id)
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:143
rng_set_type & rng_set()
Read and write access to the RNG collection object.
Definition: particle.hpp:137
typename SizeTypeTrait< T >::type SizeType
Definition: traits.hpp:212
typename WeightTypeTrait< T >::type WeightType
Definition: weight.hpp:321
size_type size() const
Number of particles.
Definition: particle.hpp:122
sp_type begin()
Get a SingleParticle<T> object for the first particle.
Definition: particle.hpp:158
A thin wrapper over a complete Particle.
rng_type & rng()
Get the (sequential) RNG used stream for resampling.
Definition: particle.hpp:149
const rng_set_type & rng_set() const
Read only access to the RNG collection object.
Definition: particle.hpp:140