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-2015, 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;
56  using rng_type = typename rng_set_type::rng_type;
57  using resample_type = std::function<void(std::size_t, std::size_t,
58  resample_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(resample_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.resample_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  resample_rng_ = other.resample_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  resample_rng_ = other.resample_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  resample_rng_type &resample_rng() { return resample_rng_; }
147 
155  bool resample(const resample_type &op, double threshold)
156  {
157  std::size_t N = static_cast<std::size_t>(weight_.resample_size());
158  bool resampled = weight_.ess() < threshold * N;
159  if (resampled) {
160  const double *const rwptr = weight_.resample_data();
161  if (rwptr != nullptr) {
162 #if VSMC_USE_TBB
163  Vector<size_type> &rep = rep_.local();
164  Vector<size_type> &idx = idx_.local();
165  rep.resize(N);
166  idx.resize(N);
167 #else // VSMC_USE_TBB
168  Vector<size_type> rep(N);
169  Vector<size_type> idx(N);
170 #endif // VSMC_USE_TBB
171 
172  op(N, N, resample_rng_, rwptr, rep.data());
173  resample_trans_rep_index(N, N, rep.data(), idx.data());
174  value_.copy(N, idx.data());
175  } else {
176  value_.copy(N, static_cast<const size_type *>(nullptr));
177  }
178  weight_.set_equal();
179  }
180 
181  return resampled;
182  }
183 
184  private:
185  size_type size_;
186  value_type value_;
187  weight_type weight_;
188  rng_set_type rng_set_;
189  resample_rng_type resample_rng_;
190 #if VSMC_USE_TBB
191  ::tbb::combinable<Vector<size_type>> rep_;
192  ::tbb::combinable<Vector<size_type>> idx_;
193 #endif
194 }; // class Particle
195 
196 } // namespace vsmc
197 
198 #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
typename rng_set_type::rng_type rng_type
Definition: particle.hpp:56
typename RNGSetTypeTrait< T >::type RNGSetType
Definition: rng_set.hpp:124
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
typename std::conditional< std::is_scalar< T >::value, std::vector< T, AlignedAllocator< T >>, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
weight_type & weight()
Read and write access to the weight collection object.
Definition: particle.hpp:131
typename ResampleRNGTypeTrait< T >::type ResampleRNGType
Definition: common.hpp:51
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:155
Particle< T > & clone(Particle< T > &&other, bool retain_rng)
Definition: particle.hpp:105
std::function< void(std::size_t, std::size_t, resample_rng_type &, const double *, size_type *)> resample_type
Definition: particle.hpp:58
resample_rng_type & resample_rng()
Get the (sequential) RNG used stream for resampling.
Definition: particle.hpp:146
rng_type & rng(size_type id)
Get an (parallel) RNG stream for a given particle.
Definition: particle.hpp:143
void resample_trans_rep_index(std::size_t M, std::size_t N, const IntType1 *replication, IntType2 *src_idx)
Transform replication numbers into parent indices.
Definition: transform.hpp:100
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:319
size_type size() const
Number of particles.
Definition: particle.hpp:122
const rng_set_type & rng_set() const
Read only access to the RNG collection object.
Definition: particle.hpp:140