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((iter != map.end()), \
42 ("**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 INITIALIZATION OBJECT IS SET " \
51 "BUT INITILIALIZED BY ITERATING"))
65 typedef cxx11::function<std::size_t (Particle<T> &,
void *)>
init_type;
66 typedef cxx11::function<std::size_t (std::size_t, Particle<T> &)>
68 typedef cxx11::function<std::size_t (std::size_t, Particle<T> &)>
82 particle_(N), iter_num_(0), path_(typename
Path<T>::eval_type())
92 particle_(N), iter_num_(0), path_(typename
Path<T>::eval_type())
103 init_by_iter_(false), resample_threshold_(resample_threshold),
104 particle_(N), iter_num_(0), path_(typename
Path<T>::eval_type())
113 Sampler (size_type N,
const resample_type &res_op,
116 particle_(N), iter_num_(0), path_(typename
Path<T>::eval_type())
128 sampler.
particle().rng_set().seed();
142 if (
this != &other) {
144 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
156 swap(rset, particle_.rng_set());
158 particle_.resample_rng());
160 swap(rset, particle_.rng_set());
161 particle_.resample_rng() = rrng;
163 particle_.rng_set().resize(other.
size());
172 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
175 if (
this != &other) {
184 particle_.rng_set().resize(other.size());
195 size_type
size ()
const {
return particle_.size();}
200 ess_history_.reserve(num);
201 resampled_history_.reserve(num);
202 for (std::size_t i = 0; i != accept_history_.size(); ++i)
203 accept_history_[i].
reserve(num);
206 for (
typename monitor_map_type::iterator
207 m = monitor_.begin(); m != monitor_.end(); ++m) {
208 if (!m->second.empty())
209 m->second.reserve(num);
214 std::size_t
iter_size ()
const {
return ess_history_.size();}
227 particle_.resample(resample_op_,
228 std::numeric_limits<double>::max
VSMC_MNE ());
235 {resample_op_ = res_op;
return *
this;}
270 {resample_threshold_ = threshold;
return *
this;}
275 {
return -std::numeric_limits<double>::infinity();}
280 {
return std::numeric_limits<double>::infinity();}
283 double ess_history (std::size_t iter)
const {
return ess_history_[iter];}
286 template <
typename OutputIter>
288 {std::copy(ess_history_.begin(), ess_history_.end(), first);}
292 {
return resampled_history_[iter];}
295 template <
typename OutputIter>
297 {std::copy(resampled_history_.begin(), resampled_history_.end(), first);}
301 {
return accept_history_[id][iter];}
327 init_by_iter_ = initialize_by_iterate;
345 init_op (
const move_type &new_move) : move_(new_move) {}
348 {
return move_(0, particle);}
355 init_ = init_op(new_init);
376 move_queue_.push_back(new_move);
382 template <
typename InputIter>
387 while (first != last) {
389 move_queue_.push_back(*first);
412 mcmc_queue_.push_back(new_mcmc);
418 template <
typename InputIter>
423 while (first != last) {
425 mcmc_queue_.push_back(*first);
449 std::size_t acc = init_(particle_, param);
450 accept_history_.push_back(std::vector<std::size_t>(1, acc));
471 for (std::size_t i = 0; i != num; ++i) {
490 bool record_only =
false)
491 {path_.set_eval(eval, record_only);
return *
this;}
502 {monitor_.insert(std::make_pair(name, mon));
return *
this;}
514 bool record_only =
false)
516 monitor_.insert(
typename monitor_map_type::value_type(
525 typename monitor_map_type::iterator iter = monitor_.find(name);
536 typename monitor_map_type::const_iterator citer = monitor_.find(name);
541 return citer->second;
546 monitor_map_type &
monitor () {
return monitor_;}
550 const monitor_map_type &
monitor ()
const {
return monitor_;}
555 return monitor_.erase(name) ==
556 static_cast<typename monitor_map_type::size_type
>(1);
568 std::size_t header_size = 1;
569 header_size += accept_history_.size();
570 if (path_.iter_size() > 0)
572 for (
typename monitor_map_type::const_iterator
573 m = monitor_.begin(); m != monitor_.end(); ++m) {
574 if (m->second.iter_size() > 0)
575 header_size += m->second.dim();
582 template <
typename OutputIter>
588 *first = std::string(
"ESS");
591 std::stringstream ss;
593 unsigned accd =
static_cast<unsigned>(accept_history_.size());
594 for (
unsigned i = 0; i != accd; ++i) {
595 ss.str(std::string());
596 ss <<
"Accept." << i + 1;
601 if (path_.iter_size() > 0) {
602 *first = std::string(
"Path.Integrand");
604 *first = std::string(
"Path.Grid");
608 for (
typename monitor_map_type::const_iterator
609 m = monitor_.begin(); m != monitor_.end(); ++m) {
610 if (m->second.iter_size() > 0) {
611 unsigned mond =
static_cast<unsigned>(m->second.dim());
612 for (
unsigned i = 0; i != mond; ++i, ++first) {
613 if (!m->second.name(i).empty()) {
614 *first = m->second.name(i);
616 ss.str(std::string());
617 ss << m->first <<
'.' << i + 1;
632 template <MatrixOrder Order,
typename OutputIter>
639 summary_data_row(first);
642 summary_data_col(first);
649 template <
typename CharT,
typename Traits>
650 std::basic_ostream<CharT, Traits> &
print (
651 std::basic_ostream<CharT, Traits> &os,
char sepchar =
'\t')
const
658 std::vector<std::string> header(var_num);
659 std::vector<double> data(dat_num);
661 summary_data<RowMajor>(data.begin());
664 for (std::size_t i = 0; i != header.size(); ++i)
665 os << sepchar << header[i];
668 std::size_t offset = 0;
669 for (std::size_t iter = 0; iter !=
iter_size(); ++iter) {
670 os << resampled_history_[iter];
671 for (std::size_t i = 0; i != var_num; ++i)
672 os << sepchar << data[offset++];
683 std::vector<move_type> move_queue_;
684 std::vector<mcmc_type> mcmc_queue_;
686 resample_type resample_op_;
687 double resample_threshold_;
690 std::size_t iter_num_;
691 std::vector<double> ess_history_;
692 std::vector<bool> resampled_history_;
693 std::vector<std::vector<std::size_t> > accept_history_;
696 monitor_map_type monitor_;
700 if (accept_history_.empty())
701 accept_history_.push_back(std::vector<std::size_t>());
703 std::size_t acc_size = move_queue_.size() + mcmc_queue_.size();
704 if (accept_history_.size() < acc_size) {
705 std::size_t diff = acc_size - accept_history_.size();
706 for (std::size_t d = 0; d != diff; ++d)
707 accept_history_.push_back(std::vector<std::size_t>());
709 for (std::size_t i = 0; i != accept_history_.size(); ++i)
715 ess_history_.clear();
716 resampled_history_.clear();
717 accept_history_.clear();
719 for (
typename monitor_map_type::iterator
720 m = monitor_.begin(); m != monitor_.end(); ++m)
733 for (; ia != accept_history_.size(); ++ia)
734 accept_history_[ia].push_back(0);
737 std::size_t do_move (std::size_t ia)
739 for (
typename std::vector<move_type>::iterator
740 m = move_queue_.begin(); m != move_queue_.end(); ++m) {
741 std::size_t acc = (*m)(iter_num_, particle_);
742 accept_history_[ia].push_back(acc);
749 std::size_t do_mcmc (std::size_t ia)
751 for (
typename std::vector<mcmc_type>::iterator
752 m = mcmc_queue_.begin(); m != mcmc_queue_.end(); ++m) {
753 std::size_t acc = (*m)(iter_num_, particle_);
754 accept_history_[ia].push_back(acc);
763 ess_history_.push_back(particle_.
weight_set().ess());
764 resampled_history_.push_back(particle_.
resample(
765 resample_op_, resample_threshold_));
771 path_.
eval(iter_num_, particle_);
773 for (
typename monitor_map_type::iterator
774 m = monitor_.begin(); m != monitor_.end(); ++m) {
775 if (!m->second.empty())
776 m->second.eval(iter_num_, particle_);
780 template <
typename OutputIter>
781 void summary_data_row (OutputIter first)
const
783 double missing_data = std::numeric_limits<double>::quiet_NaN();
785 std::size_t piter = 0;
786 std::vector<std::size_t> miter(monitor_.size(), 0);
787 for (std::size_t iter = 0; iter !=
iter_size(); ++iter) {
788 *first = ess_history_[iter] /
size();
790 for (std::size_t i = 0; i != accept_history_.size(); ++i) {
791 *first = accept_history_[i][iter] /
792 static_cast<double>(
size());
797 *first = missing_data;
799 *first = missing_data;
804 *first = path_.
grid(piter);
810 for (
typename monitor_map_type::const_iterator
811 m = monitor_.begin(); m != monitor_.end(); ++m, ++mm) {
812 if (m->second.iter_size() > 0) {
813 if (miter[mm] == m->second.iter_size()
814 || iter != m->second.index(miter[mm])) {
815 for (std::size_t i = 0; i != m->second.dim();
817 *first = missing_data;
819 for (std::size_t i = 0; i != m->second.dim();
821 *first = m->second.record(i, miter[mm]);
829 template <
typename OutputIter>
830 void summary_data_col (OutputIter first)
const
832 double missing_data = std::numeric_limits<double>::quiet_NaN();
834 for (std::size_t iter = 0; iter !=
iter_size(); ++iter, ++first)
835 *first = ess_history_[iter] /
size();
836 for (std::size_t i = 0; i != accept_history_.size(); ++i) {
837 for (std::size_t iter = 0; iter !=
iter_size(); ++iter, ++first)
838 *first = accept_history_[i][iter] /
839 static_cast<double>(
size());
844 for (std::size_t iter = 0; iter !=
iter_size(); ++iter, ++first) {
846 *first = missing_data;
853 for (std::size_t iter = 0; iter !=
iter_size(); ++iter, ++first) {
855 *first = missing_data;
857 *first = path_.
grid(piter);
862 for (
typename monitor_map_type::const_iterator
863 m = monitor_.begin(); m != monitor_.end(); ++m) {
864 if (m->second.iter_size() > 0) {
865 for (std::size_t i = 0; i != m->second.dim(); ++i) {
866 std::size_t miter = 0;
867 for (std::size_t iter = 0; iter !=
iter_size();
869 if (miter == m->second.iter_size()
870 || iter != m->second.index(miter)) {
871 *first = missing_data;
873 *first = m->second.record(i, miter);
883 template <
typename CharT,
typename Traits,
typename T>
885 std::basic_ostream<CharT, Traits> &os,
const Sampler<T> &sampler)
886 {
return sampler.
print(os);}
890 #endif // VSMC_CORE_SAMPLER_HPP
cxx11::function< double(std::size_t, const Particle< T > &, double *)> eval_type
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.
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, char sepchar= '\t') const
Print the history of the Sampler.
Sampler< T > & monitor(const std::string &name, std::size_t dim, const typename Monitor< T >::eval_type &eval, bool record_only=false)
Add a monitor with an evaluation object.
Sampler< T > & path_sampling(const typename Path< T >::eval_type &eval, bool record_only=false)
Set the Path sampling evaluation object.
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.
Sampler< T > & clear_monitor()
Erase all monitors.
size_type size() const
Number of particles.
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 object.
monitor_map_type & monitor()
Read and write access to all monitors to the monitor_map_type object.
std::size_t summary_header_size() const
The size of Sampler summary header.
void eval(std::size_t iter, const Particle< T > &particle)
std::size_t index(std::size_t iter) const
Get the iteration index of the sampler of a given monitor iteration.
traits::RngSetTypeTrait< T >::type rng_set_type
Sampler< T > & clone(Sampler< T > &&other, bool retain_rng)
traits::ResampleRngTypeTrait< T >::type resample_rng_type
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)
ResampleScheme
Resampling schemes.
Sampler< T > & mcmc(const mcmc_type &new_mcmc, bool append)
Add a new mcmc.
void summary_header(OutputIter first) const
Sampler summary header.
#define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_MONITOR_NAME(iter, map, func)
cxx11::function< std::size_t(Particle< T > &, void *)> init_type
cxx11::function< void(std::size_t, std::size_t, resample_rng_type &, const double *, size_type *)> resample_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.
std::size_t move_queue_size() const
Check the size of the move queue.
double resample_threshold() const
Get resampling threshold.
Data are stored column by column in memory.
cxx11::function< void(std::size_t, std::size_t, const Particle< T > &, double *)> eval_type
bool empty() const
Whether the evaluation object is valid.
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.
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.
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
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.
cxx11::function< std::size_t(std::size_t, Particle< T > &)> move_type
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.
Data are stored row by row in memory.
#define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_FUNCTOR(func, caller, name)
remove_reference< T >::type && move(T &&t) noexcept
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.
Resample< cxx11::integral_constant< ResampleScheme, Scheme > > type
const monitor_map_type & monitor() const
Read only access to all monitors to the the monitor_map_type object.
Particle< T >::resample_type resample_type
#define VSMC_NULLPTR
nullptr
bool mcmc_queue_empty() const
Check if mcmc queue is empty.
Monitor for Path sampling.
std::size_t iter_size() const
The number of iterations has been recorded.
void swap(Array< T, N > &ary1, Array< T, N > &ary2)
Array ADL of swap.
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.
traits::SizeTypeTrait< T >::type size_type
Particle< T >::size_type size_type
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.
cxx11::function< std::size_t(std::size_t, Particle< T > &)> mcmc_type
std::size_t iter_num() const
Current iteration number (initialization count as zero)
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.
Systematic resampling on residuals.
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 object.
Sampler< T > & init_by_iter(bool initialize_by_iterate)
Set if initialization should use the move and mcmc queue.
Sampler< T > & move_queue_clear()
Clear the move queue.
Stratified resampling on residuals.
Sampler< T > & resample_scheme(ResampleScheme scheme)
Set resampling method by a built-in ResampleScheme scheme name.
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.
Sampler(size_type N, const resample_type &res_op, double resample_threshold=0.5)
Construct a Sampler with a user defined resampling operation.
std::map< std::string, Monitor< T > > monitor_map_type
const Monitor< T > & monitor(const std::string &name) const
Read only access to a named monitor.
Sampler< T > & monitor(const std::string &name, const Monitor< T > &mon)
Add a monitor.
weight_set_type & weight_set()
Read and write access to the weight collection object.
std::size_t mcmc_queue_size() const
Check the size of the mcmc queue.
void summary_data(OutputIter first) const
Sampler summary data.
Sampler< T > & clone(const Sampler< T > &other, bool retain_rng)
Clone another sampler system except the RNG engines.