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));
785 std::size_t ia = do_move(0);
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.