34 const std::vector<std::string>* parameter_names,
35 const std::vector<double>* parameters,
36 const std::vector<double>* fixed,
37 const std::vector<bool>* param_skip_adapt_flags,
38 const TMatrixDSym* throwMatrix,
39 const double initial_scale_) {
62 if(!adapt_manager[
"AdaptionOptions"][
"Covariance"][matrix_name_str]) {
63 MACH3LOG_WARN(
"Adaptive Settings not found for {}, this is fine if you don't want adaptive MCMC", matrix_name_str);
68 if(!GetFromManager<bool>(adapt_manager[
"AdaptionOptions"][
"Covariance"][matrix_name_str][
"DoAdaption"],
false)) {
73 if(!
CheckNodeExists(adapt_manager,
"AdaptionOptions",
"Settings",
"OutputFileName")) {
74 MACH3LOG_ERROR(
"No OutputFileName specified in AdaptionOptions::Settings into your config file");
79 start_adaptive_throw = GetFromManager<int>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"StartThrow"], 10);
80 start_adaptive_update = GetFromManager<int>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"StartUpdate"], 0);
81 end_adaptive_update = GetFromManager<int>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"EndUpdate"], 10000);
82 adaptive_update_step = GetFromManager<int>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"UpdateStep"], 100);
84 output_file_name = GetFromManager<std::string>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"OutputFileName"],
"");
87 use_robbins_monro = GetFromManager<bool>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"UseRobbinsMonro"],
false);
88 target_acceptance = GetFromManager<double>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"TargetAcceptance"], 0.234);
89 if (target_acceptance <= 0 || target_acceptance >= 1) {
94 acceptance_rate_batch_size = GetFromManager<int>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"AcceptanceRateBatchSize"], 10000);
95 total_rm_restarts = GetFromManager<int>(adapt_manager[
"AdaptionOptions"][
"Settings"][
"TotalRobbinsMonroRestarts"], 0);
122 bool matrix_blocks_by_name = GetFromManager<bool>(adapt_manager[
"AdaptionOptions"][
"Covariance"][matrix_name_str][
"MatrixBlocksByName"],
false);
123 std::vector<std::vector<int>> matrix_blocks;
125 if (matrix_blocks_by_name) {
126 auto matrix_blocks_input = GetFromManager<std::vector<std::vector<std::string>>>(adapt_manager[
"AdaptionOptions"][
"Covariance"][matrix_name_str][
"MatrixBlocks"], {{}});
128 for (
const auto& block : matrix_blocks_input) {
130 matrix_blocks.push_back(block_indices);
133 matrix_blocks = GetFromManager<std::vector<std::vector<int>>>(adapt_manager[
"AdaptionOptions"][
"Covariance"][matrix_name_str][
"MatrixBlocks"], {{}});
167 if(block_indices.size()==0 || block_indices[0].size()==0)
return;
169 int block_size =
static_cast<int>(block_indices.size());
171 for(
int iblock=0; iblock < block_size; iblock++){
173 int sub_block_size =
static_cast<int>(block_indices.size()-1);
174 for(
int isubblock=0; isubblock < sub_block_size ; isubblock+=2){
175 int block_lb = block_indices[iblock][isubblock];
176 int block_ub = block_indices[iblock][isubblock+1];
179 MACH3LOG_ERROR(
"Cannot set matrix block with edges {}, {} for matrix of size {}",
183 for(
int ipar = block_lb; ipar < block_ub; ipar++){
195 const std::string &systematicName,
bool is_final) {
203 TFile *outFile =
new TFile(outFileName.c_str(),
"UPDATE");
204 if (outFile->IsZombie()) {
209 TVectorD *outMeanVec =
new TVectorD(
int(
par_means.size()));
210 for (
int i = 0; i < int(
par_means.size()); i++) {
214 std::string adaptive_cov_name = systematicName +
"_posfit_matrix";
215 std::string mean_vec_name = systematicName +
"_mean_vec";
218 std::string total_steps_str =
220 std::string syst_name_str = systematicName;
222 total_steps_str +
'_' + syst_name_str + std::string(
"_throw_matrix");
224 total_steps_str +
'_' + syst_name_str + std::string(
"_mean_vec");
232 for (
int j = 0; j <= i; ++j) {
257 adaptive_to_save->Write(adaptive_cov_name.c_str());
258 outMeanVec->Write(mean_vec_name.c_str());
262 std::string initial_cov_name =
"0_" + systematicName + std::string(
"_initial_throw_matrix");
266 initial_throw_matrix_to_save->Write(initial_cov_name.c_str());
267 delete initial_throw_matrix_to_save;
271 delete adaptive_to_save;
281 const std::string& matrix_name,
282 const std::string& means_name,
283 bool& use_adaptive) {
287 auto matrix_file = std::make_unique<TFile>(matrix_file_name.c_str());
290 if(matrix_file->IsZombie()){
298 MACH3LOG_ERROR(
"Couldn't find {} in {}", matrix_name, matrix_file_name);
303 TVectorD* means_vector =
static_cast<TVectorD*
>(matrix_file->Get(means_name.c_str()));
318 MACH3LOG_INFO(
"Found Means in External File, Will be able to adapt");
323 MACH3LOG_WARN(
"Cannot find means vector in {}, therefore I will not be able to adapt!", matrix_file_name);
324 use_adaptive =
false;
327 matrix_file->Close();
334 std::vector<double> par_means_prev =
par_means;
343 par_means[i] = (
CurrVal(i) + par_means_prev[i]*steps_post_burn)/(steps_post_burn+1);
349 #pragma omp parallel for
353 (*adaptive_covariance)(i, i) = 1.0;
359 for (
int j = 0; j <= i; ++j) {
361 (*adaptive_covariance)(i, j) = 0.0;
362 (*adaptive_covariance)(j, i) = 0.0;
366 double cov_prev = (*adaptive_covariance)(i, j);
367 double cov_updated = 0.0;
384 if (steps_post_burn > 0) {
386 double cov_t = cov_prev * (steps_post_burn - 1) / steps_post_burn;
387 double prev_means_t = steps_post_burn * par_means_prev[i] * par_means_prev[j];
391 cov_updated = cov_t + (prev_means_t - curr_means_t + curr_step_t) / steps_post_burn;
394 (*adaptive_covariance)(i, j) = cov_updated;
395 (*adaptive_covariance)(j, i) = cov_updated;
452 int n = covMatrix->GetNrows();
453 std::vector<std::vector<double>> corrMatrix(n, std::vector<double>(n));
456 std::vector<double> stdDevs(n);
457 for (
int i = 0; i < n; ++i) {
458 stdDevs[i] = std::sqrt((*covMatrix)(i, i));
462 for (
int i = 0; i < n; ++i) {
463 for (
int j = 0; j < n; ++j) {
464 double cov = (*covMatrix)(i, j);
465 double corr = cov / (stdDevs[i] * stdDevs[j]);
466 corrMatrix[i][j] = corr;
471 constexpr
double NumberOfParametersThreshold = 5;
472 constexpr
double CorrelationThreshold = 0.5;
474 bool FlagMessage =
false;
476 for (
int i = 0; i < n; ++i) {
481 int correlatedCount = 0;
482 std::vector<int> correlatedWith;
484 for (
int j = 0; j < n; ++j) {
488 if (corrMatrix[i][j] > CorrelationThreshold) {
490 correlatedWith.push_back(j);
494 if (correlatedCount > NumberOfParametersThreshold) {
495 MACH3LOG_WARN(
"Parameter {} ({}) is highly correlated with {} other parameters (above threshold {}).",
_ParamNames->at(i), i, correlatedCount, CorrelationThreshold);
496 MACH3LOG_WARN(
"Correlated with parameters: {}.", fmt::join(correlatedWith,
", "));
501 MACH3LOG_WARN(
"Found highly correlated block, adaptive may not work as intended, proceed with caution");
502 MACH3LOG_WARN(
"You can consider defying so called Adaption Block to not update this part of matrix");
529 if(non_fixed_pars == 0){
530 MACH3LOG_ERROR(
"Number of non_fixed_pars is 0, have you fixed all parameters");
535 c_robbins_monro = (1- 1/non_fixed_pars)*std::sqrt(TMath::Pi()*2 * std::exp(alpha*alpha));
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
Custom exception class used throughout MaCh3.
std::vector< double > par_means
Mean values for all parameters.
const std::vector< std::string > * _ParamNames
Parameter names.
bool IsFixed(const int ipar) const
Check if a parameter is fixed.
int GetNFixed() const
Get the number of fixed parameters.
double GetAdaptionScale()
Get the current adaption scale.
bool UpdateMatrixAdapt()
Tell whether matrix should be updated.
std::vector< int > adapt_block_matrix_indices
Indices for block-matrix adaption.
std::string output_file_name
Name of the file to save the adaptive matrices into.
double adaption_scale
Scaling factor.
void CheckMatrixValidityForAdaption(const TMatrixDSym *covMatrix) const
Check if there are structures in matrix that could result in failure of adaption fits....
std::vector< int > GetParIndicesFromNames(const std::vector< std::string > ¶m_names) const
Convert vector of parameter names to indices.
void SaveAdaptiveToFile(const std::string &outFileName, const std::string &systematicName, const bool is_final=false)
HW: Save adaptive throw matrix to file.
const std::vector< double > * _fCurrVal
Current values of parameters.
int start_adaptive_update
When do we stop update the adaptive matrix.
double target_acceptance
Target acceptance rate for Robbins Monro.
int acceptance_rate_batch_size
Acceptance rate in the current batch.
std::vector< int > adapt_block_sizes
Size of blocks for adaption.
double initial_scale
Initial scaling factor.
virtual ~AdaptiveMCMCHandler()
Destructor.
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.
int adaptive_save_n_iterations
bool IndivStepScaleAdapt() const
Tell whether we want reset step scale or not.
void SetFixed(const std::vector< double > *fix)
Set the fixed parameters.
void SetParams(const std::vector< double > *params)
Set the current values of the parameters.
void CalculateRobbinsMonroStepLength()
Calculate the constant step length for Robbins-Monro adaption.
AdaptiveMCMCHandler()
Constructor.
void CreateNewAdaptiveCovariance()
If we don't have a covariance matrix to start from for adaptive tune we need to make one!
bool SkipAdaption() const
Tell if we are Skipping Adaption.
const std::vector< bool > * _param_skip_adapt_flags
Parameters to skip during adaption.
int end_adaptive_update
Steps between changing throw matrix.
int total_steps
Total number of MCMC steps.
void Print() const
Print all class members.
void UpdateAdaptiveCovariance()
Method to update adaptive MCMC .
double CurrVal(const int par_index) const
Get Current value of parameter.
int adaptive_update_step
Steps between changing throw matrix.
bool AdaptionUpdate() const
To be fair not a clue...
int n_rm_restarts
Number of restarts for Robbins Monro (so far)
double c_robbins_monro
Constant "step scaling" factor for Robbins-Monro.
bool use_robbins_monro
Use Robbins Monro https://arxiv.org/pdf/1006.3690.
void SetAdaptiveBlocks(const std::vector< std::vector< int >> &block_indices)
HW: sets adaptive block matrix.
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
int GetNumParams() const
Get the current values of the parameters.
void UpdateRobbinsMonroScale()
Update the scale factor for Robbins-Monro adaption.
bool prev_step_accepted
Need to keep track of whether previous step was accepted for RM.
bool initial_throw_matrix_saved
Flag to check if initial throw matrix has been saved.
int total_rm_restarts
Total number of restarts ALLOWED for Robbins Monro.
const TMatrixDSym * initial_throw_matrix
Initial throw matrix.
TMatrixDSym * adaptive_covariance
Full adaptive covariance matrix.