vSMC  v3.0.0
Scalable Monte Carlo
monitor.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/core/monitor.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_CORE_MONITOR_HPP
33 #define VSMC_CORE_MONITOR_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #define VSMC_RUNTIME_ASSERT_CORE_MONITOR_ID(func) \
38  VSMC_RUNTIME_ASSERT( \
39  (id < dim()), "**Monitor::" #func "** INVALID ID NUMBER ARGUMENT")
40 
41 #define VSMC_RUNTIME_ASSERT_CORE_MONITOR_ITER(func) \
42  VSMC_RUNTIME_ASSERT((iter < iter_size()), \
43  "**Monitor::" #func "** INVALID ITERATION NUMBER ARGUMENT")
44 
45 #define VSMC_RUNTIME_ASSERT_CORE_MONITOR_EVAL \
46  VSMC_RUNTIME_ASSERT(eval_, "**Monitor::eval** INVALID EVALUATION OBJECT")
47 
48 namespace vsmc
49 {
50 
57 }; // enum MonitorStage
58 
61 template <typename T>
62 class Monitor
63 {
64  public:
65  using eval_type =
66  std::function<void(std::size_t, std::size_t, Particle<T> &, double *)>;
67 
68  Monitor(std::size_t dim, const eval_type &eval, bool record_only = false,
70  : dim_(dim)
71  , eval_(eval)
72  , record_only_(record_only)
73  , stage_(stage)
74  , name_(dim)
75  {
76  internal::size_check<VSMC_BLAS_INT>(dim_, "Monitor::Monitor");
77  }
78 
80  std::size_t dim() const { return dim_; }
81 
83  bool record_only() const { return record_only_; }
84 
86  MonitorStage stage() const { return stage_; }
87 
89  std::size_t iter_size() const { return index_.size(); }
90 
92  void reserve(std::size_t num)
93  {
94  index_.reserve(num);
95  record_.reserve(dim_ * num);
96  }
97 
99  bool empty() const { return !eval_; }
100 
108  std::string &name(std::size_t id)
109  {
111 
112  return name_[id];
113  }
114 
116  const std::string &name(std::size_t id) const
117  {
119 
120  return name_[id];
121  }
122 
124  std::size_t index() const
125  {
126  std::size_t iter = iter_size() > 0 ? iter_size() - 1 : iter_size();
128 
129  return index_[iter];
130  }
131 
141  std::size_t index(std::size_t iter) const
142  {
144 
145  return index_[iter];
146  }
147 
149  template <typename OutputIter>
150  OutputIter read_index(OutputIter first) const
151  {
152  return std::copy(index_.begin(), index_.end(), first);
153  }
154 
157  double record(std::size_t id) const
158  {
159  std::size_t iter = iter_size() > 0 ? iter_size() - 1 : iter_size();
162 
163  return record_[iter * dim_ + id];
164  }
165 
168  double record(std::size_t id, std::size_t iter) const
169  {
172 
173  return record_[iter * dim_ + id];
174  }
175 
178  template <typename OutputIter>
179  OutputIter read_record(std::size_t id, OutputIter first) const
180  {
182 
183  const std::size_t N = iter_size();
184  const double *riter = record_.data() + id;
185  for (std::size_t i = 0; i != N; ++i, ++first, riter += dim_)
186  *first = *riter;
187 
188  return first;
189  }
190 
193  template <typename OutputIter>
194  OutputIter read_record_matrix(MatrixLayout layout, OutputIter first) const
195  {
196  if (layout == RowMajor)
197  return std::copy(record_.begin(), record_.end(), first);
198 
199  if (layout == ColMajor) {
200  for (std::size_t d = 0; d != dim_; ++d)
201  for (std::size_t i = 0; i != iter_size(); ++i)
202  *first++ = record(d, i);
203  }
204 
205  return first;
206  }
207 
209  std::map<std::string, Vector<double>> summary() const
210  {
211  std::map<std::string, Vector<double>> df;
212  Vector<double> data(iter_size());
213 
214  std::copy(index_.begin(), index_.end(), data.begin());
215  df["Index"] = data;
216 
217  for (std::size_t d = 0; d != dim_; ++d) {
218  for (std::size_t i = 0; i != iter_size(); ++i)
219  data[i] = record(d, i);
220  if (name_[d].empty())
221  df["X." + std::to_string(d)] = data;
222  else
223  df[name_[d]] = data;
224  }
225 
226  return df;
227  }
228 
230  void eval(const eval_type &new_eval, bool record_only = false,
232  {
233  eval_ = new_eval;
234  record_only_ = record_only;
235  stage_ = stage;
236  }
237 
241  std::size_t iter, Particle<T> &particle, MonitorStage stage)
242  {
243  internal::size_check<VSMC_BLAS_INT>(particle.size(), "Monitor::eval");
244 
245  if (stage != stage_)
246  return;
247 
249 
250  result_.resize(dim_);
251  if (record_only_) {
252  eval_(iter, dim_, particle, result_.data());
253  push_back(iter);
254 
255  return;
256  }
257 
258  const std::size_t N = static_cast<std::size_t>(particle.size());
259  buffer_.resize(N * dim_);
260  eval_(iter, dim_, particle, buffer_.data());
261  internal::cblas_dgemv(internal::CblasColMajor, internal::CblasNoTrans,
262  static_cast<VSMC_BLAS_INT>(dim_), static_cast<VSMC_BLAS_INT>(N),
263  1.0, buffer_.data(), static_cast<VSMC_BLAS_INT>(dim_),
264  particle.weight().data(), 1, 0.0, result_.data(), 1);
265  push_back(iter);
266  }
267 
269  void clear()
270  {
271  index_.clear();
272  record_.clear();
273  }
274 
275  private:
276  std::size_t dim_;
277  eval_type eval_;
278  bool record_only_;
279  MonitorStage stage_;
280  Vector<std::string> name_;
281  Vector<std::size_t> index_;
282  Vector<double> record_;
283  Vector<double> result_;
284  Vector<double> buffer_;
285 
286  void push_back(std::size_t iter)
287  {
288  index_.push_back(iter);
289  record_.insert(record_.end(), result_.begin(), result_.end());
290  }
291 }; // class Monitor
292 
293 } // namespace vsmc
294 
295 #endif // VSMC_CORE_MONITOR_HPP
std::vector< T, Alloc > Vector
std::vector with Allocator as default allocator
bool empty() const
Whether the evaluation object is valid.
Definition: monitor.hpp:99
#define VSMC_RUNTIME_ASSERT_CORE_MONITOR_EVAL
Definition: monitor.hpp:45
Definition: monitor.hpp:48
Particle class representing the whole particle set.
Definition: particle.hpp:83
#define VSMC_BLAS_INT
Definition: cblas.hpp:42
bool record_only() const
If this is a record only Monitor.
Definition: monitor.hpp:83
MonitorStage
Monitor stage.
Definition: monitor.hpp:53
MatrixLayout
Matrix layout.
Definition: defines.hpp:51
void clear()
Clear all records of the index and integrations.
Definition: monitor.hpp:269
weight_type & weight()
Read and write access to the weight collection object.
Definition: particle.hpp:174
std::map< std::string, Vector< double > > summary() const
Summary of monitor history.
Definition: monitor.hpp:209
OutputIter read_index(OutputIter first) const
Read the index history through an output iterator.
Definition: monitor.hpp:150
void reserve(std::size_t num)
Reserve space for a specified number of iterations.
Definition: monitor.hpp:92
Monitor evaluated after moves.
Definition: monitor.hpp:54
#define VSMC_RUNTIME_ASSERT_CORE_MONITOR_ITER(func)
Definition: monitor.hpp:41
Monitor(std::size_t dim, const eval_type &eval, bool record_only=false, MonitorStage stage=MonitorMCMC)
Definition: monitor.hpp:68
std::size_t dim() const
The dimension of the Monitor.
Definition: monitor.hpp:80
std::size_t index() const
Get the latest iteration index of the sampler.
Definition: monitor.hpp:124
std::size_t iter_size() const
The number of iterations has been recorded.
Definition: monitor.hpp:89
void eval(const eval_type &new_eval, bool record_only=false, MonitorStage stage=MonitorMCMC)
Set a new evaluation object of type eval_type.
Definition: monitor.hpp:230
OutputIter read_record_matrix(MatrixLayout layout, OutputIter first) const
Read the record history of all variables as a matrix through an output iterator.
Definition: monitor.hpp:194
std::string & name(std::size_t id)
Read and write access to the names of variables.
Definition: monitor.hpp:108
void operator()(std::size_t iter, Particle< T > &particle, MonitorStage stage)
Perform the evaluation for a given iteration and a Particle<T> object.
Definition: monitor.hpp:240
const std::string & name(std::size_t id) const
Read only access to the names of variables.
Definition: monitor.hpp:116
std::size_t index(std::size_t iter) const
Get the iteration index of the sampler of a given Monitor iteration.
Definition: monitor.hpp:141
MonitorStage stage() const
The stage of the Montior.
Definition: monitor.hpp:86
double record(std::size_t id) const
Get the latest Monte Carlo integration record of a given variable.
Definition: monitor.hpp:157
Monitor evaluated after MCMC moves.
Definition: monitor.hpp:56
Monitor for Monte Carlo integration.
Definition: monitor.hpp:62
#define VSMC_RUNTIME_ASSERT_CORE_MONITOR_ID(func)
Definition: monitor.hpp:37
size_type size() const
Number of particles.
Definition: particle.hpp:120
std::function< void(std::size_t, std::size_t, Particle< T > &, double *)> eval_type
Definition: monitor.hpp:66
double record(std::size_t id, std::size_t iter) const
Get the Monte Carlo integration record of a given variable and the Monitor iteration.
Definition: monitor.hpp:168
OutputIter read_record(std::size_t id, OutputIter first) const
Read the record history for a given variable through an output iterator.
Definition: monitor.hpp:179
Monitor evaluated after resampling.
Definition: monitor.hpp:55