Tomographer  v5.3
Tomographer C++ Framework Documentation
mhrw_valuehist_tools.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_MHRW_VALUEHIST_TOOLS_H
29 #define TOMOGRAPHER_MHRW_VALUEHIST_TOOLS_H
30 
31 
32 #include <iostream>
33 #include <iomanip>
34 
35 #include <boost/math/constants/constants.hpp>
36 #include <boost/serialization/serialization.hpp>
37 #include <boost/serialization/base_object.hpp>
38 
40 #include <tomographer/tools/cxxutil.h> // tomographer_assert()
43 #include <tomographer/mhrwtasks.h>
44 
45 
57 namespace Tomographer {
58 namespace MHRWTasks {
59 namespace ValueHistogramTools {
60 
61 
62 
63 
70 template<typename RawHistogramType_, typename ScaledHistogramType_>
71 struct TOMOGRAPHER_EXPORT MHRWStatsResultsBaseSimple
72 {
73  typedef RawHistogramType_ RawHistogramType;
74  typedef ScaledHistogramType_ ScaledHistogramType;
75 
76  MHRWStatsResultsBaseSimple(RawHistogramType && val)
77  : raw_histogram(std::move(val)),
78  histogram(raw_histogram.params)
79  {
80  typedef typename ScaledHistogramType::CountType CountRealType;
81  CountRealType ncounts = raw_histogram.totalCounts();
82  histogram.load(raw_histogram.bins.template cast<CountRealType>() / ncounts,
83  raw_histogram.off_chart / ncounts);
84  }
85 
86  RawHistogramType raw_histogram;
87 
88  ScaledHistogramType histogram;
89 };
90 
91 
92 
93 
94 
95 
96 // -----------------------------------------------
97 
98 
99 namespace tomo_internal {
100 //
101 // version WITHOUT binning analysis:
102 //
103 template<typename CDataBaseType, bool UseBinningAnalysis>
104 struct valuehist_types
105 {
106  typedef Histogram<typename CDataBaseType::ValueCalculator::ValueType,
107  typename CDataBaseType::HistCountIntType> HistogramType;
108 
109  // useful types
110 
111  // we know that ValueHistogramMHRWStatsCollector<ValueCalculator,...,HistogramType>::ResultType is HistogramType
112  typedef HistogramType ValueStatsCollectorResultType;
113  typedef typename HistogramType::Params HistogramParams;
114  typedef typename CDataBaseType::CountRealType CountRealType;
116 
117  // base type for user cdata to use as MHRWStatsResults member
119  MHRWStatsResultsBaseType;
120 
121  // the correct histogram aggregator type
123 };
124 //
125 // version WITH binning analysis:
126 //
127 template<typename CDataBaseType>
128 struct valuehist_types<CDataBaseType, true>
129 {
130  // useful types
131 
132  typedef typename CDataBaseType::CountRealType CountRealType;
133 
136  typename CDataBaseType::ValueCalculator,
137  typename CDataBaseType::HistCountIntType,
138  CountRealType,
139  Eigen::Dynamic,
140  Eigen::Dynamic
141  > BinningMHRWStatsCollectorParams;
142 
143  typedef typename BinningMHRWStatsCollectorParams::Result ValueStatsCollectorResultType;
144  typedef typename BinningMHRWStatsCollectorParams::HistogramType HistogramType;
145  typedef typename BinningMHRWStatsCollectorParams::HistogramParams HistogramParams;
146 
147  // base type for user cdata to use as MHRWStatsResults member
148  typedef ValueStatsCollectorResultType MHRWStatsResultsBaseType;
149 
150  // the correct histogram aggregator type
152 };
153 } // namespace tomo_internal
154 
155 
156 // ------------------------------------------------
157 
158 
159 
233 template<typename ValueCalculator_,
234  bool UseBinningAnalysis_ = true,
235  typename MHWalkerParams_ = MHWalkerParamsStepSize<double>,
236  typename RngSeedType_ = std::mt19937::result_type,
237  typename IterCountIntType_ = int,
238  typename CountRealType_ = double,
239  typename HistCountIntType_ = IterCountIntType_>
240 struct TOMOGRAPHER_EXPORT CDataBase
241  : public MHRWTasks::CDataBase<MHWalkerParams_, IterCountIntType_, RngSeedType_>,
242  public virtual Tools::NeedOwnOperatorNew<ValueCalculator_>::ProviderType
243 {
246 
249 
251  typedef typename Base::RngSeedType RngSeedType;
252 
255 
257  typedef HistCountIntType_ HistCountIntType;
258 
262  typedef ValueCalculator_ ValueCalculator;
264  typedef CountRealType_ CountRealType;
265 
267  static constexpr bool UseBinningAnalysis = UseBinningAnalysis_;
268 
281 
294 
310 
315 
318 
319 
321  TOMOGRAPHER_ENABLED_IF(!UseBinningAnalysis)
322  CDataBase(const ValueCalculator & valcalc_, HistogramParams histogram_params_,
323  MHRWParamsType p, RngSeedType base_seed = 0)
324  : Base(std::move(p), base_seed), valcalc(valcalc_), histogram_params(histogram_params_),
325  binningNumLevels()
326  {
327  }
329  TOMOGRAPHER_ENABLED_IF(!UseBinningAnalysis)
330  CDataBase(const ValueCalculator & valcalc_, HistogramParams histogram_params_,
331  MHRWParamsType p, std::vector<RngSeedType> seeds)
332  : Base(std::move(p), std::move(seeds)), valcalc(valcalc_), histogram_params(histogram_params_),
333  binningNumLevels()
334  {
335  }
336 
338  TOMOGRAPHER_ENABLED_IF(UseBinningAnalysis)
339  CDataBase(const ValueCalculator & valcalc_, HistogramParams histogram_params_, int binning_num_levels_,
340  MHRWParamsType p, RngSeedType base_seed = 0)
341  : Base(std::move(p), base_seed), valcalc(valcalc_), histogram_params(histogram_params_),
342  binningNumLevels(binning_num_levels_)
343  {
344  }
346  TOMOGRAPHER_ENABLED_IF(UseBinningAnalysis)
347  CDataBase(const ValueCalculator & valcalc_, HistogramParams histogram_params_, int binning_num_levels_,
348  MHRWParamsType p, std::vector<RngSeedType> seeds)
349  : Base(std::move(p), std::move(seeds)), valcalc(valcalc_), histogram_params(histogram_params_),
350  binningNumLevels(binning_num_levels_)
351  {
352  }
353 
356  CDataBase() : Base(), valcalc(), histogram_params(), binningNumLevels() { }
357 
358 
381 
382 
391  template<typename LoggerType, TOMOGRAPHER_ENABLED_IF_TMPL(!UseBinningAnalysis)>
393  createValueStatsCollector(LoggerType & logger) const
394  {
396  histogram_params,
397  valcalc,
398  logger
399  );
400  }
401 
410  template<typename LoggerType, TOMOGRAPHER_ENABLED_IF_TMPL(UseBinningAnalysis)>
412  typename tomo_internal::valuehist_types<CDataBase, true>::BinningMHRWStatsCollectorParams,
413  LoggerType>
414  createValueStatsCollector(LoggerType & logger) const
415  {
416  typedef typename tomo_internal::valuehist_types<CDataBase, true>::BinningMHRWStatsCollectorParams
417  BinningMHRWStatsCollectorParams;
418 
420  histogram_params,
421  valcalc,
422  binningNumLevels.value,
423  logger
424  );
425  }
426 
427 
430 
431 
440  template<typename TaskResultType>
441  AggregatedHistogramType aggregateResultHistograms(const std::vector<TaskResultType*> & task_result_list)
442  {
443  return AggregatedHistogramType::aggregate(
444  histogram_params,
445  task_result_list,
446  [](const TaskResultType * task_result)
447  -> const typename AggregatedHistogramType::HistogramType &
448  {
449  // .histogram is already the "scaled histogram". This works both
450  // for the "simple" version as well as for the
451  // "binning-analysis-error-bar" version.
452  return task_result->stats_results.histogram;
453  });
454  }
455 
456 
457 private:
458  friend boost::serialization::access;
459  template<typename Archive,
460  typename ValueCalculator2 = ValueCalculator>
461  void serialize(Archive & a, const unsigned int version)
462  {
463  a & boost::serialization::base_object<Base>(*this);
464  ValueCalculator2 & valcalc_ref = valcalc;
465  a & valcalc_ref;
466  a & histogram_params;
467  maybe_serialize_binning(a, version);
468  }
469  template<typename Archive, TOMOGRAPHER_ENABLED_IF_TMPL(UseBinningAnalysis)>
470  void maybe_serialize_binning(Archive & a, const unsigned int /* version */)
471  {
472  a & binningNumLevels.value;
473  }
474  template<typename Archive, TOMOGRAPHER_ENABLED_IF_TMPL(!UseBinningAnalysis)>
475  void maybe_serialize_binning(Archive &, const unsigned int) { }
476 
477 };
478 // define static members:
479 template<typename ValueCalculator_, bool UseBinningAnalysis_,
480  typename MHWalkerParams_, typename RngSeedType_,
481  typename IterCountIntType_, typename CountRealType_,
482  typename HistCountIntType_>
483 constexpr bool CDataBase<ValueCalculator_,UseBinningAnalysis_,MHWalkerParams_,RngSeedType_,
484  IterCountIntType_,CountRealType_,HistCountIntType_>::UseBinningAnalysis;
485 
486 
487 
488 
489 
490 
491 // ---------------------------------------------------------
492 
493 
494 
495 
496 
497 
498 
499 
500 
501 
502 
503 
504 namespace tomo_internal {
505 
506 template<typename StatsResultsType, typename = void>
507 struct maybe_show_error_summary_helper {
508  static inline void print(std::ostream & , const StatsResultsType & ) { }
509 };
510 template<typename StatsResultsType>
511 struct maybe_show_error_summary_helper<
512  StatsResultsType,
513  typename std::enable_if<
514  !std::is_same<
515  decltype(((StatsResultsType*)NULL)->errorBarConvergenceSummary()),
516  void
517  >::value
518  >::type
519  >
520 {
521  static inline void print(std::ostream & stream, const StatsResultsType & stats_results)
522  {
523  stream << " error bars: " << stats_results.errorBarConvergenceSummary() << "\n";
524  }
525 };
526 template<typename StatsResultsType>
527 inline void maybe_show_error_summary(std::ostream & stream, const StatsResultsType & stats_results)
528 {
529  maybe_show_error_summary_helper<StatsResultsType>::print(stream, stats_results) ;
530 }
531 
532 
533 template<typename TaskResultType>
534 inline void print_hist_short_bar_summary(std::ostream & stream, int dig_w, std::size_t j,
535  const TaskResultType * task_result, int columns)
536 {
537  const auto acceptance_ratio = task_result->acceptance_ratio;
539  streamstr("#" << std::setw(dig_w) << j << ": "),
540  task_result->stats_results.histogram,
541  Tomographer::Tools::fmts(" [accept ratio = %.2f]", acceptance_ratio),
542  false, columns);
543  if (acceptance_ratio > MHRWAcceptanceRatioRecommendedMax ||
544  acceptance_ratio < MHRWAcceptanceRatioRecommendedMin) {
545  stream << " *** Accept ratio out of recommended bounds ["
547  << "] ! Adapt step size ***\n";
548  }
549  maybe_show_error_summary(stream, task_result->stats_results);
550 }
551 
552 } // namespace tomo_internal
553 
554 
555 
556 
557 
558 
559 
573 template<typename CDataBaseType, typename TaskResultType, typename AggregatedHistogramType>
574 inline void printFinalReport(std::ostream & stream, const CDataBaseType & cdata,
575  const std::vector<TaskResultType*> & task_results,
576  const AggregatedHistogramType & aggregated_histogram,
577  int max_width = 0, bool print_histogram = true)
578 {
579  Tools::ConsoleFormatterHelper h(max_width); // possibly detect terminal width etc.
580 
581  // produce report on runs
582  stream << "\n"
583  << h.centerLine("Final Report of Runs")
584  << h.hrule()
585  ;
586  cdata.printBasicCDataMHRWInfo(stream);
587 
588  int dig_w = (int)std::ceil(std::log10((double)task_results.size()));
589  for (std::size_t j = 0; j < task_results.size(); ++j) {
590  tomo_internal::print_hist_short_bar_summary(stream, dig_w, j, task_results[j], (int)h.columns());
591  }
592  stream << h.hrule()
593  << "\n";
594 
595  if (print_histogram) {
596  // and the final histogram
597  stream << h.centerLine("Final Histogram")
598  << h.hrule();
599  histogramPrettyPrint(stream, aggregated_histogram.final_histogram, (int)h.columns());
600  stream << h.hrule()
601  << "\n";
602  }
603 }
604 
605 
606 
607 
608 
609 
610 
611 
612 
613 
614 } // namespace ValueHistogramTools
615 } // namespace MHRWTasks
616 } // namespace Tomographer
617 
618 
619 #endif
A StatsCollector which builds a histogram of values calculated with a ValueCalculator for each data s...
std::string centerLine(std::string x)
Produce a centered string.
Definition: fmt.h:431
void printFinalReport(std::ostream &stream, const CDataBaseType &cdata, const std::vector< TaskResultType *> &task_results, const AggregatedHistogramType &aggregated_histogram, int max_width=0, bool print_histogram=true)
Produce a final, human-readable report of the whole procedure.
tomo_internal::valuehist_types< CDataBase, UseBinningAnalysis >::ValueStatsCollectorResultType ValueStatsCollectorResultType
The result type of our stats collector.
MHRWTasks::CDataBase< MHWalkerParams_, IterCountIntType_, RngSeedType_ > Base
The MHRWTasks::CDataBase base class.
The parameters of a Histogram.
Definition: histogram.h:72
Base namespace for the Tomographer project.
Definition: densellh.h:45
void histogramShortBarWithInfo(std::ostream &str, std::string head, const HistogramType &hist, std::string tail, bool log_scale=true, int full_max_width=0)
Format the histogram as a one-line bar, with some surrounding info.
Definition: histogram.h:1854
T ceil(T... args)
std::size_t columns() const
The number of character columns (as specified to the constructor or detected)
Definition: fmt.h:423
An MHWalkerParams type which just stores a step size.
Definition: mhrw.h:97
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
STL namespace.
constexpr const double MHRWAcceptanceRatioRecommendedMax
Maximal recommended acceptance ratio.
Definition: mhrw.h:87
MHRWParams< MHWalkerParams, IterCountIntType > MHRWParamsType
Type for the parameters of the random walk.
Multiprocessing tasks interface (see Multiprocessing Task Interfaces) for parallel Metropolis-Hasting...
Base::RngSeedType RngSeedType
Type of the seed for the pseudo-random number generator.
constexpr const double MHRWAcceptanceRatioRecommendedMin
Minimal recommended acceptance ratio.
Definition: mhrw.h:85
T log10(T... args)
Constant data structure for MH random walk tasks with a value histogram stats collector.
T setw(T... args)
Data needed to be accessible to the working code.
Definition: mhrwtasks.h:81
Traits-like class for ValueHistogramWithBinningMHRWStatsCollector.
void histogramPrettyPrint(std::ostream &str, const HistogramType &histogram, int max_width=0)
pretty-print the given histogram.
Definition: histogram.h:1751
Minimal tool for formatting console stuff with fixed line width.
Definition: fmt.h:407
Collect a histogram of values from a MH random walk, with binning analysis.
HistCountIntType_ HistCountIntType
The integer counting type in our underlying raw histogram type.
RngSeedType_ RngSeedType
Type used to specify the seed of the random number generator.
Definition: mhrwtasks.h:92
AggregatedHistogramType aggregateResultHistograms(const std::vector< TaskResultType *> &task_result_list)
Convenience function for aggregating histograms resulting from value-histogram tasks.
ValueHistogramWithBinningMHRWStatsCollector< typename tomo_internal::valuehist_types< CDataBase, true >::BinningMHRWStatsCollectorParams, LoggerType > createValueStatsCollector(LoggerType &logger) const
Create the stats collector (with binning analysis)
Stores a histogram.
Definition: histogram.h:230
HistogramParams histogram_params
The parameters of the histogram that we are collecting.
ValueHistogramMHRWStatsCollector< ValueCalculator, LoggerType, HistogramType > createValueStatsCollector(LoggerType &logger) const
Create the stats collector (without binning analysis)
ValueCalculator_ ValueCalculator
The class which calculates the value we are collecting a histogram of (ValueCalculator Interface comp...
tomo_internal::valuehist_types< CDataBase, UseBinningAnalysis >::HistogramParams HistogramParams
The appropriate parameters type for the histogram reported by the task.
Some C++ utilities, with a tad of C++11 tricks.
T move(T... args)
HistogramType_ HistogramType
The histogram type corresponding to the result of a task.
Definition: histogram.h:1073
Base::IterCountIntType IterCountIntType
The integer type which serves to count the number of iterations (see MHRWParams)
Managing the need for specific overrides to operator new() for some types (especially Eigen types) ...
T size(T... args)
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:128
STL class.
Base::MHWalkerParams MHWalkerParams
The MHWalkerParams required for our MHWalker (for instance a MHWalkerParamsStepSize) ...
VarValueDecoder< T >::RetType value(const Var &var)
Access the value of the given variable, as a C++ type.
Definition: ezmatio.h:878
tomo_internal::valuehist_types< CDataBase, UseBinningAnalysis >::HistogramType HistogramType
The histogram type reported by the task.
Stores the result of the value histogram stats collector (version without binning analysis) ...
tomo_internal::valuehist_types< CDataBase, UseBinningAnalysis >::MHRWStatsResultsBaseType MHRWStatsResultsBaseType
Stores result of the stats collector. May serve as base class for your own MHRWStatsResults class...
Definitions for MHRWStatsCollector Interface&#39;s.
IterCountIntType_ IterCountIntType
Type used to count the number of iterations.
Definition: mhrwtasks.h:84
#define streamstr(tokens)
Utility macro to format stream tokens to a std::string.
Definition: fmt.h:149
MHWalkerParams_ MHWalkerParams
Type used to specify the step size.
Definition: mhrwtasks.h:86
ValueCalculator valcalc
The value calculator instance.
STL class.
Histogram aggregator, if each individual histogram already has error bars.
Definition: histogram.h:1218
Histogram aggregator, if each histogram doesn&#39;t have error bars.
Definition: histogram.h:1063
Tools::StoreIfEnabled< int, UseBinningAnalysis > binningNumLevels
The number of levels in the binning analysis (only if we are using a binning analysis) ...
Utilities for logging messages.
CountRealType_ CountRealType
The real type which serves to average histogram counts (typically double)