Tomographer  v1.0a
Tomographer C++ Framework Documentation
mhrwtasks.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2015 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_MHWALKER_TASKS_H
28 #define TOMOGRAPHER_MHWALKER_TASKS_H
29 
37 #include <string>
38 #include <limits>
39 #include <random>
40 
41 #include <tomographer/tools/fmt.h>
42 #include <tomographer/mhrw.h>
43 #include <tomographer/multiproc.h> // StatusReport Base
44 
45 
46 namespace Tomographer {
47 
48 
55 namespace MHRWTasks
56 {
57 
67  template<typename CountIntType_ = unsigned int, typename RealType_ = double>
68  struct CDataBase
69  {
76  CDataBase(int base_seed_ = 0)
77  : base_seed(base_seed_)
78  {
79  }
80 
82  typedef CountIntType_ CountIntType;
84  typedef RealType_ RealType;
85 
87  CountIntType n_sweep;
89  CountIntType n_therm;
91  CountIntType n_run;
93  RealType step_size;
94 
110  };
111 
123  template<typename MHRWStatsCollectorResultType_, typename CountIntType>
125  {
126  typedef MHRWStatsCollectorResultType_ MHRWStatsCollectorResultType;
127 
128  template<typename MHRWStatsCollectorResultTypeInit, typename MHRandomWalkType>
129  MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit && stats_collector_result_,
130  const MHRandomWalkType & mhrandomwalk)
131  : stats_collector_result(std::forward<MHRWStatsCollectorResultTypeInit>(stats_collector_result_)),
132  n_sweep(mhrandomwalk.n_sweep()),
133  n_therm(mhrandomwalk.n_therm()),
134  n_run(mhrandomwalk.n_run()),
135  step_size(mhrandomwalk.step_size()),
136  acceptance_ratio(mhrandomwalk.acceptance_ratio())
137  {
138  }
139 
140  const MHRWStatsCollectorResultType stats_collector_result;
141 
142  const CountIntType n_sweep;
143  const CountIntType n_therm;
144  const CountIntType n_run;
145  const double step_size;
146  const double acceptance_ratio;
147  };
148 
159  template<typename MHRandomWalkTaskCData,
160  typename Rng = std::mt19937>
162  {
163  typedef typename MHRandomWalkTaskCData::CountIntType CountIntType;
164 
169  typedef MHRandomWalkTaskResult<typename MHRandomWalkTaskCData::MHRWStatsCollectorResultType,
170  CountIntType> Result;
171 
180  {
182  StatusReport(double fdone = 0.0, const std::string & msg = std::string(),
183  CountIntType kstep_ = 0, CountIntType n_sweep_ = 0,
184  CountIntType n_therm_ = 0, CountIntType n_run_ = 0,
185  double acceptance_ratio_ = 0.0)
186  : MultiProc::StatusReport(fdone, msg),
187  kstep(kstep_),
188  n_sweep(n_sweep_),
189  n_therm(n_therm_),
190  n_run(n_run_),
191  acceptance_ratio(acceptance_ratio_),
193  {
194  }
196  CountIntType kstep;
198  CountIntType n_sweep;
200  CountIntType n_therm;
202  CountIntType n_run;
213  CountIntType n_total_iters;
214  };
219 
220  private:
222  typename Rng::result_type _seed;
223 
231  Result * result;
232 
233  public:
234 
243  static inline int get_input(int k, const MHRandomWalkTaskCData * pcdata)
244  {
245  return pcdata->base_seed + k;
246  }
247 
253  template<typename LoggerType>
254  MHRandomWalkTask(int inputseed, const MHRandomWalkTaskCData * /*pcdata*/, LoggerType & logger)
255  : _seed(inputseed), result(NULL)
256  {
257  logger.longdebug("MHRandomWalkTask", "() inputseed=%d", inputseed);
258  }
259 
261  {
262  if (result != NULL) {
263  delete result;
264  }
265  }
266 
267 
277  template<typename LoggerType, typename TaskManagerIface>
278  inline void run(const MHRandomWalkTaskCData * pcdata, LoggerType & logger,
279  TaskManagerIface * tmgriface)
280  {
281  Rng rng(_seed); // seeded random number generator
282 
283  // the user's stats collector
284  auto stats = pcdata->createStatsCollector(logger);
285  typedef decltype(stats) MHRWStatsCollectorType;
286 
287  // our own "stats collector" which checks if we need to send a status report back
288  typedef StatusReportCheck<TaskManagerIface, MHRWStatsCollectorType> OurStatusReportCheck;
289  OurStatusReportCheck statreportcheck(this, &stats, tmgriface);
290 
292  OurStatsCollectors;
293  OurStatsCollectors ourstatscollectors(stats, statreportcheck);
294 
295  auto mhwalker = pcdata->createMHWalker(rng, logger);
296  typedef decltype(mhwalker) MHWalkerType;
297 
299  // MH random walk parameters
300  pcdata->n_sweep,
301  pcdata->n_therm,
302  pcdata->n_run,
303  pcdata->step_size,
304  // the MHWalker
305  mhwalker,
306  // our stats collectors
307  ourstatscollectors,
308  // a random number generator
309  rng,
310  // and a logger
311  logger
312  );
313 
314  rwalk.run();
315 
316  result = new Result(stats.getResult(), rwalk);
317  }
318 
319  inline const Result & getResult() const
320  {
321  return *result;
322  }
323 
324  private:
330  template<typename TaskManagerIface, typename MHRWStatsCollectorType>
331  struct StatusReportCheck
332  {
333  StatusReportCheck(MHRandomWalkTask * mhrwtask_, MHRWStatsCollectorType * stats_, TaskManagerIface *tmgriface_)
334  : mhrwtask(mhrwtask_), stats(stats_), tmgriface(tmgriface_)
335  { }
336 
337  MHRandomWalkTask *mhrwtask;
338  MHRWStatsCollectorType *stats;
339  TaskManagerIface *tmgriface;
340 
341  inline void init() { }
342  inline void thermalizing_done() { }
343  inline void done() { }
344 
345  template<typename PointType, typename FnValueType, typename MHRandomWalk>
346  inline void raw_move(
347  CountIntType k, bool is_thermalizing, bool, bool, double, const PointType &, FnValueType,
348  const PointType &, FnValueType, MHRandomWalk & rw
349  )
350  {
351  // see if we should provide a status report
352  // fprintf(stderr, "StatusReportCheck::raw_move(): testing for status report requested!\n");
353  if (tmgriface->status_report_requested()) {
354  // prepare & provide status report
355  CountIntType totiters = rw.n_sweep()*(rw.n_therm()+rw.n_run());
356  double fdone = (double)k/totiters;
357  double accept_ratio = std::numeric_limits<double>::quiet_NaN();
358  bool warn_accept_ratio = false;
359  if (rw.has_acceptance_ratio()) {
360  accept_ratio = rw.acceptance_ratio();
361  warn_accept_ratio = (accept_ratio > 0.35 || accept_ratio < 0.2);
362  }
363  std::string msg = Tools::fmts(
364  "%s %lu/(%lu=%lu*(%lu+%lu)) : %5.2f%% done [%saccept ratio=%.2f%s]",
365  ( ! is_thermalizing
366  ? "iteration"
367  : "[therm.] "),
368  (unsigned long)k, (unsigned long)totiters, (unsigned long)rw.n_sweep(),
369  (unsigned long)rw.n_therm(), (unsigned long)rw.n_run(),
370  fdone*100.0,
371  warn_accept_ratio ? "!!** " : "",
372  accept_ratio,
373  warn_accept_ratio ? " **!!" : ""
374  );
375  typedef MHRWStatsCollectorStatus<MHRWStatsCollectorType> MHRWStatsCollectorStatusType;
376  if (MHRWStatsCollectorStatusType::CanProvideStatus) {
377  std::string nlindent = "\n ";
378  msg += nlindent;
379  std::string s = MHRWStatsCollectorStatusType::getStatus(stats);
380  for (std::size_t j = 0; j < s.size(); ++j) {
381  if (s[j] == '\n') {
382  msg += nlindent;
383  } else {
384  msg += s[j];
385  }
386  }
387  }
388  tmgriface->submit_status_report(StatusReport(fdone, msg, k, rw.n_sweep(), rw.n_therm(),
389  rw.n_run(), accept_ratio));
390  }
391  // fprintf(stderr, "StatusReportCheck::raw_move(): done\n");
392  }
393 
394  template<typename PointType, typename FnValueType, typename MHRandomWalk>
395  inline void process_sample(CountIntType, CountIntType, const PointType &, FnValueType, MHRandomWalk &)
396  {
397  }
398  };
399  };
400 
401 
402 
403 } // MHWalkerTasks
404 
405 
406 
407 } // namespace Tomographer
408 
409 
410 
411 #endif
A Metropolis-Hastings Random Walk.
Definition: mhrw.h:303
Utilities for formatting strings.
static int get_input(int k, const MHRandomWalkTaskCData *pcdata)
Returns a random seed to seed the random number generator with for run number k.
Definition: mhrwtasks.h:243
double acceptance_ratio
the current acceptance ratio of the random walk (see Tomographer::MHRandomWalk::acceptance_ratio() ) ...
Definition: mhrwtasks.h:206
Base namespace for the Tomographer project.
Definition: dmmhrw.h:51
StatusReport(double fdone=0.0, const std::string &msg=std::string(), CountIntType kstep_=0, CountIntType n_sweep_=0, CountIntType n_therm_=0, CountIntType n_run_=0, double acceptance_ratio_=0.0)
Constructor which initializes all fields.
Definition: mhrwtasks.h:182
CountIntType n_therm
the number of thermalization sweeps (see MHRandomWalk)
Definition: mhrwtasks.h:200
MHRandomWalkTask(int inputseed, const MHRandomWalkTaskCData *, LoggerType &logger)
Constructs the MHRandomWalkTask.
Definition: mhrwtasks.h:254
void run(const MHRandomWalkTaskCData *pcdata, LoggerType &logger, TaskManagerIface *tmgriface)
Run this task.
Definition: mhrwtasks.h:278
Random Walk task, collecting statistics.
Definition: mhrwtasks.h:161
STL class.
Data needed to be accessible to the working code.
Definition: mhrwtasks.h:68
CountIntType kstep
the current iteration number
Definition: mhrwtasks.h:196
CDataBase(int base_seed_=0)
Constructor.
Definition: mhrwtasks.h:76
RealType step_size
Parameter of the random walk – step size of the random walk.
Definition: mhrwtasks.h:93
CountIntType n_sweep
the number of iterations that form a sweep (see MHRandomWalk)
Definition: mhrwtasks.h:198
CountIntType n_run
the number of live run sweeps (see MHRandomWalk)
Definition: mhrwtasks.h:202
MHRandomWalkTaskResult< typename MHRandomWalkTaskCData::MHRWStatsCollectorResultType, CountIntType > Result
Result type of a single task run.
Definition: mhrwtasks.h:170
Status Report for a MHRandomWalkTask.
Definition: mhrwtasks.h:179
CountIntType n_therm
Parameter of the random walk – number of thermalizing sweeps.
Definition: mhrwtasks.h:89
T size(T...args)
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:122
CountIntType n_total_iters
the total number of iterations required for this random walk
Definition: mhrwtasks.h:213
Some common definitions for multiprocessing interfaces.
CountIntType n_sweep
Parameter of the random walk – number of iterations per sweep.
Definition: mhrwtasks.h:87
StatusReport StatusReportType
Typedef for StatusReport. This is needed by, e.g. MultiProc::OMP::TaskDispatcher. ...
Definition: mhrwtasks.h:218
T quiet_NaN(T...args)
CountIntType n_run
Parameter of the random walk – number of "live" sweeps.
Definition: mhrwtasks.h:91
Routines for performing a Metropolis-Hastings random walk.
CountIntType_ CountIntType
Type used to count the number of iterations.
Definition: mhrwtasks.h:82
Basic status report class.
Definition: multiproc.h:64
int base_seed
A base random seed from which each run seed will be derived.
Definition: mhrwtasks.h:109
A simple MHRWStatsCollector interface which combines several stats collectors.
Definition: mhrw.h:583
RealType_ RealType
Type used to specify the step size.
Definition: mhrwtasks.h:84