32 #ifndef MCKL_ALGORITHM_SMC_HPP 33 #define MCKL_ALGORITHM_SMC_HPP 48 template <
typename T,
typename U =
double>
50 :
public Estimator<U, std::size_t, std::size_t, Particle<T> &, U *>
52 static_assert(std::is_convertible<U, double>::value,
53 "**SMCEsimator** used with estimate type U not convertible to double");
63 template <
typename Eval>
65 bool record_only =
false)
67 dim,
std::forward<Eval>(eval))
69 , record_only_(record_only)
77 template <
typename Eval>
82 std::forward<Eval>(eval));
84 record_only_ = record_only;
91 result_.resize(this->dim());
93 this->eval(iter, this->dim(), particle, this->insert_estimate());
97 const std::size_t n =
static_cast<std::size_t
>(particle.
size());
98 const std::size_t d = this->dim();
100 this->eval(iter, d, particle, u_.data());
102 const double *w = particle.
weight().data();
103 double *r = rptr(std::is_same<U, double>());
104 internal::size_check<MCKL_BLAS_INT>(n,
"SMCEstimator::estimate");
105 internal::size_check<MCKL_BLAS_INT>(d,
"SMCEstimator::estimate");
107 internal::cblas_dgemv(internal::CblasColMajor,
108 internal::CblasNoTrans, static_cast<MCKL_BLAS_INT>(d),
109 static_cast<MCKL_BLAS_INT>(n), 1.0, r,
110 static_cast<MCKL_BLAS_INT>(d), w, 1, 0.0, result_.data(), 1);
112 internal::cblas_dgemv(internal::CblasColMajor,
113 internal::CblasTrans, static_cast<MCKL_BLAS_INT>(n),
114 static_cast<MCKL_BLAS_INT>(d), 1.0, r,
115 static_cast<MCKL_BLAS_INT>(n), w, 1, 0.0, result_.data(), 1);
117 this->insert_estimate(result_.data());
127 double *rptr(std::true_type) {
return u_.data(); }
129 double *rptr(std::false_type)
131 r_.resize(u_.size());
132 std::copy(u_.begin(), u_.end(), r_.begin());
138 template <
typename,
typename =
double>
141 template <
typename T,
typename U>
145 using eval_type = std::function<void(std::size_t, Particle<T> &)>;
151 template <
typename T,
typename U>
160 SMCSampler() : iter_(0), resample_threshold_(resample_threshold_never()) {}
166 template <
typename... Args>
169 , particle_(N,
std::forward<Args>(args)...)
171 , resample_threshold_(resample_threshold_never())
179 sampler.
particle().rng_set().reset();
190 std::size_t
num_iter()
const {
return size_history_.size(); }
197 size_history_.reserve(n);
198 ess_history_.reserve(n);
214 size_history_.clear();
215 ess_history_.clear();
224 resample_threshold_ = threshold;
236 template <
typename Eval>
238 std::enable_if_t<!std::is_integral<Eval>::value> * =
nullptr)
240 return this->eval(0, std::forward<Eval>(eval));
247 return this->eval(0, k);
251 template <
typename Eval>
253 std::enable_if_t<!std::is_integral<Eval>::value> * =
nullptr)
255 return this->eval(1, std::forward<Eval>(eval));
278 "**SMCSampler::resample** used with unknown resample " 289 template <
typename Eval>
291 std::enable_if_t<!std::is_integral<Eval>::value> * =
nullptr)
293 return this->eval(2, std::forward<Eval>(eval));
300 template <
typename Estimator>
302 std::enable_if_t<!std::is_integral<Estimator>::value> * =
nullptr)
304 return this->estimator(0, std::forward<Estimator>(estimator));
309 return this->estimator(0, k);
314 return this->estimator(0, k);
317 template <
typename Estimator>
319 std::enable_if_t<!std::is_integral<Estimator>::value> * =
nullptr)
321 return this->estimator(1, std::forward<Estimator>(estimator));
326 return this->estimator(1, k);
331 return this->estimator(1, k);
334 template <
typename Estimator>
336 std::enable_if_t<!std::is_integral<Estimator>::value> * =
nullptr)
338 return this->estimator(2, std::forward<Estimator>(estimator));
343 return this->estimator(2, k);
348 return this->estimator(2, k);
357 for (std::size_t i = 0; i != n; ++i) {
369 template <
typename OutputIter>
372 return std::copy(size_history_.begin(), size_history_.end(), first);
376 template <
typename OutputIter>
379 return std::copy(ess_history_.begin(), ess_history_.end(), first);
385 double resample_threshold_;
394 size_history_.push_back(size());
395 ess_history_.push_back(particle_.
weight().ess());
397 if (ess_history_.back() < size() * resample_threshold_) {
408 void do_eval(std::size_t step)
410 for (
auto &eval : this->eval(step)) {
411 eval(iter_, particle_);
415 void do_estimate(std::size_t step)
417 for (
auto &est : this->estimator(step)) {
418 est.estimate(iter_, particle_);
427 #endif // MCKL_ALGORITHM_SMC_HPP ResampleAlgorithm< U01SequenceSystematic, true > ResampleResidualSystematic
Residual systematic resampling.
std::size_t num_iter() const
The number of iterations already performed.
double resample_threshold() const
Get resampling threshold.
constexpr ResampleScheme ResidualStratified
std::size_t selection_estimator(Estimator &&estimator, std::enable_if_t<!std::is_integral< Estimator >::value > *=nullptr)
std::size_t resample(ResampleScheme scheme)
Add a new evaluation object for the resample step by a built-in resample scheme.
void iterate(std::size_t n=1)
Iterate the sampler.
const estimator_type & selection_estimator(std::size_t k) const
constexpr ResampleScheme Residual
Particle< T > & particle()
Read and write access to the Particle<T> object.
const eval_type & mutation(std::size_t k) const
ResampleAlgorithm< U01SequenceSorted, false > ResampleMultinomial
Multinomial resampling.
#define MCKL_PUSH_CLANG_WARNING(warning)
size_type size() const
this->particle().size()
SMCEstimator(std::size_t dim)
ResampleAlgorithm< U01SequenceSorted, true > ResampleResidual
Residual resampling.
ResampleScheme
Resampling schemes.
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Sampler for iterative Monte Carlo algorithms.
bool record_only() const
If this is a record only estimator.
ResampleAlgorithm< U01SequenceStratified, false > ResampleStratified
Stratified resampling.
eval_type & selection(std::size_t k)
std::function< void(std::size_t, Particle< T > &)> eval_type
constexpr ResampleScheme Systematic
void estimate(std::size_t iter, Particle< T > &particle)
Perform the evaluation given the iteration number and the particle system.
estimator_type & mutation_estimator(std::size_t k)
estimator_type & selection_estimator(std::size_t k)
std::size_t selection(Eval &&eval, std::enable_if_t<!std::is_integral< Eval >::value > *=nullptr)
Add a new evaluation object for the selection step.
weight_type & weight()
Read and write access to the weight collection object.
typename rng_set_type::rng_type rng_type
ResampleAlgorithm< U01SequenceStratified, true > ResampleResidualStratified
Residual stratified resampling.
const eval_type & selection(std::size_t k) const
OutputIter read_ess_history(OutputIter first) const
Read the history of the values of ESS.
void reserve(std::size_t n)
Reserve space for a specified number of iterations.
typename Sampler< SMCSampler< T, U > >::estimator_type estimator_type
const estimator_type & resample_estimator(std::size_t k) const
constexpr ResampleScheme ResidualSystematic
SMCSampler<T>::eval_type subtype.
const estimator_type & mutation_estimator(std::size_t k) const
constexpr ResampleScheme Stratified
const Particle< T > & particle() const
Read only access to the Particle<T> object.
std::size_t mutation(Eval &&eval, std::enable_if_t<!std::is_integral< Eval >::value > *=nullptr)
Add a new evaluation object for the mutation step.
SMCSampler(size_type N, Args &&... args)
Construct a SMC sampler.
const eval_type & resample(std::size_t k) const
SMCSampler< T, U > clone() const
Clone the SMC sampler except the RNG engines.
eval_type & mutation(std::size_t k)
size_type size() const
The number of particles.
void reset()
Reset the sampler by clear all history, evaluation objects, and estimators.
#define MCKL_POP_CLANG_WARNING
eval_type & resample(std::size_t k)
std::size_t resample(Eval &&eval, std::enable_if_t<!std::is_integral< Eval >::value > *=nullptr)
Add a new evaluation object for the selection step.
typename Sampler< SMCSampler< T, U > >::eval_type eval_type
void estimate(Eval &&eval, MatrixLayout layout=RowMajor, bool record_only=false)
Set a new evaluation object.
typename Particle< T >::size_type size_type
constexpr MatrixLayout RowMajor
ResampleAlgorithm< U01SequenceSystematic, false > ResampleSystematic
Systematic resampling.
Estimator for iterative Monte Carlo algorithms.
estimator_type & resample_estimator(std::size_t k)
OutputIter read_size_history(OutputIter first) const
Read history the sampler sizes.
std::size_t resample_estimator(Estimator &&estimator, std::enable_if_t<!std::is_integral< Estimator >::value > *=nullptr)
SMCEstimator(std::size_t dim, Eval &&eval, MatrixLayout layout=RowMajor, bool record_only=false)
static double resample_threshold_never()
Special value of resampling threshold that indicates no resampling will be ever performed.
RNG default seed generator.
void clear()
Clear all history.
void runtime_assert(bool cond, const char *msg, bool soft=false)
MatrixLayout
Matrix layout.
void resample_threshold(double threshold)
Set resampling threshold.
constexpr ResampleScheme Multinomial
std::size_t mutation_estimator(Estimator &&estimator, std::enable_if_t<!std::is_integral< Estimator >::value > *=nullptr)
static double resample_threshold_always()
Special value of resampling threshold that indicates resampling will always be performed.