Tomographer  v2.0
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 #include <sstream>
41 
42 #include <tomographer2/tools/fmt.h>
44 #include <tomographer2/mhrw.h>
46 #include <tomographer2/multiproc.h> // StatusReport Base
47 
48 
49 namespace Tomographer {
50 namespace MHRWTasks {
51 
52 
62 template<typename CountIntType_ = unsigned int, typename StepRealType_ = double>
63 struct CDataBase
64 {
71  template<typename MHRWParamsType>
72  CDataBase(MHRWParamsType&& p, int base_seed_ = 0)
73  : mhrw_params(std::forward<MHRWParamsType>(p)), base_seed(base_seed_)
74  {
75  }
76 
78  typedef CountIntType_ CountIntType;
80  typedef StepRealType_ StepRealType;
81 
88 
96  const MHRWParamsType mhrw_params;
97 
112  const int base_seed;
113 
123  inline int getTaskInput(int k) const
124  {
125  return base_seed + k;
126  }
127 
128 
131  inline void printBasicCDataMHRWInfo(std::ostream & str) const
132  {
133  str << "\tstep size = " << std::setprecision(4) << mhrw_params.step_size << "\n"
134  << "\t# iter. / sweep = " << mhrw_params.n_sweep << "\n"
135  << "\t# therm. sweeps = " << mhrw_params.n_therm << "\n"
136  << "\t# run sweeps = " << mhrw_params.n_run << "\n";
137  }
142  {
145  return ss.str();
146  }
147 };
148 
160 template<typename MHRWStatsCollectorResultType_, typename CountIntType, typename StepRealType>
162  : public virtual Tools::NeedOwnOperatorNew<MHRWStatsCollectorResultType_>::ProviderType
163 {
166  typedef MHRWStatsCollectorResultType_ MHRWStatsCollectorResultType;
167 
171 
176  : stats_collector_result(), mhrw_params(),
177  acceptance_ratio(std::numeric_limits<double>::quiet_NaN())
178  {
179  }
180 
188  template<typename MHRWStatsCollectorResultTypeInit,
189  typename MHRWParamsType2>
190  MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit && stats_collector_result_,
191  MHRWParamsType2 && mhrw_params_,
192  double acceptance_ratio_)
193  : stats_collector_result(std::forward<MHRWStatsCollectorResultTypeInit>(stats_collector_result_)),
194  mhrw_params(std::forward<MHRWParamsType2>(mhrw_params_)),
195  acceptance_ratio(acceptance_ratio_)
196  {
197  }
198 
204  template<typename MHRWStatsCollectorResultTypeInit, typename MHRandomWalkType>
205  MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit && stats_collector_result_,
206  const MHRandomWalkType & mhrandomwalk)
207  : stats_collector_result(std::forward<MHRWStatsCollectorResultTypeInit>(stats_collector_result_)),
208  mhrw_params(mhrandomwalk.mhrwParams()),
209  acceptance_ratio(mhrandomwalk.hasAcceptanceRatio() ?
210  mhrandomwalk.acceptanceRatio() :
211  std::numeric_limits<double>::quiet_NaN())
212  {
213  }
214 
216  const MHRWStatsCollectorResultType stats_collector_result;
217 
219  const MHRWParamsType mhrw_params;
220 
222  const double acceptance_ratio;
223 };
224 
225 
235 template<typename MHRandomWalkTaskCData,
236  typename Rng = std::mt19937>
238 {
239  typedef typename MHRandomWalkTaskCData::CountIntType CountIntType;
240  typedef typename MHRandomWalkTaskCData::StepRealType StepRealType;
241 
243 
248  typedef MHRandomWalkTaskResult<typename MHRandomWalkTaskCData::MHRWStatsCollectorResultType,
249  CountIntType, StepRealType> ResultType;
250 
260  {
262  StatusReport(double fdone = 0.0, const std::string & msg = std::string(),
263  CountIntType kstep_ = 0, MHRWParamsType mhrw_params_ = MHRWParamsType(),
264  double acceptance_ratio_ = 0.0)
265  : MultiProc::TaskStatusReport(fdone, msg),
266  kstep(kstep_),
267  mhrw_params(mhrw_params_),
268  acceptance_ratio(acceptance_ratio_),
269  n_total_iters(mhrw_params.n_sweep*(mhrw_params.n_therm + mhrw_params.n_run))
270  {
271  }
272 
274  CountIntType kstep;
275 
284  MHRWParamsType mhrw_params;
285 
290 
297  CountIntType n_total_iters;
298  };
303 
304 private:
306  typename Rng::result_type _seed;
307 
315  ResultType * result;
316 
317 public:
318 
324  template<typename LoggerType>
325  MHRandomWalkTask(int inputseed, const MHRandomWalkTaskCData * /*pcdata*/, LoggerType & logger)
326  : _seed(inputseed), result(NULL)
327  {
328  logger.longdebug("MHRandomWalkTask", "() inputseed=%d", inputseed);
329  }
330 
332  {
333  if (result != NULL) {
334  delete result;
335  }
336  }
337 
338 
348  template<typename LoggerType, typename TaskManagerIface>
349  inline void run(const MHRandomWalkTaskCData * pcdata, LoggerType & logger,
350  TaskManagerIface * tmgriface)
351  {
352  Rng rng(_seed); // seeded random number generator
353 
354  logger.longdebug("Tomographer::MHRWTasks::run()", "about to construct stats collector.");
355 
356  // the user's stats collector
357  auto stats = pcdata->createStatsCollector(logger);
358  typedef decltype(stats) MHRWStatsCollectorType;
359 
360  logger.longdebug("Tomographer::MHRWTasks::run()", "stats collector constructed.");
361 
362  // our own "stats collector" which checks if we need to send a status report back
363  typedef StatusReportCheck<TaskManagerIface, MHRWStatsCollectorType> OurStatusReportCheck;
364  OurStatusReportCheck statreportcheck(this, &stats, tmgriface);
365 
367  OurStatsCollectors;
368  OurStatsCollectors ourstatscollectors(stats, statreportcheck);
369 
370  logger.longdebug("Tomographer::MHRWTasks::run()", "about to create MH walker object.");
371 
372  auto mhwalker = pcdata->createMHWalker(rng, logger);
373  typedef decltype(pcdata->createMHWalker(rng, logger)) MHWalkerType;
374 
375  logger.longdebug("Tomographer::MHRWTasks::run()", "MHWalker object created.");
376 
378  // MH random walk parameters
379  pcdata->mhrw_params,
380  // the MHWalker
381  mhwalker,
382  // our stats collectors
383  ourstatscollectors,
384  // a random number generator
385  rng,
386  // and a logger
387  logger
388  );
389 
390  logger.longdebug("Tomographer::MHRWTasks::run()", "MHRandomWalk object created, running...");
391 
392  rwalk.run();
393 
394  logger.longdebug("Tomographer::MHRWTasks::run()", "MHRandomWalk run finished.");
395 
396  result = new ResultType(stats.getResult(), rwalk);
397  }
398 
399  inline const ResultType & getResult() const
400  {
401  return *result;
402  }
403 
404 private:
410  template<typename TaskManagerIface, typename MHRWStatsCollectorType>
411  struct StatusReportCheck
412  {
413  StatusReportCheck(MHRandomWalkTask * mhrwtask_, MHRWStatsCollectorType * stats_, TaskManagerIface *tmgriface_)
414  : mhrwtask(mhrwtask_), stats(stats_), tmgriface(tmgriface_)
415  { }
416 
417  MHRandomWalkTask *mhrwtask;
418  MHRWStatsCollectorType *stats;
419  TaskManagerIface *tmgriface;
420 
421  inline void init() { }
422  inline void thermalizingDone() { }
423  inline void done() { }
424 
425  template<typename PointType, typename FnValueType, typename MHRandomWalk>
426  inline void rawMove(
427  CountIntType k, bool is_thermalizing, bool, bool, double, const PointType &, FnValueType,
428  const PointType &, FnValueType, MHRandomWalk & rw
429  )
430  {
431  // see if we should provide a status report
432  // fprintf(stderr, "StatusReportCheck::rawMove(): testing for status report requested!\n");
433  if (tmgriface->statusReportRequested()) {
434  // prepare & provide status report
435  CountIntType totiters = rw.nSweep()*(rw.nTherm()+rw.nRun());
436  double fdone = (double)k/totiters;
437  double accept_ratio = std::numeric_limits<double>::quiet_NaN();
438  bool warn_accept_ratio = false;
439  if (rw.hasAcceptanceRatio()) {
440  accept_ratio = rw.acceptanceRatio();
441  warn_accept_ratio = (accept_ratio > 0.35 || accept_ratio < 0.2);
442  }
443  std::string msg = Tools::fmts(
444  "%s %lu/(%lu=%lu*(%lu+%lu)) : %5.2f%% done [%saccept ratio=%.2f%s]",
445  ( ! is_thermalizing
446  ? "iteration"
447  : "[therm.] "),
448  (unsigned long)k, (unsigned long)totiters, (unsigned long)rw.nSweep(),
449  (unsigned long)rw.nTherm(), (unsigned long)rw.nRun(),
450  fdone*100.0,
451  warn_accept_ratio ? "!!** " : "",
452  accept_ratio,
453  warn_accept_ratio ? " **!!" : ""
454  );
455  typedef MHRWStatsCollectorStatus<MHRWStatsCollectorType> MHRWStatsCollectorStatusType;
456  if (MHRWStatsCollectorStatusType::CanProvideStatus) {
457  std::string nlindent = "\n ";
458  msg += nlindent;
459  std::string s = MHRWStatsCollectorStatusType::getStatus(stats);
460  for (std::size_t j = 0; j < s.size(); ++j) {
461  if (s[j] == '\n') {
462  msg += nlindent;
463  } else {
464  msg += s[j];
465  }
466  }
467  }
468  tmgriface->submitStatusReport(StatusReport(fdone, msg, k, rw.mhrwParams(), accept_ratio));
469  }
470  // fprintf(stderr, "StatusReportCheck::rawMove(): done\n");
471  }
472 
473  template<typename PointType, typename FnValueType, typename MHRandomWalk>
474  inline void processSample(CountIntType, CountIntType, const PointType &, FnValueType, MHRandomWalk &)
475  {
476  }
477  };
478 };
479 
480 
481 
482 } // MHWalkerTasks
483 
484 
485 
486 } // namespace Tomographer
487 
488 
489 
490 #endif
A Metropolis-Hastings Random Walk.
Definition: mhrw.h:281
Utilities for formatting strings.
std::string getBasicCDataMHRWInfo() const
Get some human-readable info about the random walk as a string, see printBasicCDataMHRWInfo() ...
Definition: mhrwtasks.h:141
CountIntType_ CountIntType
Type used to count the number of iterations.
Definition: mhrwtasks.h:78
MHRWParamsType mhrwParams() const
The parameters of the random walk.
Definition: mhrw.h:386
MHRWParamsType mhrw_params
the parameters of the random walk
Definition: mhrwtasks.h:284
double acceptance_ratio
the current acceptance ratio of the random walk (see Tomographer::MHRandomWalk::acceptanceRatio() ) ...
Definition: mhrwtasks.h:289
Base namespace for the Tomographer project.
Definition: densellh.h:44
MHRWStatsCollectorResultType_ MHRWStatsCollectorResultType
The specified result type of the MHRWStatsCollector the task will be looking at.
Definition: mhrwtasks.h:166
MHRandomWalkTaskResult()
Construct an empty task result.
Definition: mhrwtasks.h:175
const int base_seed
A base random seed from which each run seed will be derived.
Definition: mhrwtasks.h:112
CountIntType n_therm
Number of thermalization sweeps.
Definition: mhrw.h:221
CountIntType n_run
Number of live sweeps.
Definition: mhrw.h:225
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
STL namespace.
bool hasAcceptanceRatio() const
Query whether we have any statistics about acceptance ratio. This is false, for example, during the thermalizing runs.
Definition: mhrw.h:403
MHRandomWalkTask(int inputseed, const MHRandomWalkTaskCData *, LoggerType &logger)
Constructs the MHRandomWalkTask.
Definition: mhrwtasks.h:325
RatioType acceptanceRatio() const
Return the acceptance ratio so far.
Definition: mhrw.h:410
StepRealType_ StepRealType
Type used to specify the step size.
Definition: mhrwtasks.h:80
void run(const MHRandomWalkTaskCData *pcdata, LoggerType &logger, TaskManagerIface *tmgriface)
Run this task.
Definition: mhrwtasks.h:349
void printBasicCDataMHRWInfo(std::ostream &str) const
Get some human-readable info about the random walk as a string.
Definition: mhrwtasks.h:131
const double acceptance_ratio
The acceptance ratio of the Metropolis-Hastings random walk.
Definition: mhrwtasks.h:222
StepRealType step_size
The step size of the random walk.
Definition: mhrw.h:213
Random Walk task, collecting statistics.
Definition: mhrwtasks.h:237
MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit &&stats_collector_result_, MHRWParamsType2 &&mhrw_params_, double acceptance_ratio_)
Constructor, initializes fields to the given values.
Definition: mhrwtasks.h:190
CountIntType nRun() const
Number of live run sweeps.
Definition: mhrw.h:396
STL class.
MHRandomWalkTaskResult(MHRWStatsCollectorResultTypeInit &&stats_collector_result_, const MHRandomWalkType &mhrandomwalk)
Constructor with mhrw_params initialized from a random walk instance.
Definition: mhrwtasks.h:205
Data needed to be accessible to the working code.
Definition: mhrwtasks.h:63
CountIntType kstep
the current iteration number
Definition: mhrwtasks.h:274
CDataBase(MHRWParamsType &&p, int base_seed_=0)
Constructor.
Definition: mhrwtasks.h:72
const MHRWStatsCollectorResultType stats_collector_result
The result furnished by the stats collector itself.
Definition: mhrwtasks.h:216
Basic status report class.
Definition: multiproc.h:62
void run()
Run the random walk. (pun intended)
Definition: mhrw.h:560
const MHRWParamsType mhrw_params
Parameters of the random walk.
Definition: mhrwtasks.h:96
Status Report for a MHRandomWalkTask.
Definition: mhrwtasks.h:259
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:217
CountIntType nTherm() const
Number of thermalizing sweeps.
Definition: mhrw.h:394
T size(T...args)
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:124
CountIntType n_total_iters
the total number of iterations required for this random walk
Definition: mhrwtasks.h:297
StatusReport(double fdone=0.0, const std::string &msg=std::string(), CountIntType kstep_=0, MHRWParamsType mhrw_params_=MHRWParamsType(), double acceptance_ratio_=0.0)
Constructor which initializes all fields.
Definition: mhrwtasks.h:262
Some common definitions for multiprocessing interfaces.
const MHRWParamsType mhrw_params
The parameters of the random walk (see MHRWParams<CountIntType,StepRealType>)
Definition: mhrwtasks.h:219
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:302
int getTaskInput(int k) const
Returns a random seed to seed the random number generator with for run number k.
Definition: mhrwtasks.h:123
MHRWParams< CountIntType, StepRealType > MHRWParamsType
The type to use to store the parameters of the random walk.
Definition: mhrwtasks.h:170
T quiet_NaN(T...args)
Definitions for MHRWStatsCollector Interface&#39;s.
Routines for performing a Metropolis-Hastings random walk.
CountIntType nSweep() const
Number of iterations in a sweep.
Definition: mhrw.h:392
T setprecision(T...args)
MHRWParams< CountIntType, StepRealType > MHRWParamsType
Type to store the parameters of the Metropolis-Hastings random walk (number of runs, sweep size, etc.)
Definition: mhrwtasks.h:87
STL class.
MHRandomWalkTaskResult< typename MHRandomWalkTaskCData::MHRWStatsCollectorResultType, CountIntType, StepRealType > ResultType
Result type of a single task run.
Definition: mhrwtasks.h:249
A simple MHRWStatsCollector interface which combines several stats collectors.