32 #ifndef VSMC_CORE_SAMPLER_HPP    33 #define VSMC_CORE_SAMPLER_HPP    40 #define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_MONITOR_NAME(iter, map, func)        \    41     VSMC_RUNTIME_ASSERT(                                                      \    42         (iter != map.end()), "**Sampler::" #func "** INVALID MONITOR NAME")    44 #define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_FUNCTOR(func, caller, name)          \    45     VSMC_RUNTIME_ASSERT(static_cast<bool>(func),                              \    46         "**Sampler::" #caller "** INVALID " #name " OBJECT")    48 #define VSMC_RUNTIME_WARNING_CORE_SAMPLER_INIT_BY_ITER                        \    49     VSMC_RUNTIME_WARNING((!static_cast<bool>(init_)),                         \    50         "**Sampler::initialize** A VALID INIT OBJECT IS SET "                 \    51         "BUT INITILIALIZED BY ITERATING")    65     using init_type = std::function<std::size_t(Particle<T> &, 
void *)>;
    66     using move_type = std::function<std::size_t(std::size_t, Particle<T> &)>;
    67     using mcmc_type = std::function<std::size_t(std::size_t, Particle<T> &)>;
    73         , init_by_iter_(false)
    76         , path_(typename 
Path<T>::eval_type())
    87         , init_by_iter_(false)
    90         , path_(typename 
Path<T>::eval_type())
   101         , init_by_iter_(false)
   104         , path_(typename 
Path<T>::eval_type())
   113         , init_by_iter_(false)
   114         , resample_threshold_(resample_threshold)
   116         , path_(typename 
Path<T>::eval_type())
   126         , init_by_iter_(false)
   127         , resample_threshold_(resample_threshold)
   129         , path_(typename 
Path<T>::eval_type())
   142             sampler.
particle().rng_set().seed();
   156         if (
this != &other) {
   157             particle_.clone(other.particle_, retain_rng);
   158             init_by_iter_ = other.init_by_iter_;
   160             move_queue_ = other.move_queue_;
   161             mcmc_queue_ = other.mcmc_queue_;
   162             resample_op_ = other.resample_op_;
   163             resample_threshold_ = other.resample_threshold_;
   164             iter_num_ = other.iter_num_;
   165             size_history_ = other.size_history_;
   166             ess_history_ = other.ess_history_;
   167             resampled_history_ = other.resampled_history_;
   168             accept_history_ = other.accept_history_;
   176         if (
this != &other) {
   177             particle_.clone(std::move(other.particle_), retain_rng);
   178             init_by_iter_ = other.init_by_iter_;
   179             init_ = std::move(other.init_);
   180             move_queue_ = std::move(other.move_queue_);
   181             mcmc_queue_ = std::move(other.mcmc_queue_);
   182             resample_op_ = std::move(other.resample_op_);
   183             resample_threshold_ = other.resample_threshold_;
   184             iter_num_ = other.iter_num_;
   185             size_history_ = std::move(other.size_history_);
   186             ess_history_ = std::move(other.ess_history_);
   187             resampled_history_ = std::move(other.resampled_history_);
   188             accept_history_ = std::move(other.accept_history_);
   200         size_history_.reserve(num);
   201         ess_history_.reserve(num);
   202         resampled_history_.reserve(num);
   203         for (
auto &a : accept_history_)
   207         for (
auto &m : monitor_)
   208             if (!m.second.empty())
   209                 m.second.reserve(num);
   213     std::size_t 
iter_size()
 const { 
return size_history_.size(); }
   229         resample_op_ = res_op;
   260         resample_threshold_ = threshold;
   268         return -std::numeric_limits<double>::infinity();
   275         return std::numeric_limits<double>::infinity();
   280     double size_history(std::size_t iter)
 const { 
return size_history_[iter]; }
   283     template <
typename OutputIter>
   286         std::copy(size_history_.begin(), size_history_.end(), first);
   290     double ess_history(std::size_t iter)
 const { 
return ess_history_[iter]; }
   293     template <
typename OutputIter>
   296         std::copy(ess_history_.begin(), ess_history_.end(), first);
   302         return resampled_history_[iter];
   306     template <
typename OutputIter>
   309         std::copy(resampled_history_.begin(), resampled_history_.end(), first);
   315         return accept_history_[id][iter];
   342         init_by_iter_ = initialize_by_iterate;
   356         init_ = init_op([new_init](
   382         move_queue_.push_back(new_move);
   388     template <
typename InputIter>
   393         while (first != last) {
   395             move_queue_.push_back(*first);
   423         mcmc_queue_.push_back(new_mcmc);
   429     template <
typename InputIter>
   434         while (first != last) {
   436             mcmc_queue_.push_back(*first);
   477         for (std::size_t i = 0; i != num; ++i) {
   496         path_.set_eval(eval, record_only);
   512         monitor_.insert(std::make_pair(name, mon));
   530         monitor_.insert(
typename monitor_map_type::value_type(
   531             name, 
Monitor<T>(dim, eval, record_only, stage)));
   539         typename monitor_map_type::iterator iter = monitor_.find(name);
   549         typename monitor_map_type::const_iterator citer = monitor_.find(name);
   554         return citer->second;
   568         return monitor_.erase(name) ==
   569             static_cast<typename monitor_map_type::size_type
>(1);
   586         return accept_history_.size() + 2;
   595         std::size_t header_size = 1;
   596         if (path_.iter_size() > 0)
   598         for (
const auto &m : monitor_)
   599             if (m.second.iter_size() > 0)
   600                 header_size += m.second.dim();
   606     template <
typename OutputIter>
   612         *first++ = std::string(
"Size");
   613         *first++ = std::string(
"Resampled");
   614         for (std::size_t i = 0; i != accept_history_.size(); ++i)
   619     template <
typename OutputIter>
   625         *first++ = std::string(
"ESS");
   626         if (path_.iter_size() > 0) {
   627             *first++ = std::string(
"Path.Integrand");
   628             *first++ = std::string(
"Path.Grid");
   630         for (
const auto &m : monitor_) {
   631             if (m.second.iter_size() > 0) {
   632                 unsigned md = 
static_cast<unsigned>(m.second.dim());
   633                 for (
unsigned d = 0; d != md; ++d) {
   634                     if (m.second.name(d).empty())
   637                         *first++ = m.second.name(d);
   656     template <MatrixOrder Order, 
typename OutputIter>
   663             summary_data_row_int(first);
   665             summary_data_col_int(first);
   669     template <MatrixOrder Order, 
typename OutputIter>
   676             summary_data_row(first);
   678             summary_data_col(first);
   685     template <
typename CharT, 
typename Traits>
   686     std::basic_ostream<CharT, Traits> &
print(
   687         std::basic_ostream<CharT, Traits> &os, 
char sepchar = 
'\t')
 const   698         summary_data_int<RowMajor>(data_int.begin());
   704         summary_data<RowMajor>(data.begin());
   706         for (
const auto &h : header_int)
   708         for (
const auto &h : header)
   712         std::size_t offset_int = 0;
   713         std::size_t offset = 0;
   714         for (std::size_t r = 0; r != nrow; ++r) {
   715             for (std::size_t c = 0; c != ncol_int; ++c)
   716                 os << data_int[offset_int++] << sepchar;
   717             for (std::size_t c = 0; c != ncol; ++c)
   718                 os << data[offset++] << sepchar;
   734     double resample_threshold_;
   736     std::size_t iter_num_;
   747         if (accept_history_.empty())
   749         std::size_t acc_size = move_queue_.size() + mcmc_queue_.size();
   750         if (accept_history_.size() < acc_size) {
   751             std::size_t diff = acc_size - accept_history_.size();
   752             for (std::size_t d = 0; d != diff; ++d)
   755         for (std::size_t i = 0; i != accept_history_.size(); ++i)
   761         size_history_.clear();
   762         ess_history_.clear();
   763         resampled_history_.clear();
   764         accept_history_.clear();
   766         for (
auto &m : monitor_)
   769         particle_.
weight().set_equal();
   772     void do_init(
void *param)
   775         accept_history_[0].push_back(init_(particle_, param));
   793     std::size_t do_move(std::size_t ia)
   795         for (
auto &m : move_queue_)
   796             accept_history_[ia++].push_back(m(iter_num_, particle_));
   801     std::size_t do_mcmc(std::size_t ia)
   803         for (
auto &m : mcmc_queue_)
   804             accept_history_[ia++].push_back(m(iter_num_, particle_));
   811         size_history_.push_back(
size());
   812         ess_history_.push_back(particle_.
weight().ess());
   813         resampled_history_.push_back(
   814             particle_.
resample(resample_op_, resample_threshold_));
   820             path_.
eval(iter_num_, particle_);
   822         for (
auto &m : monitor_)
   823             if (!m.second.empty())
   824                 m.second.eval(iter_num_, particle_, stage);
   827     template <
typename OutputIter>
   828     void summary_data_row_int(OutputIter first)
 const   830         using int_type = 
typename std::iterator_traits<OutputIter>::value_type;
   831         for (std::size_t iter = 0; iter != 
iter_size(); ++iter) {
   832             *first++ = 
static_cast<int_type
>(size_history_[iter]);
   833             *first++ = 
static_cast<int_type
>(resampled_history_[iter]);
   834             for (std::size_t i = 0; i != accept_history_.size(); ++i)
   835                 *first++ = static_cast<int_type>(accept_history_[i][iter]);
   839     template <
typename OutputIter>
   840     void summary_data_col_int(OutputIter first)
 const   842         first = 
std::copy(size_history_.begin(), size_history_.end(), first);
   844             resampled_history_.begin(), resampled_history_.end(), first);
   845         for (std::size_t i = 0; i != accept_history_.size(); ++i) {
   847                 accept_history_[i].begin(), accept_history_[i].end(), first);
   851     template <
typename OutputIter>
   852     void summary_data_row(OutputIter first)
 const   854         double missing_data = std::numeric_limits<double>::quiet_NaN();
   856         std::size_t piter = 0;
   859         for (
const auto &m : monitor_)
   860             if (m.second.iter_size() > 0)
   861                 miter.push_back(std::make_pair(0, &m.second));
   863         for (std::size_t iter = 0; iter != 
iter_size(); ++iter) {
   864             *first++ = ess_history_[iter];
   868                     *first++ = path_.
grid(piter);
   871                     *first++ = missing_data;
   872                     *first++ = missing_data;
   875             for (
auto &m : miter) {
   876                 std::size_t md = m.second->dim();
   877                 if (m.first != m.second->iter_size() &&
   878                     iter == m.second->index(m.first)) {
   880                         m.second->record_data(m.first++), md, first);
   882                     first = std::fill_n(first, md, missing_data);
   888     template <
typename OutputIter>
   889     void summary_data_col(OutputIter first)
 const   891         double missing_data = std::numeric_limits<double>::quiet_NaN();
   893         first = 
std::copy(ess_history_.begin(), ess_history_.end(), first);
   895             std::size_t piter = 0;
   896             for (std::size_t iter = 0; iter != 
iter_size(); ++iter) {
   900                     *first = missing_data;
   903             for (std::size_t iter = 0; iter != 
iter_size(); ++iter) {
   905                     *first++ = path_.
grid(piter++);
   907                     *first = missing_data;
   910         for (
const auto &m : monitor_) {
   911             if (m.second.iter_size() > 0) {
   912                 for (std::size_t d = 0; d != m.second.dim(); ++d) {
   913                     std::size_t miter = 0;
   914                     for (std::size_t iter = 0; iter != 
iter_size(); ++iter) {
   915                         if (miter != m.second.iter_size() ||
   916                             iter == m.second.index(miter)) {
   917                             *first++ = m.second.record(d, miter++);
   919                             *first++ = missing_data;
   928 template <
typename CharT, 
typename Traits, 
typename T>
   930     std::basic_ostream<CharT, Traits> &os, 
const Sampler<T> &sampler)
   932     return sampler.
print(os);
   937 #endif // VSMC_CORE_SAMPLER_HPP Residual stratified resampling. 
 
static SeedGenerator< ID, ResultType > & instance()
 
Path< T > & path()
Read and write access to the Path sampling monitor. 
 
Particle class representing the whole particle set. 
 
const Path< T > & path() const 
Read only access to the Path sampling monitor. 
 
Sampler(size_type N, const resample_type &res_op)
Construct a Sampler with a user defined resampling operation. 
 
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, char sepchar= '\t') const 
Print the history of the Sampler. 
 
Sampler< T > & path_sampling(const typename Path< T >::eval_type &eval, bool record_only=false)
Set the Path sampling evaluation object. 
 
void summary_data_int(OutputIter first) const 
Sampler summary data (integer data) 
 
Sampler< T > & mcmc_queue_clear()
Clear the mcmc queue. 
 
Sampler< T > & resample()
Force resample. 
 
double ess_history(std::size_t iter) const 
Get ESS of a given iteration, initialization count as iter 0. 
 
Sampler< T > & init_by_move(const move_type &new_init)
Set the initialization object with a type move_type object. 
 
typename Particle< T >::resample_type resample_type
 
Sampler< T > & clear_monitor()
Erase all monitors. 
 
size_type size() const 
Number of particles. 
 
MonitorStage
Monitor stage. 
 
Sampler(size_type N, ResampleScheme scheme)
Construct a Sampler with a built-in resampling scheme. 
 
double grid(std::size_t iter) const 
Get the Path sampling grid value of a given Path iteration. 
 
#define VSMC_RUNTIME_WARNING_CORE_SAMPLER_INIT_BY_ITER
 
const Particle< T > & particle() const 
Read only access to the Particle<T> object. 
 
monitor_map_type & monitor()
Read and write access to all monitors to the monitor_map_type object. 
 
void eval(std::size_t iter, Particle< T > &particle)
 
std::size_t summary_header_size() const 
The size of Sampler summary header (floating point data) 
 
double size_history(std::size_t iter) const 
Get sampler size of a given iteration (initialization count as iteration zero) 
 
ResampleScheme
Resampling schemes. 
 
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. 
 
std::size_t index(std::size_t iter) const 
Get the iteration index of the sampler of a given monitor iteration. 
 
weight_type & weight()
Read and write access to the weight collection object. 
 
Sampler< T > & clone(Sampler< T > &&other, bool retain_rng)
 
std::size_t summary_data_size_int() const 
The size of Sampler summary data (integer data) 
 
Stratified resampling on residuals. 
 
Sampler(size_type N, ResampleScheme scheme, double resample_threshold)
Construct a Sampler with a built-in resampling scheme and a threshold for resampling. 
 
Sampler< T > & initialize(void *param=nullptr)
Initialization. 
 
std::size_t iter_size() const 
Number of iterations (including initialization) 
 
std::function< double(std::size_t, Particle< T > &, double *)> eval_type
 
Sampler< T > & mcmc(const mcmc_type &new_mcmc, bool append)
Add a new mcmc. 
 
void summary_header(OutputIter first) const 
Sampler summary header (floating point data) 
 
Monitor evaluated after moves. 
 
std::string itos(UIntType i, std::true_type)
 
bool resample(const resample_type &op, double threshold)
Performing resampling if ESS/N < threshold. 
 
double path_sampling() const 
Path sampling estimate of the logarithm of normalizing constants ratio. 
 
void summary_header_int(OutputIter first) const 
Sampler summary header (integer data) 
 
std::size_t move_queue_size() const 
Check the size of the move queue. 
 
void copy(std::size_t n, const T *x, std::size_t incx, T *y, std::size_t incy)
Copies vector to another vector. 
 
double resample_threshold() const 
Get resampling threshold. 
 
Data are stored column by column in memory. 
 
std::function< std::size_t(std::size_t, Particle< T > &)> mcmc_type
 
bool empty() const 
Whether the evaluation object is valid. 
 
#define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_MONITOR_NAME(iter, map, func)            
 
Sampler< T > & iterate(std::size_t num=1)
Iteration. 
 
Sampler< T > & move(const move_type &new_move, bool append)
Add a new move. 
 
static double resample_threshold_always()
Special value of resampling threshold that indicate no resampling will always be performed. 
 
void read_resampled_history(OutputIter first) const 
Read resampling indicator history through an output iterator. 
 
std::size_t summary_data_size() const 
The size of Sampler summary data (floating point data) 
 
typename Particle< T >::size_type size_type
 
void read_ess_history(OutputIter first) const 
Read ESS history through an output iterator. 
 
Sampler< T > & move(InputIter first, InputIter last, bool append)
Add a sequence of new moves. 
 
void reserve(std::size_t num)
Reserve space for a specified number of iterations. 
 
bool clear_monitor(const std::string &name)
Erase a named monitor. 
 
Sampler< T > & resample_scheme(const resample_type &res_op)
Set resampling method by a resample_type object. 
 
void clear()
Clear all records of the index and integrations. 
 
Systematic resampling on residuals. 
 
Data are stored row by row in memory. 
 
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Sampler< T > &sampler)
 
Sampler< T > clone(bool new_rng) const 
Clone the sampler system except the RNG engines. 
 
std::function< void(std::size_t, std::size_t, resample_rng_type &, const double *, size_type *)> resample_type
 
Sampler< T > & monitor(const std::string &name, std::size_t dim, const typename Monitor< T >::eval_type &eval, bool record_only=false, MonitorStage stage=MonitorMCMC)
Add a monitor with an evaluation object. 
 
const monitor_map_type & monitor() const 
Read only access to all monitors to the the monitor_map_type object. 
 
bool mcmc_queue_empty() const 
Check if mcmc queue is empty. 
 
void read_size_history(OutputIter first) const 
Read sampler size history through an output iterator. 
 
std::map< std::string, Monitor< T >> monitor_map_type
 
Monitor for Path sampling. 
 
std::size_t iter_size() const 
The number of iterations has been recorded. 
 
Residual systematic resampling. 
 
bool move_queue_empty() const 
Check if move queue is empty. 
 
Sampler< T > & mcmc(InputIter first, InputIter last, bool append)
Add a sequence of new mcmcs. 
 
std::size_t summary_header_size_int() const 
The size of Sampler summary header (integer data, size etc.) 
 
Monitor evaluated after MCMC moves. 
 
double integrand(std::size_t iter) const 
Get the Path sampling integrand of a given Path iteration. 
 
Sampler< T > & init(const init_type &new_init)
Set the initialization object of type init_type. 
 
Monitor for Monte Carlo integration. 
 
std::size_t iter_num() const 
Current iteration number (initialization count as zero) 
 
Sampler(size_type N, const resample_type &res_op, double resample_threshold)
Construct a Sampler with a user defined resampling scheme and a threshold for resampling. 
 
Sampler< T > & resample_threshold(double threshold)
Set resampling threshold. 
 
std::size_t accept_history(std::size_t id, std::size_t iter) const 
Get the accept count of a given move id and the iteration. 
 
Sampler(size_type N)
Construct a Sampler without selection of resampling method. 
 
static double resample_threshold_never()
Special value of resampling threshold that indicate no resampling will be ever performed. 
 
Particle< T > & particle()
Read and write access to the Particle<T> object. 
 
Sampler< T > & init_by_iter(bool initialize_by_iterate)
Set if initialization should use the move and mcmc queue. 
 
std::function< std::size_t(Particle< T > &, void *)> init_type
 
Sampler< T > & move_queue_clear()
Clear the move queue. 
 
Sampler< T > & resample_scheme(ResampleScheme scheme)
Set resampling method by a built-in ResampleScheme scheme name. 
 
#define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_FUNCTOR(func, caller, name)                
 
std::function< void(std::size_t, std::size_t, Particle< T > &, double *)> eval_type
 
Monitor< T > & monitor(const std::string &name)
Read and write access to a named monitor. 
 
bool resampled_history(std::size_t iter) const 
Get resampling indicator of a given iteration. 
 
const Monitor< T > & monitor(const std::string &name) const 
Read only access to a named monitor. 
 
std::function< std::size_t(std::size_t, Particle< T > &)> move_type
 
Sampler< T > & monitor(const std::string &name, const Monitor< T > &mon)
Add a monitor. 
 
std::size_t mcmc_queue_size() const 
Check the size of the mcmc queue. 
 
void summary_data(OutputIter first) const 
Sampler summary data (floating point data) 
 
Sampler< T > & clone(const Sampler< T > &other, bool retain_rng)
Clone another sampler system except the RNG engines. 
 
Monitor evaluated after resampling.