MaCh3  2.6.0
Reference Guide
DelayedMR2T2.cpp
Go to the documentation of this file.
1 #include "Fitters/DelayedMR2T2.h"
2 
3 // *************************
4 DelayedMR2T2::DelayedMR2T2(Manager* const FitManager) : MR2T2(FitManager) {
5 // *************************
6  AlgorithmName = "DelayedMR2T2";
7  auto Config = fitMan->raw();
8  // Step scale for delayed step = step scale prev delay * decay_rate
9  decay_rate = GetFromManager<double>(Config["General"]["MCMC"]["DecayRate"], 0.1, __FILE__, __LINE__);
10  // Maximum number of rejections
11  max_rejections = GetFromManager<int>(Config["General"]["MCMC"]["MaxRejections"], 1, __FILE__, __LINE__);
12  // How big is the first step scale. This scales parameter step by initial_scale * <step scale in ParameterHandler>
13  initial_scale = GetFromManager<int>(Config["General"]["MCMC"]["InitialScale"], 1, __FILE__, __LINE__);
14  // On delayed on out of bounds steps. This saves some compute time and possibly regains efficiency
15  delay_on_oob_only = GetFromManager<bool>(Config["General"]["MCMC"]["DelayOnlyOutBounds"], false, __FILE__, __LINE__);
16  // Allow to intrude another delayed rejection based on defined here probability
17  delay_probability = GetFromManager<double>(Config["General"]["MCMC"]["DelayProbability"], 1.0, __FILE__, __LINE__);
18 
19  if(delay_probability > 1.0){
20  MACH3LOG_WARN("Probability of delaying steps > 1, setting to 1");
21  delay_probability = 1.0;
22  }
23  if(delay_probability <= 0.0){
24  MACH3LOG_CRITICAL("Probability of delaying steps <= 0, setting to 0, delay will no longer have an impact!");
25  delay_probability = 0.0;
26  // Since we're not delaying at all set max_rejections = 0 to save time
27  max_rejections = 0;
28  }
29  MACH3LOG_INFO("Using Delayed MCMC with decay rate: {} and {} allowed rejections", decay_rate, max_rejections);
30 }
31 
32 // *************************
33 void DelayedMR2T2::ScaleSystematics(const double scale) {
34 // *************************
35  for (auto &syst : systematics)
36  {
37  syst->SetStepScale(scale*syst->GetGlobalStepScale(), false);
38  }
39 }
40 
41 // *************************
43 // *************************
44  for (int i = 0; i < static_cast<int>(systematics.size()); ++i)
45  {
46  systematics[i]->SetStepScale(start_step_scale[i], false);
47  }
48 }
49 
50 // *************************
52 // *************************
54 
55  for(size_t i = 0; i < systematics.size(); ++i){
56  if(systematics[i]->GetDoAdaption()){
57  if(systematics[i]->GetAdaptiveHandler()->GetUseRobbinsMonro()){
58  MACH3LOG_ERROR("Right now Robbins-Monro doesn't work with Delayed MCMC");
59  MACH3LOG_ERROR("Usual adaptive works fine though");
60  MACH3LOG_ERROR("Ask Dr Wallace for details");
61  throw MaCh3Exception(__FILE__ , __LINE__ );
62  }
63  }
64  }
65  // Store delayed specific settings
66  outTree->Branch("DelayedStep", &accepted_delayed, "DelayedStep/B");
67 }
68 
69 //**********************************************
71 // *********************************************
72  // Stores values from step
73  // Ensure vector is correctly sized
74  current_step_vals.resize(systematics.size());
75  start_step_scale.resize(systematics.size());
76 
77  // Fill with old proposed step, need to copy to avoid using the same step twice
78  for(int i=0; i<static_cast<int>(systematics.size()); ++i){
79  current_step_vals[i] = std::vector<double>(systematics[i]->GetParCurrVec());
80  start_step_scale[i] = systematics[i]->GetGlobalStepScale();
81  }
82 }
83 
84 // *************************
86 // *************************
87  // From https://arxiv.org/pdf/2010.04190 and DRAM Matlab implementation
88  const double numerator = std::max(0.0, std::exp(MinLogLikelihood - logLProp) - 1.0);
89  const double denominator = std::exp(MinLogLikelihood - logLCurr) - 1.0;
90  if (denominator <= 0.0) return 1.0;
91 
92  // Large enough that the the minus 1 will make NO difference so the max term cancels
93  if(std::isinf(numerator) || std::isinf(denominator) ){
95  }
96 
97  return std::min(numerator / denominator, 1.0);
98 }
99 
100 // *************************
102 // *************************
103  // Set the initial rejection to false
105 
106  // Apply initial scale
108 
109  bool accepted = false;
110  bool delay = false;
111  accepted_delayed = false;
112 
114 
115  for(int i = 0; i<= max_rejections; ++i)
116  {
117  ProposeStep();
118 
119  // Small hack to ensure we can "leapfrog"
120  for (auto &syst : systematics)
121  {
122  syst->AcceptStep();
123  }
124 
126  continue;
127  }
128 
129  if(i == 0){
131  }
132  else{
134  delay = true;
135  }
136  if(IsStepAccepted(accProb)){
137  AcceptStep();
138  accepted = true;
139 
140  // Keep track of if step is delayed + accepted for storage
141  accepted_delayed = delay;
142 
143  // Update
144  break;
145  }
148  // If we are not out of bounds and only delaying on out of bounds steps
149  // We can skip the delay
150  break;
151  }
152 
154  if (!ProbabilisticDelay()) {
155  break;
156  }
157 
158 
159  // Temporary, means we can "leapfrog"
162  }
163 
164  // If we reject we need to reset everything [this is probably a tad too slow...
165  // especially in PCA...
166  if(!accepted){
167  for(int i=0; i<static_cast<int>(systematics.size()); ++i){
168  for(int j=0; j<static_cast<int>(systematics[i]->GetParCurrVec().size()); ++j){
169  systematics[i]->SetParCurrProp(j, current_step_vals[i][j]);
170  }
171  }
172  }
173  ResetSystScale();
174 }
175 
176 // *************************
178 // *************************
179  // We can delay probabilistically
180  return (random->Rndm() > delay_probability);
181 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
bool accepted_delayed
Was the step we just accepted delayed?
Definition: DelayedMR2T2.h:93
void PrepareOutput()
override to add in rejection information to output
int max_rejections
How many rejections allowed?
Definition: DelayedMR2T2.h:87
bool ProbabilisticDelay() const
if delay has a chance of occurring
void StoreCurrentStep()
Store information about the current proposed step.
double delay_probability
Can delay with probability instead.
Definition: DelayedMR2T2.h:98
std::vector< double > start_step_scale
Stores the initial scale for all parameters.
Definition: DelayedMR2T2.h:80
bool delay_on_oob_only
Delay only if we go out of bounds.
Definition: DelayedMR2T2.h:96
void DoStep() final
The MCMC step proposal.
double MinLogLikelihood
Minimum (negative) log-likelihood of proposed steps.
Definition: DelayedMR2T2.h:90
DelayedMR2T2(Manager *const fitMan)
Constructor.
Definition: DelayedMR2T2.cpp:4
void ResetSystScale()
Reset scale after delay process.
double decay_rate
How much to decrease the step scale each step.
Definition: DelayedMR2T2.h:85
double AcceptanceProbability() final
Step acceptance probability.
void ScaleSystematics(const double scale)
Set parameter scale to be original_scale* scale.
double initial_scale
Scale for (non-delayed) step is initial_scale * start_step_scale.
Definition: DelayedMR2T2.h:83
std::vector< std::vector< double > > current_step_vals
Store information about the current proposed step.
Definition: DelayedMR2T2.h:77
std::unique_ptr< TRandom3 > random
Random number.
Definition: FitterBase.h:149
double logLProp
proposed likelihood
Definition: FitterBase.h:120
void PrepareOutput()
Prepare the output file.
Definition: FitterBase.cpp:151
double accProb
current acceptance prob
Definition: FitterBase.h:122
std::string AlgorithmName
Name of fitting algorithm that is being used.
Definition: FitterBase.h:173
Manager * fitMan
The manager for configuration handling.
Definition: FitterBase.h:113
double logLCurr
current likelihood
Definition: FitterBase.h:118
TTree * outTree
Output tree with posteriors.
Definition: FitterBase.h:158
std::vector< ParameterHandlerBase * > systematics
Systematic holder.
Definition: FitterBase.h:139
void AcceptStep()
Accept a step.
Definition: MCMCBase.cpp:252
bool out_of_bounds
Do we reject based on hitting boundaries in systs.
Definition: MCMCBase.h:67
bool IsStepAccepted(const double acc_prob)
Is step accepted?
Definition: MCMCBase.cpp:234
MCMC algorithm implementing the Metropolis–Rosenbluth–Rosenbluth–Teller–Teller (MR T ) method.
Definition: MR2T2.h:27
void ProposeStep() final
Propose a step.
Definition: MR2T2.cpp:25
double AcceptanceProbability() override
Step acceptance probability.
Definition: MR2T2.cpp:126
Custom exception class used throughout MaCh3.
The manager class is responsible for managing configurations and settings.
Definition: Manager.h:16
YAML::Node const & raw() const
Return config.
Definition: Manager.h:47
constexpr static const double _LARGE_LOGL_
Large Likelihood is used it parameter go out of physical boundary, this indicates in MCMC that such s...
Definition: Core.h:80