Loading [MathJax]/extensions/tex2jax.js
Tomographerv4.1
Tomographer C++ Framework Documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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) 2016 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  * Copyright (c) 2017 Caltech, Institute for Quantum Information and Matter, Philippe Faist
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #ifndef TOMOGRAPHER_MHWALKER_TASKS_H
29 #define TOMOGRAPHER_MHWALKER_TASKS_H
30 
38 #include <string>
39 #include <limits>
40 #include <random>
41 #include <sstream>
42 
43 #include <tomographer/tools/fmt.h>
45 #include <tomographer/mhrw.h>
47 #include <tomographer/multiproc.h> // StatusReport Base
48 
49 
50 namespace Tomographer {
51 namespace MHRWTasks {
52 
53 
63 template<typename IterCountIntType_ = int, typename StepRealType_ = double>
64 TOMOGRAPHER_EXPORT struct CDataBase
65 {
72  template<typename MHRWParamsType>
73  CDataBase(MHRWParamsType&& p, int base_seed_ = 0)
74  : mhrw_params(std::forward<MHRWParamsType>(p)), base_seed(base_seed_)
75  {
76  }
77 
79  typedef IterCountIntType_ IterCountIntType;
81  typedef StepRealType_ StepRealType;
82 
89 
97  const MHRWParamsType mhrw_params;
98 
113  const int base_seed;
114 
124  inline int getTaskInput(int k) const
125  {
126  return base_seed + k;
127  }
128 
129 
132  inline void printBasicCDataMHRWInfo(std::ostream & str) const
133  {
134  str << "\tstep size = " << std::setprecision(4) << mhrw_params.step_size << "\n"
135  << "\t# iter. / sweep = " << mhrw_params.n_sweep << "\n"
136  << "\t# therm. sweeps = " << mhrw_params.n_therm << "\n"
137  << "\t# run sweeps = " << mhrw_params.n_run << "\n";
138  }
143  {
146  return ss.str();
147  }
148 };
149 
161 template<typename MHRWStatsCollectorResultType_, typename IterCountIntType, typename StepRealType>
162 TOMOGRAPHER_EXPORT struct MHRandomWalkTaskResult
163  : public virtual Tools::NeedOwnOperatorNew<MHRWStatsCollectorResultType_>::ProviderType
164 {
167  typedef MHRWStatsCollectorResultType_ MHRWStatsCollectorResultType;
168 
172 
177  : stats_collector_result(), mhrw_params(),
178  acceptance_ratio(std::numeric_limits<double>::quiet_NaN())
179  {
180  }
181 
189  template<typename MHRWStatsCollectorResultTypeInit,
190  typename MHRWParamsType2>
191  MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit && stats_collector_result_,
192  MHRWParamsType2 && mhrw_params_,
193  double acceptance_ratio_)
194  : stats_collector_result(std::forward<MHRWStatsCollectorResultTypeInit>(stats_collector_result_)),
195  mhrw_params(std::forward<MHRWParamsType2>(mhrw_params_)),
196  acceptance_ratio(acceptance_ratio_)
197  {
198  }
199 
205  template<typename MHRWStatsCollectorResultTypeInit, typename MHRandomWalkType>
206  MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit && stats_collector_result_,
207  const MHRandomWalkType & mhrandomwalk)
208  : stats_collector_result(std::forward<MHRWStatsCollectorResultTypeInit>(stats_collector_result_)),
209  mhrw_params(mhrandomwalk.mhrwParams()),
210  acceptance_ratio(mhrandomwalk.hasAcceptanceRatio() ?
211  mhrandomwalk.acceptanceRatio() :
212  std::numeric_limits<double>::quiet_NaN())
213  {
214  }
215 
217  const MHRWStatsCollectorResultType stats_collector_result;
218 
220  const MHRWParamsType mhrw_params;
221 
223  const double acceptance_ratio;
224 };
225 
226 
236 template<typename MHRandomWalkTaskCData,
237  typename Rng = std::mt19937>
238 TOMOGRAPHER_EXPORT struct MHRandomWalkTask
239 {
241  typedef typename MHRandomWalkTaskCData::IterCountIntType IterCountIntType;
243  typedef typename MHRandomWalkTaskCData::StepRealType StepRealType;
244 
247 
252  typedef MHRandomWalkTaskResult<typename MHRandomWalkTaskCData::MHRWStatsCollectorResultType,
253  IterCountIntType, StepRealType> ResultType;
254 
264  {
266  StatusReport(double fdone = 0.0, const std::string & msg = std::string(),
267  IterCountIntType kstep_ = 0, MHRWParamsType mhrw_params_ = MHRWParamsType(),
268  double acceptance_ratio_ = 0.0)
269  : MultiProc::TaskStatusReport(fdone, msg),
270  kstep(kstep_),
271  mhrw_params(mhrw_params_),
272  acceptance_ratio(acceptance_ratio_),
273  n_total_iters(mhrw_params.n_sweep*(mhrw_params.n_therm + mhrw_params.n_run))
274  {
275  }
276 
278  IterCountIntType kstep;
279 
288  MHRWParamsType mhrw_params;
289 
294 
301  IterCountIntType n_total_iters;
302  };
307 
308 private:
310  typename Rng::result_type _seed;
311 
319  ResultType * result;
320 
321 public:
322 
328  template<typename LoggerType>
329  MHRandomWalkTask(int inputseed, const MHRandomWalkTaskCData * /*pcdata*/, LoggerType & logger)
330  : _seed(inputseed), result(NULL)
331  {
332  logger.longdebug("MHRandomWalkTask", "() inputseed=%d", inputseed);
333  }
334 
336  {
337  if (result != NULL) {
338  delete result;
339  }
340  }
341 
342 
352  template<typename LoggerType, typename TaskManagerIface>
353  inline void run(const MHRandomWalkTaskCData * pcdata, LoggerType & logger,
354  TaskManagerIface * tmgriface)
355  {
356  Rng rng(_seed); // seeded random number generator
357 
358  logger.longdebug("Tomographer::MHRWTasks::run()", "about to construct stats collector.");
359 
360  // the user's stats collector
361  auto stats = pcdata->createStatsCollector(logger);
362  typedef decltype(stats) MHRWStatsCollectorType;
363 
364  logger.longdebug("Tomographer::MHRWTasks::run()", "stats collector constructed.");
365 
366  // our own "stats collector" which checks if we need to send a status report back
367  typedef StatusReportCheck<TaskManagerIface, MHRWStatsCollectorType> OurStatusReportCheck;
368  OurStatusReportCheck statreportcheck(this, &stats, tmgriface);
369 
371  OurStatsCollectors;
372  OurStatsCollectors ourstatscollectors(stats, statreportcheck);
373 
374  logger.longdebug("Tomographer::MHRWTasks::run()", "about to create MH walker object.");
375 
376  auto mhwalker = pcdata->createMHWalker(rng, logger);
377  typedef decltype(pcdata->createMHWalker(rng, logger)) MHWalkerType;
378 
379  logger.longdebug("Tomographer::MHRWTasks::run()", "MHWalker object created.");
380 
382  // MH random walk parameters
383  pcdata->mhrw_params,
384  // the MHWalker
385  mhwalker,
386  // our stats collectors
387  ourstatscollectors,
388  // a random number generator
389  rng,
390  // and a logger
391  logger
392  );
393 
394  logger.longdebug("Tomographer::MHRWTasks::run()", "MHRandomWalk object created, running...");
395 
396  rwalk.run();
397 
398  logger.longdebug("Tomographer::MHRWTasks::run()", "MHRandomWalk run finished.");
399 
400  result = new ResultType(stats.getResult(), rwalk);
401  }
402 
403  inline const ResultType & getResult() const
404  {
405  return *result;
406  }
407 
408 private:
414  template<typename TaskManagerIface, typename MHRWStatsCollectorType>
415  struct StatusReportCheck
416  {
417  StatusReportCheck(MHRandomWalkTask * mhrwtask_, MHRWStatsCollectorType * stats_, TaskManagerIface *tmgriface_)
418  : mhrwtask(mhrwtask_), stats(stats_), tmgriface(tmgriface_)
419  { }
420 
421  MHRandomWalkTask *mhrwtask;
422  MHRWStatsCollectorType *stats;
423  TaskManagerIface *tmgriface;
424 
425  inline void init() { }
426  inline void thermalizingDone() { }
427  inline void done() { }
428 
429  template<typename PointType, typename FnValueType, typename MHRandomWalk>
430  inline void rawMove(
431  IterCountIntType k, bool is_thermalizing, bool, bool, double, const PointType &, FnValueType,
432  const PointType &, FnValueType, MHRandomWalk & rw
433  )
434  {
435  // see if we should provide a status report
436  // fprintf(stderr, "StatusReportCheck::rawMove(): testing for status report requested!\n");
437  // only check once per sweep, to speed up things
438  if ((k % rw.nSweep() == 0) && tmgriface->statusReportRequested()) {
439  // prepare & provide status report
440  IterCountIntType totiters = rw.nSweep()*(rw.nTherm()+rw.nRun());
441  // k restarts at zero after thermalization, so account for that:
442  IterCountIntType kreal = is_thermalizing ? k : k + rw.nSweep()*rw.nTherm();
443  double fdone = (double)kreal/totiters;
444  double accept_ratio = std::numeric_limits<double>::quiet_NaN();
445  bool warn_accept_ratio = false;
446  if (rw.hasAcceptanceRatio()) {
447  accept_ratio = rw.acceptanceRatio();
448  warn_accept_ratio = (accept_ratio > MHRWAcceptanceRatioRecommendedMax ||
449  accept_ratio < MHRWAcceptanceRatioRecommendedMin);
450  }
451  std::string msg = Tools::fmts(
452  "%s %lu/(%lu=%lu*(%lu+%lu)) : %5.2f%% done [%saccept ratio=%.2f%s]",
453  ( ! is_thermalizing
454  ? "iteration"
455  : "[therm.] "),
456  (unsigned long)kreal, (unsigned long)totiters, (unsigned long)rw.nSweep(),
457  (unsigned long)rw.nTherm(), (unsigned long)rw.nRun(),
458  fdone*100.0,
459  warn_accept_ratio ? "!!** " : "",
460  accept_ratio,
461  warn_accept_ratio ? " **!!" : ""
462  );
463  typedef MHRWStatsCollectorStatus<MHRWStatsCollectorType> MHRWStatsCollectorStatusType;
464  if (MHRWStatsCollectorStatusType::CanProvideStatus) {
465  std::string nlindent = "\n ";
466  msg += nlindent;
467  std::string s = MHRWStatsCollectorStatusType::getStatus(stats);
468  for (std::size_t j = 0; j < s.size(); ++j) {
469  if (s[j] == '\n') {
470  msg += nlindent;
471  } else {
472  msg += s[j];
473  }
474  }
475  }
476  tmgriface->submitStatusReport(StatusReport(fdone, msg, kreal, rw.mhrwParams(), accept_ratio));
477  }
478  // fprintf(stderr, "StatusReportCheck::rawMove(): done\n");
479  }
480 
481  template<typename PointType, typename FnValueType, typename MHRandomWalk>
482  inline void processSample(IterCountIntType, IterCountIntType, const PointType &, FnValueType, MHRandomWalk &)
483  {
484  }
485  };
486 };
487 
488 
489 
490 } // MHWalkerTasks
491 
492 
493 
494 } // namespace Tomographer
495 
496 
497 
498 #endif
A Metropolis-Hastings Random Walk.
Definition: mhrw.h:290
MHRandomWalkTaskResult< typename MHRandomWalkTaskCData::MHRWStatsCollectorResultType, IterCountIntType, StepRealType > ResultType
Result type of a single task run.
Definition: mhrwtasks.h:253
Utilities for formatting strings.
int getTaskInput(int k) const
Returns a random seed to seed the random number generator with for run number k.
Definition: mhrwtasks.h:124
void printBasicCDataMHRWInfo(std::ostream &str) const
Get some human-readable info about the random walk as a string.
Definition: mhrwtasks.h:132
StatusReport(double fdone=0.0, const std::string &msg=std::string(), IterCountIntType kstep_=0, MHRWParamsType mhrw_params_=MHRWParamsType(), double acceptance_ratio_=0.0)
Constructor which initializes all fields.
Definition: mhrwtasks.h:266
CountIntType nTherm() const
Number of thermalizing sweeps.
Definition: mhrw.h:403
MHRWParamsType mhrw_params
the parameters of the random walk
Definition: mhrwtasks.h:288
double acceptance_ratio
the current acceptance ratio of the random walk (see Tomographer::MHRandomWalk::acceptanceRatio() ) ...
Definition: mhrwtasks.h:293
Base namespace for the Tomographer project.
Definition: densellh.h:45
const MHRWParamsType mhrw_params
The parameters of the random walk (see MHRWParams<IterCountIntType,StepRealType>) ...
Definition: mhrwtasks.h:220
CountIntType n_therm
Number of thermalization sweeps.
Definition: mhrw.h:230
CountIntType n_run
Number of live sweeps.
Definition: mhrw.h:234
const double MHRWAcceptanceRatioRecommendedMin
Minimal recommended acceptance ratio.
Definition: mhrw.h:195
CountIntType nSweep() const
Number of iterations in a sweep.
Definition: mhrw.h:401
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
STL namespace.
std::string getBasicCDataMHRWInfo() const
Get some human-readable info about the random walk as a string, see printBasicCDataMHRWInfo() ...
Definition: mhrwtasks.h:142
const MHRWParamsType mhrw_params
Parameters of the random walk.
Definition: mhrwtasks.h:97
MHRandomWalkTask(int inputseed, const MHRandomWalkTaskCData *, LoggerType &logger)
Constructs the MHRandomWalkTask.
Definition: mhrwtasks.h:329
void run(const MHRandomWalkTaskCData *pcdata, LoggerType &logger, TaskManagerIface *tmgriface)
Run this task.
Definition: mhrwtasks.h:353
StepRealType step_size
The step size of the random walk.
Definition: mhrw.h:222
Random Walk task, collecting statistics.
Definition: mhrwtasks.h:238
MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit &&stats_collector_result_, const MHRandomWalkType &mhrandomwalk)
Constructor with mhrw_params initialized from a random walk instance.
Definition: mhrwtasks.h:206
STL class.
MHRandomWalkTaskResult()
Construct an empty task result.
Definition: mhrwtasks.h:176
CountIntType nRun() const
Number of live run sweeps.
Definition: mhrw.h:405
MHRWParams< IterCountIntType, StepRealType > MHRWParamsType
Type to store the parameters of the Metropolis-Hastings random walk (number of runs, sweep size, etc.)
Definition: mhrwtasks.h:88
Data needed to be accessible to the working code.
Definition: mhrwtasks.h:64
MHRWParams< IterCountIntType, StepRealType > MHRWParamsType
Type to stores the parameters of the random walk.
Definition: mhrwtasks.h:246
const double MHRWAcceptanceRatioRecommendedMax
Maximal recommended acceptance ratio.
Definition: mhrw.h:197
MHRandomWalkTaskCData::StepRealType StepRealType
The type used to describe a step size (see MHRWParams)
Definition: mhrwtasks.h:243
const MHRWStatsCollectorResultType stats_collector_result
The result furnished by the stats collector itself.
Definition: mhrwtasks.h:217
MHRWStatsCollectorResultType_ MHRWStatsCollectorResultType
The specified result type of the MHRWStatsCollector the task will be looking at.
Definition: mhrwtasks.h:167
T str(T... args)
RatioType acceptanceRatio() const
Return the acceptance ratio so far.
Definition: mhrw.h:419
MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit &&stats_collector_result_, MHRWParamsType2 &&mhrw_params_, double acceptance_ratio_)
Constructor, initializes fields to the given values.
Definition: mhrwtasks.h:191
CDataBase(MHRWParamsType &&p, int base_seed_=0)
Constructor.
Definition: mhrwtasks.h:73
Basic status report class.
Definition: multiproc.h:66
IterCountIntType_ IterCountIntType
Type used to count the number of iterations.
Definition: mhrwtasks.h:79
MHRWParams< IterCountIntType, StepRealType > MHRWParamsType
The type to use to store the parameters of the random walk.
Definition: mhrwtasks.h:171
void run()
Run the random walk. (pun intended)
Definition: mhrw.h:569
StepRealType_ StepRealType
Type used to specify the step size.
Definition: mhrwtasks.h:81
Status Report for a MHRandomWalkTask.
Definition: mhrwtasks.h:263
MHRWParamsType mhrwParams() const
The parameters of the random walk.
Definition: mhrw.h:395
Managing the need for specific overrides to operator new() for some types (especially Eigen types) ...
CountIntType n_sweep
The number of individual updates to collect together in a "sweep".
Definition: mhrw.h:226
T size(T... args)
const double acceptance_ratio
The acceptance ratio of the Metropolis-Hastings random walk.
Definition: mhrwtasks.h:223
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:125
Some common definitions for multiprocessing interfaces.
Template, specializable class to get status reports from stats collectors.
StatusReport StatusReportType
Typedef for StatusReport. This is needed by, e.g. MultiProc::OMP::TaskDispatcher. ...
Definition: mhrwtasks.h:306
T quiet_NaN(T... args)
Definitions for MHRWStatsCollector Interface&#39;s.
Routines for performing a Metropolis-Hastings random walk.
T setprecision(T... args)
MHRandomWalkTaskCData::IterCountIntType IterCountIntType
The type used to count iterations (see MHRWParams)
Definition: mhrwtasks.h:241
IterCountIntType kstep
the current iteration number
Definition: mhrwtasks.h:278
STL class.
bool hasAcceptanceRatio() const
Query whether we have any statistics about acceptance ratio. This is false, for example, during the thermalizing runs.
Definition: mhrw.h:412
const int base_seed
A base random seed from which each run seed will be derived.
Definition: mhrwtasks.h:113
IterCountIntType n_total_iters
the total number of iterations required for this random walk
Definition: mhrwtasks.h:301
A simple MHRWStatsCollector interface which combines several stats collectors.