27 #ifndef _TOMOGRAPHER_MHRW_H 28 #define _TOMOGRAPHER_MHRW_H 75 namespace tomo_internal {
84 template<
typename MHWalker,
int UseFnSyntaxType>
85 struct MHRandomWalk_helper_decide_jump
90 typedef typename MHWalker::PointType PointType;
94 typedef typename MHWalker::FnValueType FnValueType;
102 static inline FnValueType get_ptval(MHWalker & mhwalker,
const PointType & curpt)
104 (void)mhwalker; (void)curpt;
105 tomographer_assert(0 &&
"UNKNOWN UseFnSyntaxType: Not implemented");
120 static inline double get_a_value(MHWalker & ,
const PointType & , FnValueType ,
121 const PointType & , FnValueType )
123 tomographer_assert(0 &&
"UNKNOWN UseFnSyntaxType: Not implemented");
131 template<
typename MHWalker>
132 struct MHRandomWalk_helper_decide_jump<MHWalker, MHUseFnValue>
134 typedef typename MHWalker::PointType PointType;
135 typedef typename MHWalker::FnValueType FnValueType;
137 static inline FnValueType get_ptval(MHWalker & mhwalker,
const PointType & curpt)
139 return mhwalker.fnVal(curpt);
141 static inline double get_a_value(MHWalker & ,
const PointType & ,
double newptval,
142 const PointType & ,
double curptval)
144 return (newptval / curptval);
151 template<
typename MHWalker>
152 struct MHRandomWalk_helper_decide_jump<MHWalker, MHUseFnLogValue>
154 typedef typename MHWalker::PointType PointType;
155 typedef typename MHWalker::FnValueType FnValueType;
157 static inline FnValueType get_ptval(MHWalker & mhwalker,
const PointType & curpt)
159 return mhwalker.fnLogVal(curpt);
161 static inline double get_a_value(MHWalker & ,
const PointType & , FnValueType newptval,
162 const PointType & , FnValueType curptval)
164 return (newptval > curptval) ? 1.0 : exp(newptval - curptval);
171 template<
typename MHWalker>
172 struct MHRandomWalk_helper_decide_jump<MHWalker, MHUseFnRelativeValue>
174 typedef typename MHWalker::PointType PointType;
175 typedef int FnValueType;
177 static inline FnValueType get_ptval(MHWalker & ,
const PointType & )
181 static inline double get_a_value(MHWalker & mhwalker,
const PointType & newpt, FnValueType ,
182 const PointType & curpt, FnValueType )
184 return mhwalker.fnRelVal(newpt, curpt);
196 template<
typename CountIntType_,
typename StepRealType_>
199 typedef CountIntType_ CountIntType;
200 typedef StepRealType_ StepRealType;
203 : step_size(0), n_sweep(0), n_therm(0), n_run(0)
206 MHRWParams(StepRealType step_size_, CountIntType n_sweep_, CountIntType n_therm_, CountIntType n_run_)
207 : step_size(step_size_), n_sweep(n_sweep_), n_therm(n_therm_), n_run(n_run_)
230 template<
typename CountIntType,
typename StepRealType>
231 std::ostream & operator<<(std::ostream & str, const MHRWParams<CountIntType,StepRealType> & p)
233 str <<
"MHRWParams(step_size=" << p.step_size <<
",n_sweep=" << p.n_sweep
234 <<
",n_therm=" << p.n_therm <<
",n_run=" << p.n_run <<
")";
279 template<
typename Rng_,
typename MHWalker_,
typename MHRWStatsCollector_,
typename LoggerType_,
280 typename CountIntType_ =
int>
306 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN 307 typedef typename tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,MHWalker::UseFnSyntaxType>::FnValueType
315 UseFnSyntaxType = MHWalker::UseFnSyntaxType
319 const MHRWParamsType _n;
322 MHWalker & _mhwalker;
323 MHRWStatsCollector & _stats;
331 FnValueType curptval;
337 CountIntType num_accepted;
341 CountIntType num_live_points;
346 MHRandomWalk(StepRealType step_size, CountIntType n_sweep, CountIntType n_therm, CountIntType n_run,
347 MHWalker & mhwalker, MHRWStatsCollector & stats,
348 Rng & rng, LoggerType & logger_)
349 : _n(step_size, n_sweep, n_therm, n_run),
360 stream <<
"constructor(). n_sweep=" << n_sweep <<
", step_size=" << step_size
361 <<
"n_therm=" << n_therm <<
", n_run=" << n_run;
365 template<
typename MHRWParamsType>
367 MHWalker & mhwalker, MHRWStatsCollector & stats,
368 Rng & rng, LoggerType & logger_)
369 : _n(
std::forward<MHRWParamsType>(n_rw)),
379 _logger.
debug([&](
std::ostream & s) { s <<
"constructor(). mhrw parameters = " << _n; });
405 return (num_live_points > 0);
409 template<
typename RatioType =
double>
412 return RatioType(num_accepted) / RatioType(num_live_points);
445 curptval = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_ptval(_mhwalker, curpt);
447 s <<
"setCurrentPoint: set internal state. Value = " << curptval <<
"; Point =\n" << pt <<
"\n";
462 curpt = _mhwalker.startPoint();
463 curptval = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_ptval(_mhwalker, curpt);
471 inline void _thermalizing_done()
473 _mhwalker.thermalizingDone();
474 _stats.thermalizingDone();
475 _logger.
longdebug(
"_thermalizing_done() done.");
493 inline void _move(CountIntType k,
bool is_thermalizing,
bool is_live_iter)
500 PointType newpt = _mhwalker.jumpFn(curpt, _n.
step_size);
502 FnValueType newptval;
504 newptval = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_ptval(_mhwalker, newpt);
506 double a = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_a_value(
507 _mhwalker, newpt, newptval, curpt, curptval
513 accept = bool( _rng()-_rng.min() <= a*(_rng.max()-_rng.min()) );
517 if (!is_thermalizing) {
518 num_accepted += accept ? 1 : 0;
522 _stats.rawMove(k, is_thermalizing, is_live_iter, accept, a, newpt, newptval, curpt, curptval, *
this);
525 stream << (is_thermalizing?
"T":
"#") <<
std::setw(3) << k <<
": " << (accept?
"AC":
"RJ") <<
" " 528 <<
", curptval=" <<
std::setw(5) << curptval <<
", accept_ratio=" 545 inline void _process_sample(CountIntType k, CountIntType n)
547 _stats.processSample(k, n, curpt, curptval, *
this);
548 _logger.
longdebug(
"_process_sample() done.");
567 s <<
"Starting random walk, sweep size = " << _n.
n_sweep <<
", step size = " << _n.
step_size 568 <<
", # therm sweeps = " << _n.
n_therm <<
", # live sweeps = " << _n.
n_run;
573 for (k = 0; k < num_thermalize; ++k) {
575 _move(k,
true,
false);
578 _thermalizing_done();
580 _logger.
longdebug(
"Thermalizing done, starting live runs.");
586 for (k = 0; k < num_run; ++k) {
588 bool is_live_iter = ((k+1) % _n.
n_sweep == 0);
591 _move(k,
false, is_live_iter);
594 _process_sample(k, n);
602 _logger.
longdebug(
"Random walk completed.");
A Metropolis-Hastings Random Walk.
Utilities for formatting strings.
MHRWParamsType mhrwParams() const
The parameters of the random walk.
MHWalker::StepRealType StepRealType
The type of a step size of the random walk.
MHWalker::PointType PointType
The type of a point in the random walk.
Base namespace for the Tomographer project.
void debug(const char *fmt,...)
Generate a log message with level Logger::DEBUG (printf-like syntax)
CountIntType n_therm
Number of thermalization sweeps.
CountIntType n_run
Number of live sweeps.
StepRealType stepSize() const
Get the step size of the random walk.
MHRWStatsCollector_ MHRWStatsCollector
The stats collector type (see MHRWStatsCollector Interface)
void setCurrentPoint(const PointType &pt)
Force manual state of random walk.
bool hasAcceptanceRatio() const
Query whether we have any statistics about acceptance ratio. This is false, for example, during the thermalizing runs.
Provides the MH function value at each point (see Role of UseFnSyntaxType)
RatioType acceptanceRatio() const
Return the acceptance ratio so far.
MHRWParams< CountIntType, StepRealType > MHRWParamsType
The struct which can hold the parameters of this random walk.
const PointType & getCurrentPoint() const
Access the current state of the random walk.
MHRandomWalk(MHRWParamsType &&n_rw, MHWalker &mhwalker, MHRWStatsCollector &stats, Rng &rng, LoggerType &logger_)
Simple constructor, initializes the given fields.
MHWalker_ MHWalker
The random walker type which knows about the state space and jump function.
StepRealType step_size
The step size of the random walk.
#define TOMO_ORIGIN
Use this as argument for a Tomographer::Logger::LocalLogger constructor .
_FnValueType FnValueType
The type of the Metropolis-Hastings function value. (See class documentation)
CountIntType nRun() const
Number of live run sweeps.
const FnValueType & getCurrentPointValue() const
Access the current function value of the random walk.
MHRandomWalk(StepRealType step_size, CountIntType n_sweep, CountIntType n_therm, CountIntType n_run, MHWalker &mhwalker, MHRWStatsCollector &stats, Rng &rng, LoggerType &logger_)
Simple constructor, initializes the given fields.
LoggerType_ LoggerType
The logger type which will be provided by user to constructor (see Logging and Loggers) ...
void longdebug(const char *fmt,...)
Generate a log message with level Logger::LONGDEBUG (printf-like syntax)
Provides the logarithm MH function value at each point (see Role of UseFnSyntaxType) ...
Rng_ Rng
Random number generator type (see C++ std::random)
Some C++ utilities, with a tad of C++11 tricks.
void run()
Run the random walk. (pun intended)
Provides directly the ratio of the function values for two consecutive points of the MH random walk (...
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".
CountIntType nTherm() const
Number of thermalizing sweeps.
Specify the parameters of a Metropolis-Hastings random walk.
CountIntType nSweep() const
Number of iterations in a sweep.
CountIntType_ CountIntType
The type used for counting numbers of iterations (see, e.g. nSweep() or MHRWParams) ...
Binning Analysis in a Metropolis-Hastings random walk.
Utilities for logging messages.