32 #ifndef VSMC_CORE_SAMPLER_HPP 33 #define VSMC_CORE_SAMPLER_HPP 39 #define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_MONITOR_NAME(iter, map, func) \ 40 VSMC_RUNTIME_ASSERT( \ 41 (iter != map.end()), "**Sampler::" #func "** INVALID MONITOR NAME") 43 #define VSMC_RUNTIME_ASSERT_CORE_SAMPLER_FUNCTOR(func, caller, name) \ 44 VSMC_RUNTIME_ASSERT(static_cast<bool>(func), \ 45 "**Sampler::" #caller "** INVALID " #name " OBJECT") 47 #define VSMC_RUNTIME_WARNING_CORE_SAMPLER_INIT_BY_ITER \ 48 VSMC_RUNTIME_WARNING((!static_cast<bool>(init_)), \ 49 "**Sampler::initialize** A VALID INIT OBJECT IS SET " \ 50 "BUT INITILIALIZED BY ITERATING") 64 using init_type = std::function<std::size_t(Particle<T> &,
void *)>;
65 using move_type = std::function<std::size_t(std::size_t, Particle<T> &)>;
66 using mcmc_type = std::function<std::size_t(std::size_t, Particle<T> &)>;
72 , init_by_iter_(false)
85 , init_by_iter_(false)
98 , init_by_iter_(false)
109 , init_by_iter_(false)
110 , resample_threshold_(resample_threshold)
121 , init_by_iter_(false)
122 , resample_threshold_(resample_threshold)
136 sampler.
particle().rng_set().seed();
150 if (
this != &other) {
151 particle_.clone(other.particle_, retain_rng);
152 init_by_iter_ = other.init_by_iter_;
154 move_queue_ = other.move_queue_;
155 mcmc_queue_ = other.mcmc_queue_;
156 resample_op_ = other.resample_op_;
157 resample_threshold_ = other.resample_threshold_;
158 iter_num_ = other.iter_num_;
159 size_history_ = other.size_history_;
160 ess_history_ = other.ess_history_;
161 resampled_history_ = other.resampled_history_;
162 accept_history_ = other.accept_history_;
170 if (
this != &other) {
171 particle_.clone(std::move(other.particle_), retain_rng);
172 init_by_iter_ = other.init_by_iter_;
173 init_ = std::move(other.init_);
174 move_queue_ = std::move(other.move_queue_);
175 mcmc_queue_ = std::move(other.mcmc_queue_);
176 resample_op_ = std::move(other.resample_op_);
177 resample_threshold_ = other.resample_threshold_;
178 iter_num_ = other.iter_num_;
179 size_history_ = std::move(other.size_history_);
180 ess_history_ = std::move(other.ess_history_);
181 resampled_history_ = std::move(other.resampled_history_);
182 accept_history_ = std::move(other.accept_history_);
194 size_history_.reserve(num);
195 ess_history_.reserve(num);
196 resampled_history_.reserve(num);
197 for (
auto &a : accept_history_)
199 for (
auto &m : monitor_)
200 if (!m.second.empty())
201 m.second.reserve(num);
205 std::size_t
iter_size()
const {
return size_history_.size(); }
221 resample_op_ = res_op;
252 resample_threshold_ = threshold;
260 return -std::numeric_limits<double>::infinity();
267 return std::numeric_limits<double>::infinity();
272 double size_history(std::size_t iter)
const {
return size_history_[iter]; }
275 template <
typename OutputIter>
278 std::copy(size_history_.begin(), size_history_.end(), first);
282 double ess_history(std::size_t iter)
const {
return ess_history_[iter]; }
285 template <
typename OutputIter>
288 std::copy(ess_history_.begin(), ess_history_.end(), first);
294 return resampled_history_[iter];
298 template <
typename OutputIter>
301 std::copy(resampled_history_.begin(), resampled_history_.end(), first);
307 return accept_history_[id][iter];
334 init_by_iter_ = initialize_by_iterate;
348 init_ = init_op([new_init](
374 move_queue_.push_back(new_move);
380 template <
typename InputIter>
385 while (first != last) {
387 move_queue_.push_back(*first);
415 mcmc_queue_.push_back(new_mcmc);
421 template <
typename InputIter>
426 while (first != last) {
428 mcmc_queue_.push_back(*first);
469 for (std::size_t i = 0; i != num; ++i) {
484 monitor_.insert(std::make_pair(name, mon));
502 monitor_.insert(
typename monitor_map_type::value_type(
503 name,
Monitor<T>(dim, eval, record_only, stage)));
511 typename monitor_map_type::iterator iter = monitor_.find(name);
521 typename monitor_map_type::const_iterator citer = monitor_.find(name);
526 return citer->second;
540 return monitor_.erase(name) ==
541 static_cast<typename monitor_map_type::size_type
>(1);
558 return accept_history_.size() + 2;
567 std::size_t header_size = 1;
568 for (
const auto &m : monitor_)
569 if (m.second.iter_size() > 0)
570 header_size += m.second.dim();
576 template <
typename OutputIter>
582 *first++ = std::string(
"Size");
583 *first++ = std::string(
"Resampled");
584 for (std::size_t i = 0; i != accept_history_.size(); ++i)
589 template <
typename OutputIter>
595 *first++ = std::string(
"ESS");
596 for (
const auto &m : monitor_) {
597 if (m.second.iter_size() > 0) {
598 unsigned md =
static_cast<unsigned>(m.second.dim());
599 for (
unsigned d = 0; d != md; ++d) {
600 if (m.second.name(d).empty())
603 *first++ = m.second.name(d);
622 template <MatrixLayout Layout,
typename OutputIter>
629 summary_data_row_int(first);
631 summary_data_col_int(first);
635 template <MatrixLayout Layout,
typename OutputIter>
642 summary_data_row(first);
644 summary_data_col(first);
651 template <
typename CharT,
typename Traits>
652 std::basic_ostream<CharT, Traits> &
print(
653 std::basic_ostream<CharT, Traits> &os,
char sepchar =
'\t')
const 664 summary_data_int<RowMajor>(data_int.begin());
670 summary_data<RowMajor>(data.begin());
672 for (
const auto &h : header_int)
674 for (
const auto &h : header)
678 std::size_t offset_int = 0;
679 std::size_t offset = 0;
680 for (std::size_t r = 0; r != nrow; ++r) {
681 for (std::size_t c = 0; c != ncol_int; ++c)
682 os << data_int[offset_int++] << sepchar;
683 for (std::size_t c = 0; c != ncol; ++c)
684 os << data[offset++] << sepchar;
700 double resample_threshold_;
702 std::size_t iter_num_;
711 if (accept_history_.empty())
713 std::size_t acc_size = move_queue_.size() + mcmc_queue_.size();
714 if (accept_history_.size() < acc_size) {
715 std::size_t diff = acc_size - accept_history_.size();
716 for (std::size_t d = 0; d != diff; ++d)
719 for (std::size_t i = 0; i != accept_history_.size(); ++i)
725 size_history_.clear();
726 ess_history_.clear();
727 resampled_history_.clear();
728 accept_history_.clear();
729 for (
auto &m : monitor_)
732 particle_.
weight().set_equal();
735 void do_init(
void *param)
738 accept_history_[0].push_back(init_(particle_, param));
748 std::size_t ia = do_move(0);
756 std::size_t do_move(std::size_t ia)
758 for (
auto &m : move_queue_)
759 accept_history_[ia++].push_back(m(iter_num_, particle_));
764 std::size_t do_mcmc(std::size_t ia)
766 for (
auto &m : mcmc_queue_)
767 accept_history_[ia++].push_back(m(iter_num_, particle_));
774 size_history_.push_back(
size());
775 ess_history_.push_back(particle_.
weight().ess());
776 resampled_history_.push_back(
777 particle_.
resample(resample_op_, resample_threshold_));
782 for (
auto &m : monitor_)
783 if (!m.second.empty())
784 m.second.eval(iter_num_, particle_, stage);
787 template <
typename OutputIter>
788 void summary_data_row_int(OutputIter first)
const 790 using int_type =
typename std::iterator_traits<OutputIter>::value_type;
791 for (std::size_t iter = 0; iter !=
iter_size(); ++iter) {
792 *first++ =
static_cast<int_type
>(size_history_[iter]);
793 *first++ =
static_cast<int_type
>(resampled_history_[iter]);
794 for (std::size_t i = 0; i != accept_history_.size(); ++i)
795 *first++ = static_cast<int_type>(accept_history_[i][iter]);
799 template <
typename OutputIter>
800 void summary_data_col_int(OutputIter first)
const 802 first = std::copy(size_history_.begin(), size_history_.end(), first);
804 resampled_history_.begin(), resampled_history_.end(), first);
805 for (std::size_t i = 0; i != accept_history_.size(); ++i) {
807 accept_history_[i].begin(), accept_history_[i].end(), first);
811 template <
typename OutputIter>
812 void summary_data_row(OutputIter first)
const 814 double missing_data = std::numeric_limits<double>::quiet_NaN();
817 for (
const auto &m : monitor_)
818 if (m.second.iter_size() > 0)
819 miter.push_back(std::make_pair(0, &m.second));
821 for (std::size_t iter = 0; iter !=
iter_size(); ++iter) {
822 *first++ = ess_history_[iter];
823 for (
auto &m : miter) {
824 std::size_t md = m.second->dim();
825 if (m.first != m.second->iter_size() &&
826 iter == m.second->index(m.first)) {
828 m.second->record_data(m.first++), md, first);
830 first = std::fill_n(first, md, missing_data);
836 template <
typename OutputIter>
837 void summary_data_col(OutputIter first)
const 839 double missing_data = std::numeric_limits<double>::quiet_NaN();
841 first = std::copy(ess_history_.begin(), ess_history_.end(), first);
842 for (
const auto &m : monitor_) {
843 if (m.second.iter_size() > 0) {
844 for (std::size_t d = 0; d != m.second.dim(); ++d) {
845 std::size_t miter = 0;
846 for (std::size_t iter = 0; iter !=
iter_size(); ++iter) {
847 if (miter != m.second.iter_size() ||
848 iter == m.second.index(miter)) {
849 *first++ = m.second.record(d, miter++);
851 *first++ = missing_data;
860 template <
typename CharT,
typename Traits,
typename T>
862 std::basic_ostream<CharT, Traits> &os,
const Sampler<T> &sampler)
864 return sampler.
print(os);
869 #endif // VSMC_CORE_SAMPLER_HPP Residual stratified resampling.
static SeedGenerator< ID, ResultType > & instance()
Particle class representing the whole particle set.
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.
void summary_data_int(OutputIter first) const
Sampler summary data (integer data)
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
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.
#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.
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.
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)
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.
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.
double resample_threshold() const
Get resampling threshold.
std::function< std::size_t(std::size_t, Particle< T > &)> mcmc_type
#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.
std::function< void(std::size_t, std::size_t, rng_type &, const double *, size_type *)> resample_type
Systematic resampling on residuals.
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.
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
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.)
void resize(std::array< T, N > &, std::size_t)
Monitor evaluated after MCMC moves.
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.