Tomographer  v1.0a
Tomographer C++ Framework Documentation
mhrw.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_MHRW_H
28 #define _TOMOGRAPHER_MHRW_H
29 
30 #include <cstddef>
31 #include <cassert>
32 
33 #include <limits>
34 #include <random>
35 #include <tuple>
36 #include <utility>
37 #include <type_traits>
38 
39 #include <tomographer/qit/matrq.h>
40 #include <tomographer/qit/util.h>
43 #include <tomographer/histogram.h>
46 
47 
54 namespace Tomographer {
55 
56 
84 template<typename RandomWalk_>
86 {
87  typedef RandomWalk_ RandomWalk;
88  typedef typename RandomWalk::CountIntType CountIntType;
89 
97  static void run(RandomWalk & rw)
98  {
99  const CountIntType Nsweep = rw.n_sweep();
100  const CountIntType Ntherm = rw.n_therm();
101  const CountIntType Nrun = rw.n_run();
102 
103  rw.init();
104 
105  CountIntType k;
106 
107  const CountIntType num_thermalize = Nsweep*Ntherm;
108 
109  for (k = 0; k < num_thermalize; ++k) {
110  // calculate a candidate jump point and see if we accept the move
111  rw.move(k, true, false);
112  }
113 
114 
115  rw.thermalizing_done();
116 
117  const CountIntType num_run = Nsweep*Nrun;
118 
119  CountIntType n = 0; // number of live samples
120 
121  for (k = 0; k < num_run; ++k) {
122 
123  bool is_live_iter = ((k+1) % Nsweep == 0);
124 
125  // calculate a candidate jump point and see if we accept the move
126  rw.move(k, false, is_live_iter);
127 
128  if (is_live_iter) {
129  rw.process_sample(k, n);
130  ++n;
131  }
132 
133  }
134 
135  rw.done();
136  return;
137  }
138 
139 private:
140  RandomWalkBase() { } // static-only class
141 };
142 
143 
144 
145 
146 
147 
148 
149 // -----------------
150 
151 
152 
153 enum {
167 };
168 
169 
170 namespace tomo_internal {
171 
179  template<typename MHWalker, int UseFnSyntaxType>
180  struct MHRandomWalk_helper_decide_jump
181  {
185  typedef typename MHWalker::PointType PointType;
189  typedef typename MHWalker::FnValueType FnValueType;
190 
197  static inline FnValueType get_ptval(MHWalker & mhwalker, const PointType & curpt)
198  {
199  (void)mhwalker; (void)curpt;
200  assert(0 && "UNKNOWN UseFnSyntaxType: Not implemented");
201  }
215  static inline double get_a_value(MHWalker & /*mhwalker*/, const PointType & /*newpt*/, FnValueType /*newptval*/,
216  const PointType & /*curpt*/, FnValueType /*curptval*/)
217  {
218  assert(0 && "UNKNOWN UseFnSyntaxType: Not implemented");
219  return 0;
220  }
221  };
222 
226  template<typename MHWalker>
227  struct MHRandomWalk_helper_decide_jump<MHWalker, MHUseFnValue>
228  {
229  typedef typename MHWalker::PointType PointType;
230  typedef typename MHWalker::FnValueType FnValueType;
231 
232  static inline FnValueType get_ptval(MHWalker & mhwalker, const PointType & curpt)
233  {
234  return mhwalker.fnval(curpt);
235  }
236  static inline double get_a_value(MHWalker & /*mhwalker*/, const PointType & /*newpt*/, double newptval,
237  const PointType & /*curpt*/, double curptval)
238  {
239  return (newptval / curptval);
240  }
241  };
242 
246  template<typename MHWalker>
247  struct MHRandomWalk_helper_decide_jump<MHWalker, MHUseFnLogValue>
248  {
249  typedef typename MHWalker::PointType PointType;
250  typedef typename MHWalker::FnValueType FnValueType;
251 
252  static inline FnValueType get_ptval(MHWalker & mhwalker, const PointType & curpt)
253  {
254  return mhwalker.fnlogval(curpt);
255  }
256  static inline double get_a_value(MHWalker & /*mhwalker*/, const PointType & /*newpt*/, FnValueType newptval,
257  const PointType & /*curpt*/, FnValueType curptval)
258  {
259  return (newptval > curptval) ? 1.0 : exp(newptval - curptval);
260  }
261  };
262 
266  template<typename MHWalker>
267  struct MHRandomWalk_helper_decide_jump<MHWalker, MHUseFnRelativeValue>
268  {
269  typedef typename MHWalker::PointType PointType;
270  typedef int FnValueType; // dummy FnValueType
271 
272  static inline FnValueType get_ptval(MHWalker & /*mhwalker*/, const PointType & /*curpt*/)
273  {
274  return 0;
275  }
276  static inline double get_a_value(MHWalker & mhwalker, const PointType & newpt, FnValueType /*newptval*/,
277  const PointType & curpt, FnValueType /*curptval*/)
278  {
279  return mhwalker.fnrelval(newpt, curpt);
280  }
281  };
282 };
283 
284 
285 
301 template<typename Rng_, typename MHWalker_, typename MHRWStatsCollector_, typename LoggerType_,
302  typename CountIntType_ = unsigned int>
304 {
305 public:
307  typedef Rng_ Rng;
309  typedef MHWalker_ MHWalker;
311  typedef MHRWStatsCollector_ MHRWStatsCollector;
313  typedef LoggerType_ LoggerType;
315  typedef CountIntType_ CountIntType;
316 
318  typedef typename MHWalker::PointType PointType;
320  typedef typename MHWalker::RealScalar RealScalar;
321 
323 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
324  typedef typename tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,MHWalker::UseFnSyntaxType>::FnValueType
325  FnValueType;
326 #else
327  typedef _FnValueType FnValueType;
328 #endif
329 
330  enum {
332  UseFnSyntaxType = MHWalker::UseFnSyntaxType
333  };
334 
335 private:
336  const CountIntType _n_sweep;
337  const CountIntType _n_therm;
338  const CountIntType _n_run;
339  const RealScalar _step_size;
340 
341  Rng & _rng;
342  MHWalker & _mhwalker;
343  MHRWStatsCollector & _stats;
344  LoggerType & _logger;
345 
347  PointType curpt;
351  FnValueType curptval;
352 
357  CountIntType num_accepted;
361  CountIntType num_live_points;
362 
363 public:
364 
366  MHRandomWalk(CountIntType n_sweep, CountIntType n_therm, CountIntType n_run, RealScalar step_size,
367  MHWalker & mhwalker, MHRWStatsCollector & stats,
368  Rng & rng, LoggerType & logger_)
369  : _n_sweep(n_sweep), _n_therm(n_therm), _n_run(n_run),
370  _step_size(step_size),
371  _rng(rng),
372  _mhwalker(mhwalker),
373  _stats(stats),
374  _logger(logger_),
375  curpt(),
376  curptval(),
377  num_accepted(0),
378  num_live_points(0)
379  {
380  _logger.debug("MHRandomWalk", "constructor(). n_sweep=%lu, n_therm=%lu, n_run=%lu, step_size=%g",
381  (unsigned long)n_sweep, (unsigned long)n_therm, (unsigned long)n_run, (double)step_size);
382  }
383 
385  inline CountIntType n_sweep() const { return _n_sweep; }
387  inline CountIntType n_therm() const { return _n_therm; }
389  inline CountIntType n_run() const { return _n_run; }
390 
392  inline RealScalar step_size() const { return _step_size; }
393 
397  inline void init()
398  {
399  num_accepted = 0;
400  num_live_points = 0;
401 
402  // starting point
403  curpt = _mhwalker.startpoint();
404  curptval = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_ptval(_mhwalker, curpt);
405 
406  _mhwalker.init();
407  _stats.init();
408  }
412  inline void thermalizing_done()
413  {
414  _mhwalker.thermalizing_done();
415  _stats.thermalizing_done();
416  }
420  inline void done()
421  {
422  _mhwalker.done();
423  _stats.done();
424  }
425 
430  inline const PointType & get_curpt() const
431  {
432  return curpt;
433  }
434 
442  inline const FnValueType & get_curptval() const
443  {
444  return curptval;
445  }
446 
452  inline void set_curpt(const PointType& pt)
453  {
454  curpt = pt;
455  curptval = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_ptval(_mhwalker, curpt);
456  _logger.longdebug("MHRandomWalk",
457  streamstr("set_curpt(): set internal state. Value = "<<curptval<<"; Point =\n"<<pt<<"\n"));
458 
459  }
460 
468  inline void move(CountIntType k, bool is_thermalizing, bool is_live_iter)
469  {
470  // The reason `step_size` is passed to jump_fn instead of leaving jump_fn itself
471  // handle the step size, is that we might in the future want to dynamically adapt the
472  // step size according to the acceptance ratio. That would have to be done in this
473  // class.
474  PointType newpt = _mhwalker.jump_fn(curpt, _step_size);
475 
476  FnValueType newptval;
477 
478  newptval = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_ptval(_mhwalker, newpt);
479 
480  double a = tomo_internal::MHRandomWalk_helper_decide_jump<MHWalker,UseFnSyntaxType>::get_a_value(
481  _mhwalker, newpt, newptval, curpt, curptval
482  );
483 
484  // accept move?
485  bool accept = true;
486  if (a < 1.0) {
487  accept = bool( _rng()-_rng.min() <= a*(_rng.max()-_rng.min()) );
488  }
489 
490  // track acceptance ratio, except if we are thermalizing
491  if (!is_thermalizing) {
492  num_accepted += accept ? 1 : 0;
493  ++num_live_points;
494  }
495 
496  _stats.raw_move(k, is_thermalizing, is_live_iter, accept, a, newpt, newptval, curpt, curptval, *this);
497 
498  _logger.longdebug("MHRandomWalk",
499  "%s%3lu: %s a=%-7.2g, newptval=%5.4g [llh=%.4g], curptval=%5.4g [llh=%.4g] accept_ratio=%s",
500  (is_thermalizing?"T":"#"),
501  (unsigned long)k, accept?"AC":"RJ", (double)a, (double)newptval, -2.0*newptval,
502  (double)curptval, -2.0*curptval,
503  (!is_thermalizing?Tools::fmts("%.2g", acceptance_ratio()).c_str():"N/A"));
504 
505  if (accept) {
506  // update the internal state of the random walk
507  curpt = newpt;
508  curptval = newptval;
509  }
510  }
511 
515  inline bool has_acceptance_ratio() const
516  {
517  return (num_live_points > 0);
518  }
521  template<typename RatioType = double>
522  inline RatioType acceptance_ratio() const
523  {
524  return (RatioType) num_accepted / num_live_points;
525  }
526 
531  inline void process_sample(CountIntType k, CountIntType n)
532  {
533  _stats.process_sample(k, n, curpt, curptval, *this);
534  }
535 
536 
537  inline void run()
538  {
540  }
541 };
542 
543 
544 
545 
546 
547 // -----------------
548 
549 
550 
551 
552 
582 template<typename... MHRWStatsCollectors>
584 {
585 public:
586  typedef std::tuple<MHRWStatsCollectors&...> MHRWStatsCollectorsRefTupleType;
587  typedef std::tuple<MHRWStatsCollectors...> MHRWStatsCollectorsTupleType;
588 
590  static constexpr int NumStatColl = sizeof...(MHRWStatsCollectors);
591 
592 private:
593  MHRWStatsCollectorsRefTupleType statscollectors;
594 
595 public:
596 
597  MultipleMHRWStatsCollectors(MHRWStatsCollectors&... statscollectors_)
598  : statscollectors(statscollectors_...)
599  {
600  }
601 
602  // method to get a particular stats collector
603  template<int I>
604  inline const typename std::tuple_element<I, MHRWStatsCollectorsTupleType>::type & getStatsCollector()
605  {
606  return std::get<I>(statscollectors);
607  }
608 
609  // init() callback
610 
611  template<int I = 0>
612  inline typename std::enable_if<I < NumStatColl, void>::type init()
613  {
614  std::get<I>(statscollectors).init();
615  init<I+1>();
616  }
617  template<int I = 0>
618  inline typename std::enable_if<I == NumStatColl, void>::type init()
619  {
620  }
621 
622  // thermalizing_done() callback
623 
624  template<int I = 0>
625  inline typename std::enable_if<I < NumStatColl, void>::type thermalizing_done()
626  {
627  std::get<I>(statscollectors).thermalizing_done();
628  thermalizing_done<I+1>();
629  }
630  template<int I = 0>
631  inline typename std::enable_if<I == NumStatColl, void>::type thermalizing_done()
632  {
633  }
634 
635  // done() callback
636 
637  template<int I = 0>
638  inline typename std::enable_if<I < NumStatColl, void>::type done()
639  {
640  std::get<I>(statscollectors).done();
641  done<I+1>();
642  }
643  template<int I = 0>
644  inline typename std::enable_if<I == NumStatColl, void>::type done()
645  {
646  }
647 
648 
649  // raw_move() callback
650 
651  template<typename CountIntType, typename PointType, typename FnValueType, typename MHRandomWalk, int I = 0>
652  inline typename std::enable_if<I < NumStatColl, void>::type raw_move(
653  CountIntType k, bool is_thermalizing, bool is_live_iter, bool accepted,
654  double a, const PointType & newpt, FnValueType newptval,
655  const PointType & curpt, FnValueType curptval,
656  MHRandomWalk & rw
657  )
658  {
659  std::get<I>(statscollectors).raw_move(
660  k, is_thermalizing, is_live_iter, accepted, a,
661  newpt, newptval, curpt, curptval, rw
662  );
663  raw_move<CountIntType, PointType, FnValueType, MHRandomWalk, I+1>(
664  k, is_thermalizing, is_live_iter, accepted, a,
665  newpt, newptval, curpt, curptval, rw
666  );
667  }
668  template<typename CountIntType, typename PointType, typename FnValueType, typename MHRandomWalk, int I = 0>
669  inline typename std::enable_if<I == NumStatColl, void>::type raw_move(
670  CountIntType, bool, bool, bool, double, const PointType &, FnValueType,
671  const PointType &, FnValueType, MHRandomWalk &
672  )
673  {
674  }
675 
676 
677  // process_sample() callback
678 
679  template<typename CountIntType, typename PointType, typename FnValueType, typename MHRandomWalk, int I = 0>
680  inline typename std::enable_if<I < NumStatColl, void>::type process_sample(
681  CountIntType k, CountIntType n, const PointType & curpt, FnValueType curptval, MHRandomWalk & rw
682  )
683  {
684  std::get<I>(statscollectors).process_sample(k, n, curpt, curptval, rw);
685  process_sample<CountIntType, PointType, FnValueType, MHRandomWalk, I+1>(k, n, curpt, curptval, rw);
686  }
687 
688  template<typename CountIntType, typename PointType, typename FnValueType, typename MHRandomWalk, int I = 0>
689  inline typename std::enable_if<I == NumStatColl, void>::type process_sample(
690  CountIntType, CountIntType, const PointType &, FnValueType, MHRandomWalk &
691  )
692  {
693  }
694 
695 };
696 
697 
698 
699 
700 // -----------------
701 
702 
703 
716 template<typename ValueCalculator_,
717  typename LoggerType = Logger::VacuumLogger,
718  typename HistogramType_ = UniformBinsHistogram<typename ValueCalculator_::ValueType>
719  >
721 {
722 public:
726  typedef ValueCalculator_ ValueCalculator;
727 
729  typedef typename ValueCalculator::ValueType ValueType;
730 
732  typedef HistogramType_ HistogramType;
733 
735  typedef HistogramType_ Result;
736 
738  typedef typename HistogramType::Params HistogramParams;
739 
740 private:
741 
743  HistogramType _histogram;
744 
749  ValueCalculator _vcalc;
750 
751  LoggerType & _logger;
752 
753 public:
755  ValueHistogramMHRWStatsCollector(HistogramParams histogram_params,
756  const ValueCalculator & vcalc,
757  LoggerType & logger)
758  : _histogram(histogram_params),
759  _vcalc(vcalc),
760  _logger(logger)
761  {
762  }
763 
765  inline const HistogramType & histogram() const
766  {
767  return _histogram;
768  }
769 
773  inline const Result & getResult() const
774  {
775  return _histogram;
776  }
777 
778  // stats collector part
779 
781  inline void init()
782  {
783  // reset our array
784  _histogram.reset();
785  }
787  inline void thermalizing_done()
788  {
789  }
797  template<bool PrintHistogram = true>
798  inline void done()
799  {
800  if (PrintHistogram) {
801  if (_logger.enabled_for(Logger::LONGDEBUG)) {
802  // _logger.longdebug("ValueHistogramMHRWStatsCollector", "done()");
803  _logger.longdebug("ValueHistogramMHRWStatsCollector",
804  "Done walking & collecting stats. Here's the histogram:\n"
805  + _histogram.pretty_print());
806  }
807  }
808  }
809 
811  template<typename CountIntType, typename PointType, typename LLHValueType, typename MHRandomWalk>
812  void raw_move(CountIntType k, bool /*is_thermalizing*/, bool /*is_live_iter*/, bool /*accepted*/,
813  double /*a*/, const PointType & /*newpt*/, LLHValueType /*newptval*/,
814  const PointType & /*curpt*/, LLHValueType /*curptval*/, MHRandomWalk & /*mh*/)
815  {
816  _logger.longdebug("ValueHistogramMHRWStatsCollector", "raw_move(): k=%lu", (unsigned long)k);
817  }
818 
820  template<typename CountIntType, typename PointType, typename LLHValueType, typename MHRandomWalk>
821  std::size_t process_sample(CountIntType k, CountIntType n, const PointType & curpt,
822  LLHValueType /*curptval*/, MHRandomWalk & /*mh*/)
823  {
824  ValueType val = _vcalc.getValue(curpt);
825 
826  _logger.longdebug("ValueHistogramMHRWStatsCollector", "in process_sample(): k=%lu, n=%lu, val=%.4g",
827  (unsigned long)k, (unsigned long)n, val);
828 
829  return _histogram.record(val);
830 
831  //_logger.longdebug("ValueHistogramMHRWStatsCollector", "process_sample() finished");
832  }
833 
834 
835 };
836 
837 
838 
846 template<typename ValueCalculator_,
847  typename CountIntType_ = int,
848  typename CountRealAvgType_ = double,
849  int NumTrackValues_ = Eigen::Dynamic,
850  int NumLevels_ = Eigen::Dynamic
851  >
853 {
856  typedef ValueCalculator_ ValueCalculator;
858  typedef CountIntType_ CountIntType;
860  typedef CountRealAvgType_ CountRealAvgType;
861 
863  static constexpr int NumTrackValues = NumTrackValues_;
865  static constexpr int NumLevels = NumLevels_;
866 
868  typedef typename ValueCalculator::ValueType ValueType;
869 
871  typedef BinningAnalysisParams<ValueType,NumTrackValues,NumLevels,false/*StoreBinSums*/,CountIntType>
873 
883  typedef typename HistogramType::Params HistogramParams;
884 
890  struct Result
891  {
893  explicit Result()
895  {
896  }
897 
899  template<typename BinningAnalysisType>
900  Result(HistogramParams p, const BinningAnalysisType & b)
901  : hist(p),
902  error_levels(b.num_track_values(), b.num_levels()+1),
903  converged_status(Eigen::ArrayXi::Constant(b.num_track_values(), BinningAnalysisType::UNKNOWN_CONVERGENCE))
904  {
905  eigen_assert(converged_status.rows() == b.num_track_values() && converged_status.cols() == 1);
906  }
907 
909  HistogramType hist;
915  Eigen::ArrayXi converged_status;
916 
918  inline void dump_convergence_analysis(std::ostream & str) const
919  {
920  for (int k = 0; k < converged_status.size(); ++k) {
921  str << "\tval[" << std::setw(3) << k << "] = "
922  << std::setw(12) << hist.bins(k)
923  << " +- " << std::setw(12) << hist.delta(k);
925  str << " [CONVERGED]";
927  str << " [NOT CONVERGED]";
929  str << " [UNKNOWN]";
930  } else {
931  str << " [UNKNOWN CONVERGENCE STATUS: " << converged_status(k) << "]";
932  }
933  str << "\n";
934  }
935  }
936 
939  {
942  return ss.str();
943  }
944 
945  };
946 
947 };
948 
956 template<typename Params,
957  typename LoggerType_ = Logger::VacuumLogger
958  >
960 {
961 public:
962 
964  typedef typename Params::ValueCalculator ValueCalculator;
966  typedef typename Params::CountIntType CountIntType;
968  typedef typename Params::CountRealAvgType CountRealAvgType;
969 
971  typedef LoggerType_ LoggerType;
972 
974  typedef typename Params::BaseHistogramType BaseHistogramType;
976  typedef typename Params::HistogramParams HistogramParams;
977 
979  typedef typename Params::ValueType ValueType;
980 
982  typedef typename Params::BinningAnalysisParamsType BinningAnalysisParamsType;
985 
987  static constexpr int NumTrackValuesCTime = Params::NumTrackValues;
989  static constexpr int NumLevelsCTime = Params::NumLevels;
990 
992  typedef typename Params::Result Result;
993 
999  LoggerType,
1000  BaseHistogramType
1002 
1003 private:
1004 
1005  ValueHistogramMHRWStatsCollectorType value_histogram;
1006 
1007  BinningAnalysisType binning_analysis;
1008 
1009  LoggerType & logger;
1010 
1011  Result result;
1012 
1013 public:
1014 
1015  ValueHistogramWithBinningMHRWStatsCollector(HistogramParams histogram_params,
1016  const ValueCalculator & vcalc,
1017  int num_levels,
1018  LoggerType & logger_)
1019  : value_histogram(histogram_params, vcalc, logger_),
1020  binning_analysis(histogram_params.num_bins, num_levels, logger_),
1021  logger(logger_),
1022  result(histogram_params, binning_analysis)
1023  {
1024  logger.longdebug("ValueHistogramWithBinningMHRWStatsCollector", "constructor()");
1025  }
1026 
1028  inline const BaseHistogramType & histogram() const
1029  {
1030  return value_histogram.histogram();
1031  }
1032 
1033  inline const BinningAnalysisType & get_binning_analysis() const
1034  {
1035  return binning_analysis;
1036  }
1037 
1044  inline const Result & getResult() const
1045  {
1046  return result;
1047  }
1048 
1049  // stats collector part
1050 
1052  inline void init()
1053  {
1054  value_histogram.init();
1055  }
1057  inline void thermalizing_done()
1058  {
1059  value_histogram.thermalizing_done();
1060  }
1062  inline void done()
1063  {
1064  logger.longdebug("ValueHistogramWithBinningMHRWStatsCollector::done()", "finishing up ...");
1065 
1066  value_histogram.template done<false>();
1067 
1068  const BaseHistogramType & h = value_histogram.histogram();
1069  result.hist.params = h.params;
1070  CountRealAvgType normalization = h.bins.sum() + h.off_chart; // need ALL samples, because that's
1071  // what the binning analysis sees
1072  result.hist.bins = h.bins.template cast<CountRealAvgType>() / normalization;
1073  result.error_levels = binning_analysis.calc_error_levels(result.hist.bins);
1074  result.hist.delta = result.error_levels.col(binning_analysis.num_levels()).template cast<CountRealAvgType>();
1075  result.hist.off_chart = h.off_chart / normalization;
1076 
1077  result.converged_status = binning_analysis.determine_error_convergence(result.error_levels);
1078 
1079  logger.debug("ValueHistogramWithBinningMHRWStatsCollector", [&,this](std::ostream & str) {
1080  str << "Binning analysis: bin sqmeans at different binning levels are:\n"
1081  << binning_analysis.get_bin_sqmeans() << "\n"
1082  << "\t-> so the error bars at different binning levels are:\n"
1083  << result.error_levels << "\n"
1084  << "\t-> convergence analysis: \n";
1085  result.dump_convergence_analysis(str);
1086  str << "\t... and just for you, here is the final histogram:\n" << result.hist.pretty_print() << "\n";
1087  });
1088  }
1089 
1091  template<typename CountIntType2, typename PointType, typename LLHValueType, typename MHRandomWalk>
1092  inline void raw_move(CountIntType2 k, bool is_thermalizing, bool is_live_iter, bool accepted,
1093  double a, const PointType & newpt, LLHValueType newptval,
1094  const PointType & curpt, LLHValueType curptval, MHRandomWalk & mh)
1095  {
1096  value_histogram.raw_move(k, is_thermalizing, is_live_iter, accepted, a, newpt, newptval, curpt, curptval, mh);
1097  }
1098 
1100  template<typename CountIntType2, typename PointType, typename LLHValueType, typename MHRandomWalk>
1101  inline void process_sample(CountIntType2 k, CountIntType2 n, const PointType & curpt,
1102  LLHValueType curptval, MHRandomWalk & mh)
1103  {
1104  std::size_t histindex = value_histogram.process_sample(k, n, curpt, curptval, mh);
1105  binning_analysis.process_new_values(
1106  can_basis_vec<Eigen::Array<ValueType,Eigen::Dynamic,1> >(histindex, value_histogram.histogram().num_bins())
1107  );
1108  }
1109 
1110 };
1111 
1112 
1113 
1114 
1115 
1116 
1123 template<typename MHRWStatsCollector_>
1125 {
1126  typedef MHRWStatsCollector_ MHRWStatsCollector;
1127 
1128  static constexpr bool CanProvideStatus = false;
1129 
1134  static inline std::string getStatus(const MHRWStatsCollector * /*stats*/)
1135  {
1136  return std::string();
1137  }
1138 };
1139 
1140 
1141 
1145 template<typename... Args>
1147 {
1149 
1150  static constexpr int NumStatColl = MHRWStatsCollector::NumStatColl;
1151 
1152  static constexpr bool CanProvideStatus = true;
1153 
1154  template<int I = 0, typename std::enable_if<(I < NumStatColl), bool>::type dummy = true>
1155  static inline std::string getStatus(const MHRWStatsCollector * stats)
1156  {
1157  typedef typename std::tuple_element<I, typename MHRWStatsCollector::MHRWStatsCollectorsTupleType>::type
1158  ThisStatsCollector;
1159  return
1161  ? (MHRWStatsCollectorStatus<ThisStatsCollector>::getStatus(stats->template getStatsCollector<I>())
1162  + ((I < (NumStatColl-1)) ? std::string("\n") : std::string()))
1163  : std::string())
1164  + getStatus<I+1>(stats);
1165  };
1166 
1167  template<int I = 0, typename std::enable_if<(I == NumStatColl), bool>::type dummy = true>
1168  static inline std::string getStatus(const MHRWStatsCollector * stats)
1169  {
1170  (void)stats;
1171  return std::string();
1172  }
1173 
1174 };
1175 
1176 
1177 
1181 template<typename ValueCalculator_,
1182  typename LoggerType_,
1183  typename HistogramType_
1184  >
1185 struct MHRWStatsCollectorStatus<ValueHistogramMHRWStatsCollector<ValueCalculator_, LoggerType_, HistogramType_> >
1186 {
1188 
1189  static constexpr bool CanProvideStatus = true;
1190 
1191  static inline std::string getStatus(const MHRWStatsCollector * stats)
1192  {
1193  const int maxbarwidth = 50;
1194 
1195  typedef typename MHRWStatsCollector::HistogramType HistogramType;
1196 
1197  return "Histogram: " + histogram_short_bar<HistogramType>(stats->histogram(), true, maxbarwidth);
1198  }
1199 };
1200 
1204 template<typename Params_,
1205  typename LoggerType_
1206  >
1208 {
1210 
1211  static constexpr bool CanProvideStatus = true;
1212 
1213  static inline std::string getStatus(const MHRWStatsCollector * stats)
1214  {
1215  const int maxbarwidth = 50;
1216 
1217  typedef typename MHRWStatsCollector::BaseHistogramType BaseHistogramType;
1218  const BaseHistogramType & histogram = stats->histogram();
1219 
1220  // calculate the error bars at different levels, to determine convergence status.
1221  typedef typename MHRWStatsCollector::BinningAnalysisType BinningAnalysisType;
1222  //typedef typename MHRWStatsCollector::CountRealAvgType CountRealAvgType;
1223  typedef typename BinningAnalysisType::ValueType ValueType;
1224  const auto& binning_analysis = stats->get_binning_analysis();
1225  Eigen::Array<ValueType, Eigen::Dynamic, 1> binmeans(histogram.num_bins());
1226  binmeans = histogram.bins.template cast<ValueType>() /
1227  (ValueType)(histogram.bins.sum() + histogram.off_chart);
1228 
1229  auto error_levels = binning_analysis.calc_error_levels(binmeans);
1230  auto conv_status = binning_analysis.determine_error_convergence(error_levels);
1231 
1232  int n_cnvg = 0;
1233  int n_unknown = 0;
1234  int n_not_cnvg = 0;
1235  for (std::size_t k = 0; k < (std::size_t)histogram.num_bins(); ++k) {
1236  if (conv_status(k) == BinningAnalysisType::CONVERGED) {
1237  ++n_cnvg;
1238  } else if (conv_status(k) == BinningAnalysisType::NOT_CONVERGED) {
1239  ++n_not_cnvg;
1240  } else {
1241  ++n_unknown;
1242  }
1243  }
1244 
1245  return tomo_internal::histogram_short_bar_fmt<BaseHistogramType>(histogram, "", maxbarwidth)
1246  + Tools::fmts(" err: (cnvg/?/fail) %d/%d/%d", n_cnvg, n_unknown, n_not_cnvg);
1247  }
1248 };
1249 
1250 
1251 
1252 } // namespace Tomographer
1253 
1254 
1255 
1256 
1257 
1258 
1259 
1260 
1261 #endif
A StatsCollector which builds a histogram of values calculated with a ValueCalculator for each data s...
Definition: mhrw.h:720
A Metropolis-Hastings Random Walk.
Definition: mhrw.h:303
Eigen::ArrayXi determine_error_convergence(const Eigen::Ref< const BinSumSqArray > &error_levels) const
Attempt to determine if the error bars have converged.
Definition: mhrw_bin_err.h:707
Result type of the corresponding ValueHistogramWithBinningMHRWStatsCollector.
Definition: mhrw.h:890
Params::BaseHistogramType BaseHistogramType
See ValueHistogramWithBinningMHRWStatsCollectorParams::BaseHistogramType .
Definition: mhrw.h:974
Eigen::Array< CountType, Eigen::Dynamic, 1 > bins
The counts for each bin.
Definition: histogram.h:187
MHWalker::PointType PointType
The type of a point in the random walk.
Definition: mhrw.h:318
void process_sample(CountIntType2 k, CountIntType2 n, const PointType &curpt, LLHValueType curptval, MHRandomWalk &mh)
Part of the MHRWStatsCollector Interface. Records the sample in the histogram.
Definition: mhrw.h:1101
const Result & getResult() const
Get the final histogram data. This method is needed for Resultable Interface compliance.
Definition: mhrw.h:1044
Result(HistogramParams p, const BinningAnalysisType &b)
Constructor which initializes the fields from the histogram and binning analysis type.
Definition: mhrw.h:900
void done()
Finalize the data collection. Part of the MHRWStatsCollector Interface.
Definition: mhrw.h:1062
BinningAnalysis< BinningAnalysisParamsType, LoggerType > BinningAnalysisType
See ValueHistogramWithBinningMHRWStatsCollectorParams::BinningAnalysisType .
Definition: mhrw.h:984
void done()
Part of the MHRWStatsCollector Interface.
Definition: mhrw.h:798
Base namespace for the Tomographer project.
Definition: dmmhrw.h:51
CountRealAvgType_ CountRealAvgType
Type used to store the averages of the histogram bins.
Definition: mhrw.h:860
std::size_t process_sample(CountIntType k, CountIntType n, const PointType &curpt, LLHValueType, MHRandomWalk &)
Part of the MHRWStatsCollector Interface. Records the sample in the histogram.
Definition: mhrw.h:821
ValueHistogramMHRWStatsCollector(HistogramParams histogram_params, const ValueCalculator &vcalc, LoggerType &logger)
Simple constructor, initializes with the given values.
Definition: mhrw.h:755
void init()
Required for RandomWalk Interface. Resets counts and relays to the MHWalker and the MHRWStatsCollecto...
Definition: mhrw.h:397
ValueCalculator::ValueType ValueType
The type to use to represent a calculated distance.
Definition: mhrw.h:729
Eigen::ArrayXi converged_status
Information of convergence status of the error bars (see e.g. BinningAnalysisParamsType::CONVERGED) ...
Definition: mhrw.h:915
void thermalizing_done()
Part of the MHRWStatsCollector Interface. No-op.
Definition: mhrw.h:1057
Group template parameters for BinningAnalysis.
Definition: mhrw_bin_err.h:108
T exp(T...args)
RealScalar step_size() const
Get the step size of the random walk.
Definition: mhrw.h:392
BinSumSqArray calc_error_levels(const Eigen::ArrayBase< Derived > &means) const
Calculate the error bars of samples at different binning levels.
Definition: mhrw_bin_err.h:607
MHRWStatsCollector_ MHRWStatsCollector
The stats collector type (see MHRWStatsCollector Interface)
Definition: mhrw.h:311
The error bars appear to have converged.
Definition: mhrw_bin_err.h:186
CountIntType n_run() const
Required for RandomWalk Interface. Number of live run sweeps.
Definition: mhrw.h:389
Params::HistogramParams HistogramParams
See ValueHistogramWithBinningMHRWStatsCollectorParams::HistogramParams .
Definition: mhrw.h:976
void dump_convergence_analysis(std::ostream &str) const
Dump values, error bars and convergence status in human-readable form into ostream.
Definition: mhrw.h:918
ValueCalculator_ ValueCalculator
The type which calculates the interesting value. Should be of type interface ValueCalculator Interfac...
Definition: mhrw.h:726
Eigen::Array< CountType, Eigen::Dynamic, 1 > delta
The error bars associated with each histogram bin.
Definition: histogram.h:402
HistogramType hist
Histogram, already with error bars.
Definition: mhrw.h:909
Unable to determine whether the error bars have converged.
Definition: mhrw_bin_err.h:184
void thermalizing_done()
Required for RandomWalk Interface. Relays to the MHWalker and the MHRWStatsCollector.
Definition: mhrw.h:412
MHWalker_ MHWalker
The random walker type which knows about the state space and jump function.
Definition: mhrw.h:309
UniformBinsHistogram< typename ValueCalculator::ValueType, CountIntType > BaseHistogramType
The Base Histogram Type.
Definition: mhrw.h:878
Result()
Simple default constructor (e.g. to use as std::vector).
Definition: mhrw.h:893
HistogramType::Params HistogramParams
Structure which holds the parameters of the histogram we're recording.
Definition: mhrw.h:738
The error bars don't seem to have converged.
Definition: mhrw_bin_err.h:188
Define types for quantum objects. See Tomographer::MatrQ.
Params::Result Result
See ValueHistogramWithBinningMHRWStatsCollectorParams::Result .
Definition: mhrw.h:992
_FnValueType FnValueType
The type of the Metropolis-Hastings function value. (See class documentation)
Definition: mhrw.h:327
T setw(T...args)
auto can_basis_vec(IndexType k, IndexType size) -> const Eigen::CwiseNullaryOp< tomo_internal::can_basis_vec_generator< typename Eigen::internal::traits< Der >::Scalar, IndexType >, Der >
Expression for the k-th canonical basis vector of given dimension.
Definition: util.h:271
static constexpr int NumStatColl
The number of stats collectors we are tracking.
Definition: mhrw.h:590
STL class.
void set_curpt(const PointType &pt)
Force manual state of random walk.
Definition: mhrw.h:452
BinningAnalysisParamsType::BinSumSqArray error_levels
Detailed error bars for all binning levels.
Definition: mhrw.h:911
Provides the MH function value at each point (see Role of UseFnSyntaxType)
Definition: mhrw.h:157
Traits-like class for ValueHistogramWithBinningMHRWStatsCollector.
Definition: mhrw.h:852
const Tools::static_or_dynamic< int, NumLevelsCTime > num_levels
The number of levels in the binning analysis.
Definition: mhrw_bin_err.h:310
Collect a histogram of values from a MH random walk, with binning analysis.
Definition: mhrw.h:959
LoggerType_ LoggerType
The logger type (see Logging and Loggers)
Definition: mhrw.h:313
void done()
Required for RandomWalk Interface. Relays to the MHWalker and the MHRWStatsCollector.
Definition: mhrw.h:420
Data corresponding to a quantum tomography setting.
Tools for parameterizing hermitian matrices with the X Parameterization.
Params::ValueType ValueType
See ValueHistogramWithBinningMHRWStatsCollectorParams::ValueType .
Definition: mhrw.h:979
CountIntType n_sweep() const
Required for RandomWalk Interface. Number of iterations in a sweep.
Definition: mhrw.h:385
const HistogramType & histogram() const
Get the histogram data collected so far. See HistogramType.
Definition: mhrw.h:765
Params::BinningAnalysisParamsType BinningAnalysisParamsType
See ValueHistogramWithBinningMHRWStatsCollectorParams::BinningAnalysisParamsType .
Definition: mhrw.h:982
Params::ValueCalculator ValueCalculator
See ValueHistogramWithBinningMHRWStatsCollectorParams::ValueCalculator .
Definition: mhrw.h:964
Provides directly the ratio of the function values for two consecutive points of the MH random walk (...
Definition: mhrw.h:166
bool has_acceptance_ratio() const
Query whether we have any statistics about acceptance ratio. This is false, for example, during the thermalizing runs.
Definition: mhrw.h:515
T str(T...args)
void raw_move(CountIntType2 k, bool is_thermalizing, bool is_live_iter, bool accepted, double a, const PointType &newpt, LLHValueType newptval, const PointType &curpt, LLHValueType curptval, MHRandomWalk &mh)
Part of the MHRWStatsCollector Interface. No-op.
Definition: mhrw.h:1092
Params::CountRealAvgType CountRealAvgType
See ValueHistogramWithBinningMHRWStatsCollectorParams::CountRealAvgType .
Definition: mhrw.h:968
Rng_ Rng
Random number generator type (see C++ std::random)
Definition: mhrw.h:307
static void run(RandomWalk &rw)
Run the random walk. (pun intended)
Definition: mhrw.h:97
HistogramType_ HistogramType
The type of the histogram. Usually a UniformBinsHistogram with ValueType range type.
Definition: mhrw.h:732
static std::string getStatus(const MHRWStatsCollector *)
Prepare a string which reports the status of the given stats collector.
Definition: mhrw.h:1134
static constexpr int NumTrackValuesCTime
See ValueHistogramWithBinningMHRWStatsCollectorParams::NumTrackValues .
Definition: mhrw.h:987
void init()
Part of the MHRWStatsCollector Interface. Initializes the histogram to zeros.
Definition: mhrw.h:781
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:122
void process_sample(CountIntType k, CountIntType n)
Required for RandomWalk Interface. Process a new live sample in the random walk. Relays the call to t...
Definition: mhrw.h:531
Provides the logarithm MH function value at each point (see Role of UseFnSyntaxType) ...
Definition: mhrw.h:161
Base_::Params Params
Shortcut for our base class' histogram parameters. See UniformBinsHistogram
Definition: histogram.h:396
Template, specializable class to get status reports from stats collectors.
Definition: mhrw.h:1124
void raw_move(CountIntType k, bool, bool, bool, double, const PointType &, LLHValueType, const PointType &, LLHValueType, MHRandomWalk &)
Part of the MHRWStatsCollector Interface. No-op.
Definition: mhrw.h:812
Params::CountIntType CountIntType
See ValueHistogramWithBinningMHRWStatsCollectorParams::CountIntType .
Definition: mhrw.h:966
BinningAnalysisParams< ValueType, NumTrackValues, NumLevels, false, CountIntType > BinningAnalysisParamsType
The relevant BinningAnalysis parameters for us.
Definition: mhrw.h:872
std::string dump_convergence_analysis() const
Dump values, error bars and convergence status in human-readable form as string.
Definition: mhrw.h:938
ValueCalculator_ ValueCalculator
The type of the ValueCalculator Interface which calculates the value of which we're collecting a hist...
Definition: mhrw.h:856
LoggerType_ LoggerType
Somewhere where this object may log what it's doing.
Definition: mhrw.h:971
void process_new_values(const Eigen::DenseBase< Derived > &vals)
Process new raw samples.
Definition: mhrw_bin_err.h:435
const Result & getResult() const
Get the histogram data collected so far. This method is needed for Resultable Interface compliance...
Definition: mhrw.h:773
Definitions for Histogram Types.
UniformBinsHistogramWithErrorBars< typename ValueCalculator::ValueType, CountRealAvgType > HistogramType
The Final Histogram Type (with error bars).
Definition: mhrw.h:882
Long Debug logging level.
Definition: loggers.h:122
MHWalker::RealScalar RealScalar
The type of a step size of the random walk.
Definition: mhrw.h:320
Stores a histogram.
Definition: histogram.h:65
#define streamstr(tokens)
Utility macro to format stream tokens to a std::string.
Definition: fmt.h:143
static constexpr int NumLevels
The number of levels in the binning analysis. See BinningAnalysis.
Definition: mhrw.h:865
static constexpr int NumTrackValues
Number of values we're tracking, i.e. the number of bins in the histogram [for now].
Definition: mhrw.h:863
MHRandomWalk(CountIntType n_sweep, CountIntType n_therm, CountIntType n_run, RealScalar step_size, MHWalker &mhwalker, MHRWStatsCollector &stats, Rng &rng, LoggerType &logger_)
Simple constructor, initializes the given fields.
Definition: mhrw.h:366
const FnValueType & get_curptval() const
Access the current function value of the random walk.
Definition: mhrw.h:442
CountIntType_ CountIntType
The type used for counting numbers of iterations (see, e.g. n_sweep())
Definition: mhrw.h:315
void move(CountIntType k, bool is_thermalizing, bool is_live_iter)
Required for RandomWalk Interface. Processes a single move in the random walk.
Definition: mhrw.h:468
Binning Analysis in a Metropolis-Hastings random walk.
static constexpr int NumLevelsCTime
See ValueHistogramWithBinningMHRWStatsCollectorParams::NumLevels .
Definition: mhrw.h:989
STL class.
void init()
Part of the MHRWStatsCollector Interface. Initializes the histogram to zeros.
Definition: mhrw.h:1052
const BaseHistogramType & histogram() const
Get the histogram data collected so far. See BaseHistogramType .
Definition: mhrw.h:1028
Basic utilities for dealing with Eigen matrices and other types.
CountIntType n_therm() const
Required for RandomWalk Interface. Number of thermalizing sweeps.
Definition: mhrw.h:387
HistogramType_ Result
Required for compliance with Resultable Interface type.
Definition: mhrw.h:735
ValueHistogramMHRWStatsCollector< ValueCalculator, LoggerType, BaseHistogramType > ValueHistogramMHRWStatsCollectorType
This is the natural ValueHistogramMHRWStatsCollector type on which we're adding error bars...
Definition: mhrw.h:1001
const PointType & get_curpt() const
Access the current state of the random walk.
Definition: mhrw.h:430
RatioType acceptance_ratio() const
Return the acceptance ratio so far.
Definition: mhrw.h:522
Utilities for logging messages.
ValueCalculator::ValueType ValueType
The type of a value calculated by the ValueCalculator Interface.
Definition: mhrw.h:868
A simple MHRWStatsCollector interface which combines several stats collectors.
Definition: mhrw.h:583
Base class performing an abstract random walk.
Definition: mhrw.h:85
auto get_bin_sqmeans() const
Get the raw average of the squared values observed, for each binning level.
Definition: mhrw_bin_err.h:557
How to calculate the Metropolis-Hastings jump probability ratio (see class documentation) ...
Definition: mhrw.h:332
CountIntType_ CountIntType
Type used to count the number of hits in each bin.
Definition: mhrw.h:858
void thermalizing_done()
Part of the MHRWStatsCollector Interface. No-op.
Definition: mhrw.h:787