MaCh3  2.6.0
Reference Guide
AdaptiveMCMCHandler.cpp
Go to the documentation of this file.
2 
3 // ********************************************
5 // ********************************************
10  total_steps = 0;
11  par_means = {};
12  adaptive_covariance = nullptr;
13 
15  use_robbins_monro = false;
17 
18  target_acceptance = 0.234;
20 }
21 
22 // ********************************************
24 // ********************************************
25  if(adaptive_covariance != nullptr) {
26  delete adaptive_covariance;
27  }
28 }
29 
30 // ********************************************
31 bool AdaptiveMCMCHandler::InitFromConfig(const YAML::Node& adapt_manager, const std::string& matrix_name_str,
32  const std::vector<std::string>* parameter_names,
33  const std::vector<double>* parameters,
34  const std::vector<double>* fixed,
35  const std::vector<bool>* param_skip_adapt_flags,
36  const TMatrixDSym* throwMatrix,
37  const double initial_scale_) {
38 // ********************************************
39  /*
40  * HW: Idea is that adaption can simply read the YAML config
41  * Options :
42  * External Info:
43  * UseExternalMatrix [bool] : Use an external matrix
44  * ExternalMatrixFileName [str] : Name of file containing external info
45  * ExternalMatrixName [str] : Name of external Matrix
46  * ExternalMeansName [str] : Name of external means vector [for updates]
47  *
48  * General Info:
49  * DoAdaption [bool] : Do we want to do adaption?
50  * AdaptionStartThrow [int] : Step we start throwing adaptive matrix from
51  * AdaptionEndUpdate [int] : Step we stop updating adaptive matrix
52  * AdaptionStartUpdate [int] : Do we skip the first N steps?
53  * AdaptionUpdateStep [int] : Number of steps between matrix updates
54  * AdaptionSaveNIterations [int]: You don't have to save every adaptive stage so decide how often you want to save
55  * Adaption blocks [vector<vector<int>>] : Splits the throw matrix into several block matrices
56  * OuputFileName [std::string] : Name of the file that the adaptive matrices will be saved into
57  */
58 
59  // setAdaptionDefaults();
60  if(!adapt_manager["AdaptionOptions"]["Covariance"][matrix_name_str]) {
61  MACH3LOG_WARN("Adaptive Settings not found for {}, this is fine if you don't want adaptive MCMC", matrix_name_str);
62  return false;
63  }
64 
65  // We"re going to grab this info from the YAML manager
66  if(!GetFromManager<bool>(adapt_manager["AdaptionOptions"]["Covariance"][matrix_name_str]["DoAdaption"], false, __FILE__ , __LINE__)) {
67  MACH3LOG_WARN("Not using adaption for {}", matrix_name_str);
68  return false;
69  }
70 
71  if(!CheckNodeExists(adapt_manager, "AdaptionOptions", "Settings", "OutputFileName")) {
72  MACH3LOG_ERROR("No OutputFileName specified in AdaptionOptions::Settings into your config file");
73  MACH3LOG_ERROR("This is required if you are using adaptive MCMC");
74  throw MaCh3Exception(__FILE__, __LINE__);
75  }
76  auto AdaptSettings = adapt_manager["AdaptionOptions"]["Settings"];
77  start_adaptive_throw = GetFromManager<int>(AdaptSettings["StartThrow"], 10, __FILE__ , __LINE__);
78  start_adaptive_update = GetFromManager<int>(AdaptSettings["StartUpdate"], 0, __FILE__ , __LINE__);
79  end_adaptive_update = GetFromManager<int>(AdaptSettings["EndUpdate"], 10000, __FILE__ , __LINE__);
80  adaptive_update_step = GetFromManager<int>(AdaptSettings["UpdateStep"], 100, __FILE__ , __LINE__);
81  adaptive_save_n_iterations = GetFromManager<int>(AdaptSettings["SaveNIterations"], -1, __FILE__ , __LINE__);
82  output_file_name = GetFromManager<std::string>(AdaptSettings["OutputFileName"], "", __FILE__ , __LINE__);
83 
84  // Check for Robbins-Monro adaption
85  use_robbins_monro = GetFromManager<bool>(AdaptSettings["UseRobbinsMonro"], false, __FILE__ , __LINE__);
86  target_acceptance = GetFromManager<double>(AdaptSettings["TargetAcceptance"], 0.234, __FILE__ , __LINE__);
87  if (target_acceptance <= 0 || target_acceptance >= 1) {
88  MACH3LOG_ERROR("Target acceptance must be in (0,1), got {}", target_acceptance);
89  throw MaCh3Exception(__FILE__, __LINE__);
90  }
91 
92  acceptance_rate_batch_size = GetFromManager<int>(AdaptSettings["AcceptanceRateBatchSize"], 10000, __FILE__ , __LINE__);
93  total_rm_restarts = GetFromManager<int>(AdaptSettings["TotalRobbinsMonroRestarts"], 0, __FILE__ , __LINE__);
94  n_rm_restarts = 0;
95 
96  prev_step_accepted = false;
97 
98  // We also want to check for "blocks" by default all parameters "know" about each other
99  // but we can split the matrix into independent block matrices
100  SetParams(parameters);
101  SetFixed(fixed);
102 
103  _ParamNames = parameter_names;
104 
105  initial_throw_matrix = static_cast<TMatrixDSym*>(throwMatrix->Clone());
106 
107  initial_scale = initial_scale_;
108 
110  if(use_robbins_monro) {
111  MACH3LOG_INFO("Using Robbins-Monro for adaptive step size tuning with target acceptance {}", target_acceptance);
112  // Now we need some thing
114  }
115 
116  // We'll use the same start scale for Robbins-Monro as standard adaption
117  adaption_scale = 2.38/std::sqrt(GetNumParams());
118 
119  auto AdaptOptions = adapt_manager["AdaptionOptions"]["Covariance"][matrix_name_str];
120  // HH: added ability to define blocks by parameter names
121  bool matrix_blocks_by_name = GetFromManager<bool>(AdaptOptions["MatrixBlocksByName"], false, __FILE__ , __LINE__);
122  std::vector<std::vector<int>> matrix_blocks;
123  // HH: read blocks by names and convert to indices
124  if (matrix_blocks_by_name) {
125  auto matrix_blocks_input = GetFromManager<std::vector<std::vector<std::string>>>(AdaptOptions["MatrixBlocks"], {{}}, __FILE__ , __LINE__);
126  // Now we need to convert to indices
127  for (const auto& block : matrix_blocks_input) {
128  auto block_indices = GetParIndicesFromNames(block);
129  matrix_blocks.push_back(block_indices);
130  }
131  } else {
132  matrix_blocks = GetFromManager<std::vector<std::vector<int>>>(AdaptOptions["MatrixBlocks"], {{}}, __FILE__ , __LINE__);
133  }
134  SetAdaptiveBlocks(matrix_blocks);
135 
136  // set parameters to skip during adaption
137  _param_skip_adapt_flags = param_skip_adapt_flags;
138 
139  return true;
140 }
141 
142 // ********************************************
144 // ********************************************
145  adaptive_covariance = new TMatrixDSym(GetNumParams());
146  adaptive_covariance->Zero();
147  par_means = std::vector<double>(GetNumParams(), 0);
148 }
149 
150 // ********************************************
151 void AdaptiveMCMCHandler::SetAdaptiveBlocks(const std::vector<std::vector<int>>& block_indices) {
152 // ********************************************
153  /*
154  * In order to adapt efficient we want to setup our throw matrix to be a serious of block-diagonal (ish) matrices
155  *
156  * To do this we set sub-block in the config by parameter index. For example having
157  * [[0,4],[4, 6]] in your config will set up two blocks one with all indices 0<=i<4 and the other with 4<=i<6
158  */
159  // Set up block regions
160  adapt_block_matrix_indices = std::vector<int>(GetNumParams(), 0);
161 
162  // Should also make a matrix of block sizes
163  adapt_block_sizes = std::vector<int>(block_indices.size()+1, 0);
165 
166  if(block_indices.size()==0 || block_indices[0].size()==0) return;
167 
168  int block_size = static_cast<int>(block_indices.size());
169  // Now we loop over our blocks
170  for(int iblock=0; iblock < block_size; iblock++){
171  // Loop over blocks in the block
172  int sub_block_size = static_cast<int>(block_indices.size()-1);
173  for(int isubblock=0; isubblock < sub_block_size ; isubblock+=2){
174  int block_lb = block_indices[iblock][isubblock];
175  int block_ub = block_indices[iblock][isubblock+1];
176 
177  if(block_lb > GetNumParams() || block_ub > GetNumParams()){
178  MACH3LOG_ERROR("Cannot set matrix block with edges {}, {} for matrix of size {}",
179  block_lb, block_ub, GetNumParams());
180  throw MaCh3Exception(__FILE__, __LINE__);;
181  }
182  for(int ipar = block_lb; ipar < block_ub; ipar++){
183  adapt_block_matrix_indices[ipar] = iblock+1;
184  adapt_block_sizes[iblock+1] += 1;
185  adapt_block_sizes[0] -= 1;
186  }
187  }
188  }
189 }
190 
191 // ********************************************
192 //HW: Truly adaptive MCMC!
193 void AdaptiveMCMCHandler::SaveAdaptiveToFile(const std::string &outFileName,
194  const std::string &systematicName, bool is_final) {
195 // ********************************************
196  // Skip saving if adaptive_save_n_iterations is negative,
197  // unless this is the final iteration (is_final overrides the condition)
198  if (adaptive_save_n_iterations < 0 && !is_final) return;
199  if (is_final ||
202  TFile *outFile = new TFile(outFileName.c_str(), "UPDATE");
203  if (outFile->IsZombie()) {
204  MACH3LOG_ERROR("Couldn't find {}", outFileName);
205  throw MaCh3Exception(__FILE__, __LINE__);
206  }
207 
208  TVectorD *outMeanVec = new TVectorD(int(par_means.size()));
209  for (int i = 0; i < int(par_means.size()); i++) {
210  (*outMeanVec)(i) = par_means[i];
211  }
212 
213  std::string adaptive_cov_name = systematicName + "_posfit_matrix";
214  std::string mean_vec_name = systematicName + "_mean_vec";
215  if (!is_final) {
216  // Some string to make the name of the saved adaptive matrix clear
217  std::string total_steps_str =
218  std::to_string(total_steps);
219  std::string syst_name_str = systematicName;
220  adaptive_cov_name =
221  total_steps_str + '_' + syst_name_str + std::string("_throw_matrix");
222  mean_vec_name =
223  total_steps_str + '_' + syst_name_str + std::string("_mean_vec");
224  }
225 
226  outFile->cd();
227  auto adaptive_to_save = static_cast<TMatrixDSym*>(adaptive_covariance->Clone());
228  // Multiply by scale
229  // HH: Only scale parameters not being skipped
230  for (int i = 0; i < GetNumParams(); ++i) {
231  for (int j = 0; j <= i; ++j) {
232  // If both parameters are skipped, scale by initial scale
233  if ((*_param_skip_adapt_flags)[i] && (*_param_skip_adapt_flags)[j]) {
234  (*adaptive_to_save)(i, j) *= initial_scale * initial_scale;
235  if (i != j) {
236  (*adaptive_to_save)(j, i) *= initial_scale * initial_scale;
237  }
238  }
239  else if (!(*_param_skip_adapt_flags)[i] && !(*_param_skip_adapt_flags)[j]) {
240  (*adaptive_to_save)(i, j) *= GetAdaptionScale() * GetAdaptionScale();
241  if (i != j) {
242  (*adaptive_to_save)(j, i) *= GetAdaptionScale() * GetAdaptionScale();
243  }
244  }
245  else {
246  // Not too sure what to do here, as the correlation should be zero
247  // Scale by both factors as a compromise
248  (*adaptive_to_save)(i, j) *= GetAdaptionScale() * initial_scale;
249  if (i != j) {
250  (*adaptive_to_save)(j, i) *= GetAdaptionScale() * initial_scale;
251  }
252  }
253  }
254  }
255 
256  adaptive_to_save->Write(adaptive_cov_name.c_str());
257  outMeanVec->Write(mean_vec_name.c_str());
258 
259  // HH: Also save the initial throw matrix for reference
261  std::string initial_cov_name = "0_" + systematicName + std::string("_initial_throw_matrix");
262  auto initial_throw_matrix_to_save = static_cast<TMatrixDSym*>(initial_throw_matrix->Clone());
263  *(initial_throw_matrix_to_save) *= initial_scale * initial_scale;
265  initial_throw_matrix_to_save->Write(initial_cov_name.c_str());
266  delete initial_throw_matrix_to_save;
267  }
268 
269  outFile->Close();
270  delete adaptive_to_save;
271  delete outMeanVec;
272  delete outFile;
273  }
274 }
275 
276 // ********************************************
277 // HW : I would like this to be less painful to use!
278 // First things first we need setters
279 void AdaptiveMCMCHandler::SetThrowMatrixFromFile(const std::string& matrix_file_name,
280  const std::string& matrix_name,
281  const std::string& means_name,
282  bool& use_adaptive) {
283 // ********************************************
284  // Lets you set the throw matrix externally
285  // Open file
286  auto matrix_file = std::make_unique<TFile>(matrix_file_name.c_str());
287  use_adaptive = true;
288 
289  if(matrix_file->IsZombie()){
290  MACH3LOG_ERROR("Couldn't find {}", matrix_file_name);
291  throw MaCh3Exception(__FILE__ , __LINE__ );
292  }
293 
294  // Next we grab our matrix
295  adaptive_covariance = static_cast<TMatrixDSym*>(matrix_file->Get(matrix_name.c_str()));
296  if(!adaptive_covariance){
297  MACH3LOG_ERROR("Couldn't find {} in {}", matrix_name, matrix_file_name);
298  throw MaCh3Exception(__FILE__ , __LINE__ );
299  }
300 
301  // Finally we grab the means vector
302  TVectorD* means_vector = static_cast<TVectorD*>(matrix_file->Get(means_name.c_str()));
303 
304  // This is fine to not exist!
305  if(means_vector){
306  // Yay our vector exists! Let's loop and fill it
307  // Should check this is done
308  if(means_vector->GetNrows() != GetNumParams()){
309  MACH3LOG_ERROR("External means vec size ({}) != matrix size ({})", means_vector->GetNrows(), GetNumParams());
310  throw MaCh3Exception(__FILE__, __LINE__);
311  }
312 
313  par_means = std::vector<double>(GetNumParams());
314  for(int i = 0; i < GetNumParams(); i++){
315  par_means[i] = (*means_vector)(i);
316  }
317  MACH3LOG_INFO("Found Means in External File, Will be able to adapt");
318  }
319  // Totally fine if it doesn't exist, we just can't do adaption
320  else{
321  // We don't need a means vector, set the adaption=false
322  MACH3LOG_WARN("Cannot find means vector in {}, therefore I will not be able to adapt!", matrix_file_name);
323  use_adaptive = false;
324  }
325 
326  matrix_file->Close();
327  MACH3LOG_INFO("Set up matrix from external file");
328 }
329 
330 // ********************************************
332 // ********************************************
333  std::vector<double> par_means_prev = par_means;
334  int steps_post_burn = total_steps - start_adaptive_update;
335 
336  prev_step_accepted = false;
337 
338  // Step 1: Update means and compute deviations
339  for (int i = 0; i < GetNumParams(); ++i) {
340  if (IsFixed(i)) continue;
341 
342  par_means[i] = (CurrVal(i) + par_means_prev[i]*steps_post_burn)/(steps_post_burn+1);
343  // Left over from cyclic means
344  }
345 
346  // Step 2: Update covariance
347  #ifdef MULTITHREAD
348  #pragma omp parallel for
349  #endif
350  for (int i = 0; i < GetNumParams(); ++i) {
351  if (IsFixed(i)) {
352  (*adaptive_covariance)(i, i) = 1.0;
353  continue;
354  }
355 
356  int block_i = adapt_block_matrix_indices[i];
357 
358  for (int j = 0; j <= i; ++j) {
359  if (IsFixed(j) || adapt_block_matrix_indices[j] != block_i) {
360  (*adaptive_covariance)(i, j) = 0.0;
361  (*adaptive_covariance)(j, i) = 0.0;
362  continue;
363  }
364 
365  double cov_prev = (*adaptive_covariance)(i, j);
366  double cov_updated = 0.0;
367 
368  // HH: Check if either parameter is skipped
369  // If parameter i and j are both skipped
370  if ((*_param_skip_adapt_flags)[i] && (*_param_skip_adapt_flags)[j]) {
371  // Set covariance to initial throw matrix value
372  (*adaptive_covariance)(i, j) = (*initial_throw_matrix)(i, j);
373  (*adaptive_covariance)(j, i) = (*initial_throw_matrix)(j, i);
374  continue;
375  }
376  // If only one parameter is skipped we need to make sure correlation is zero
377  // because we don't want to change one parameter while keeping the other fixed
378  // as this would lead to penalty terms in the prior
379  else if ((*_param_skip_adapt_flags)[i] || (*_param_skip_adapt_flags)[j]) {
380  continue;
381  } // otherwise adapt as normal
382 
383  if (steps_post_burn > 0) {
384  // Haario-style update
385  double cov_t = cov_prev * (steps_post_burn - 1) / steps_post_burn;
386  double prev_means_t = steps_post_burn * par_means_prev[i] * par_means_prev[j];
387  double curr_means_t = (steps_post_burn + 1) * par_means[i] * par_means[j];
388  double curr_step_t = CurrVal(i) * CurrVal(j);
389 
390  cov_updated = cov_t + (prev_means_t - curr_means_t + curr_step_t) / steps_post_burn;
391  }
392 
393  (*adaptive_covariance)(i, j) = cov_updated;
394  (*adaptive_covariance)(j, i) = cov_updated;
395  }
396  }
397 }
398 
399 // ********************************************
401 // ********************************************
402  if(total_steps == start_adaptive_throw) return true;
403  else return false;
404 }
405 
406 // ********************************************
408 // ********************************************
410  // Check whether the number of steps is divisible by the adaptive update step
411  // e.g. if adaptive_update_step = 1000 and (total_step - start_adpative_throw) is 5000 then this is true
413  return true;
414  }
415  else return false;
416 }
417 
418 // ********************************************
420 // ********************************************
422  total_steps< start_adaptive_update) return true;
423  else return false;
424 }
425 
426 // ********************************************
428 // ********************************************
429  if(total_steps <= start_adaptive_throw) return true;
430  else return false;
431 }
432 
433 // ********************************************
435 // ********************************************
436  MACH3LOG_INFO("Adaptive MCMC Info:");
437  MACH3LOG_INFO("Throwing from New Matrix from Step : {}", start_adaptive_throw);
438  MACH3LOG_INFO("Adaption Matrix Start Update : {}", start_adaptive_update);
439  MACH3LOG_INFO("Adaption Matrix Ending Updates : {}", end_adaptive_update);
440  MACH3LOG_INFO("Steps Between Updates : {}", adaptive_update_step);
441  MACH3LOG_INFO("Saving matrices to file : {}", output_file_name);
442  MACH3LOG_INFO("Will only save every {} iterations" , adaptive_save_n_iterations);
443  if(use_robbins_monro) {
444  MACH3LOG_INFO("Using Robbins-Monro for adaptive step size tuning with target acceptance {}", target_acceptance);
445  }
446 }
447 
448 // ********************************************
449 void AdaptiveMCMCHandler::CheckMatrixValidityForAdaption(const TMatrixDSym *covMatrix) const {
450 // ********************************************
451  int n = covMatrix->GetNrows();
452  std::vector<std::vector<double>> corrMatrix(n, std::vector<double>(n));
453 
454  // Extract standard deviations from the diagonal
455  std::vector<double> stdDevs(n);
456  for (int i = 0; i < n; ++i) {
457  stdDevs[i] = std::sqrt((*covMatrix)(i, i));
458  }
459 
460  // Compute correlation for each element
461  for (int i = 0; i < n; ++i) {
462  for (int j = 0; j < n; ++j) {
463  double cov = (*covMatrix)(i, j);
464  double corr = cov / (stdDevs[i] * stdDevs[j]);
465  corrMatrix[i][j] = corr;
466  }
467  }
468 
469  // KS: These numbers are completely arbitrary
470  constexpr double NumberOfParametersThreshold = 5;
471  constexpr double CorrelationThreshold = 0.5;
472 
473  bool FlagMessage = false;
474  // For each parameter, count how many others it is correlated with
475  for (int i = 0; i < n; ++i) {
476  if (IsFixed(i)) {
477  continue;
478  }
479  int block_i = adapt_block_matrix_indices[i];
480  int correlatedCount = 0;
481  std::vector<int> correlatedWith;
482 
483  for (int j = 0; j < n; ++j) {
484  if (i == j || IsFixed(j) || adapt_block_matrix_indices[j] != block_i) {
485  continue;
486  }
487  if (corrMatrix[i][j] > CorrelationThreshold) {
488  correlatedCount++;
489  correlatedWith.push_back(j);
490  }
491  }
492 
493  if (correlatedCount > NumberOfParametersThreshold) {
494  MACH3LOG_WARN("Parameter {} ({}) is highly correlated with {} other parameters (above threshold {}).", _ParamNames->at(i), i, correlatedCount, CorrelationThreshold);
495  MACH3LOG_WARN("Correlated with parameters: {}.", fmt::join(correlatedWith, ", "));
496  FlagMessage = true;
497  }
498  }
499  if(FlagMessage){
500  MACH3LOG_WARN("Found highly correlated block, adaptive may not work as intended, proceed with caution");
501  MACH3LOG_WARN("You can consider defying so called Adaption Block to not update this part of matrix");
502  }
503 }
504 
505 
506 // ********************************************
507 double AdaptiveMCMCHandler::CurrVal(const int par_index) const {
508 // ********************************************
511  return (*_fCurrVal)[par_index];
512 }
513 
514 // ********************************************
516 // ********************************************
517  /*
518  Obtains the constant "step scale" for Robbins-Monro adaption
519  for simplicity and because it has the degrees of freedom "baked in"
520  it will be same across ALL blocks.
521  */
522 
524  double alpha = -ROOT::Math::normal_quantile(target_acceptance/2, 1.0);
525 
526  int non_fixed_pars = GetNumParams()-GetNFixed();
527 
528  if(non_fixed_pars == 0){
529  MACH3LOG_ERROR("Number of non_fixed_pars is 0, have you fixed all parameters");
530  MACH3LOG_ERROR("This will cause division by 0 and crash ()");
531  throw MaCh3Exception(__FILE__, __LINE__);
532  }
534  c_robbins_monro = (1- 1/non_fixed_pars)*std::sqrt(TMath::Pi()*2 * std::exp(alpha*alpha));
535  c_robbins_monro += 1/(non_fixed_pars*target_acceptance*(1-target_acceptance));
536 
537  MACH3LOG_INFO("Robbins-Monro scale factor set to {}", c_robbins_monro);
538 }
539 
540 // ********************************************
542 // ********************************************
543  /*
544  Update the scale factor using Robbins-Monro.
545  TLDR: If acceptance rate is too high, scale factor goes up, if too low goes down
546  will pretty rapidly converge to the right value.
547  */
548  if ((total_steps>0) && (total_steps % acceptance_rate_batch_size == 0)) {
549  n_rm_restarts++;
550  }
551 
553  int batch_step;
555  batch_step = total_steps;
556  }
557  else{
559  }
560 
561  int non_fixed_pars = GetNumParams()-GetNFixed();
562 
563  // double root_scale = std::sqrt(adaption_scale);
564 
566  double scale_factor = adaption_scale * c_robbins_monro / std::max(200.0, static_cast<double>(batch_step) / non_fixed_pars);
567 
569  if(prev_step_accepted){
570  adaption_scale += (1 - target_acceptance) * scale_factor;
571  }
572  else{
573  adaption_scale -= target_acceptance * scale_factor;
574  }
575 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
Definition: YamlHelper.h:60
const std::vector< bool > * _param_skip_adapt_flags
Parameters to skip during adaption.
bool IndivStepScaleAdapt() const
Tell whether we want reset step scale or not.
void SaveAdaptiveToFile(const std::string &outFileName, const std::string &systematicName, const bool is_final=false)
HW: Save adaptive throw matrix to file.
bool SkipAdaption() const
Tell if we are Skipping Adaption.
bool AdaptionUpdate() const
To be fair not a clue...
int GetNumParams() const
Get the current values of the parameters.
void CheckMatrixValidityForAdaption(const TMatrixDSym *covMatrix) const
Check if there are structures in matrix that could result in failure of adaption fits....
const std::vector< std::string > * _ParamNames
Parameter names.
std::vector< int > GetParIndicesFromNames(const std::vector< std::string > &param_names) const
Convert vector of parameter names to indices.
void SetFixed(const std::vector< double > *fix)
Set the fixed parameters.
double GetAdaptionScale() const
Get the current adaption scale.
bool UpdateMatrixAdapt()
Tell whether matrix should be updated.
int end_adaptive_update
Steps between changing throw matrix.
const TMatrixDSym * initial_throw_matrix
Initial throw matrix.
int total_steps
Total number of MCMC steps.
void UpdateAdaptiveCovariance()
Method to update adaptive MCMC .
void SetThrowMatrixFromFile(const std::string &matrix_file_name, const std::string &matrix_name, const std::string &means_name, bool &use_adaptive)
sets throw matrix from a file
double target_acceptance
Target acceptance rate for Robbins Monro.
int adaptive_update_step
Steps between changing throw matrix.
void UpdateRobbinsMonroScale()
Update the scale factor for Robbins-Monro adaption.
void SetParams(const std::vector< double > *params)
Set the current values of the parameters.
void CreateNewAdaptiveCovariance()
If we don't have a covariance matrix to start from for adaptive tune we need to make one!
bool IsFixed(const int ipar) const
Check if a parameter is fixed.
bool InitFromConfig(const YAML::Node &adapt_manager, const std::string &matrix_name_str, const std::vector< std::string > *parameter_names, const std::vector< double > *parameters, const std::vector< double > *fixed, const std::vector< bool > *param_skip_adapt_flags, const TMatrixDSym *throwMatrix, const double initial_scale_)
Read initial values from config file.
AdaptiveMCMCHandler()
Constructor.
int start_adaptive_update
When do we stop update the adaptive matrix.
TMatrixDSym * adaptive_covariance
Full adaptive covariance matrix.
double initial_scale
Initial scaling factor.
double adaption_scale
Scaling factor.
std::string output_file_name
Name of the file to save the adaptive matrices into.
double CurrVal(const int par_index) const
Get Current value of parameter.
int acceptance_rate_batch_size
Acceptance rate in the current batch.
void CalculateRobbinsMonroStepLength()
Calculate the constant step length for Robbins-Monro adaption.
std::vector< int > adapt_block_sizes
Size of blocks for adaption.
void Print() const
Print all class members.
std::vector< double > par_means
Mean values for all parameters.
int total_rm_restarts
Total number of restarts ALLOWED for Robbins Monro.
bool initial_throw_matrix_saved
Flag to check if initial throw matrix has been saved.
void SetAdaptiveBlocks(const std::vector< std::vector< int >> &block_indices)
HW: sets adaptive block matrix.
bool use_robbins_monro
Use Robbins Monro https://arxiv.org/pdf/1006.3690.
std::vector< int > adapt_block_matrix_indices
Indices for block-matrix adaption.
bool prev_step_accepted
Need to keep track of whether previous step was accepted for RM.
double c_robbins_monro
Constant "step scaling" factor for Robbins-Monro.
int n_rm_restarts
Number of restarts for Robbins Monro (so far)
const std::vector< double > * _fCurrVal
Current values of parameters.
int GetNFixed() const
Get the number of fixed parameters.
virtual ~AdaptiveMCMCHandler()
Destructor.
Custom exception class used throughout MaCh3.