17 std::vector<M3::float_t>* fProp_Val) {
25 const double eigen_thresh,
const int _fNumPar) {
32 if (CovMatrix ==
nullptr) {
39 MACH3LOG_ERROR(
"FirstPCAdpar and LastPCAdpar are higher than the number of parameters");
44 MACH3LOG_ERROR(
"FirstPCAdpar and LastPCAdpar are less than 0 but not default -999");
57 TMatrixDSymEigen eigen(submat);
94 temp2.ResizeTo(CovMatrix->GetNrows(),
NumParPCA);
101 temp2(iRow, iRow) = 1.0;
109 for(
int iRow = 0;iRow < (CovMatrix->GetNrows()-1)-
LastPCAdpar; iRow++) {
112 temp2(OrigRow, PCARow) = 1.;
153 constexpr
double correlation_threshold = 1e-6;
155 bool found_significant_correlation =
false;
157 int N = CovMatrix->GetNrows();
159 for (
int j = 0; j < N; ++j) {
163 double corr_val = (*CovMatrix)(i, j);
164 if (std::fabs(corr_val) > correlation_threshold) {
165 found_significant_correlation =
true;
166 MACH3LOG_ERROR(
"Significant correlation detected between decomposed parameter '{}' "
167 "and undecomposed parameter '{}': {:.6e}", i, j, corr_val);
172 if (found_significant_correlation) {
173 MACH3LOG_ERROR(
"There are correlations between undecomposed and decomposed part of matrices, this will not work");
184 #pragma omp parallel for
196 const double GlobalStepScale,
202 #pragma omp parallel for
204 for (
int i = 0; i < NumParPCA; ++i)
206 if (_fErrorPCA[i] > 0.)
208 double IndStepScale = 1.;
210 if(isDecomposedPCA[i] >= 0)
212 IndStepScale *= IndivStepScale[isDecomposedPCA[i]];
213 IndStepScale *= corr_throw[isDecomposedPCA[i]];
218 IndStepScale *= randParams[i];
220 IndStepScale *= IndivStepScale[FirstPCAdpar];
222 _fParPropPCA(i) = _fParCurrPCA(i)+GlobalStepScale*IndStepScale*eigen_values_master[i];
234 TVectorD fParCurr_vec(
static_cast<Int_t
>(
_pCurrVal->size()));
235 TVectorD fParProp_vec(
static_cast<Int_t
>(
_pCurrVal->size()));
236 for(
int i = 0; i < static_cast<int>(
_pCurrVal->size()); ++i) {
237 fParCurr_vec(i) = (*_pCurrVal)[i];
238 fParProp_vec(i) = (*_pPropVal)[i];
258 #pragma GCC diagnostic push
259 #pragma GCC diagnostic ignored "-Wuseless-cast"
264 #pragma omp parallel for
266 for(
int i = 0; i < static_cast<int>(
_pCurrVal->size()); ++i) {
267 (*_pPropVal)[i] =
static_cast<M3::float_t>(fParProp_vec(i));
268 (*_pCurrVal)[i] = fParCurr_vec(i);
270 #pragma GCC diagnostic pop
286 tree.Branch(Form(
"%s_PCA", Names[i].c_str()), &
_fParCurrPCA.GetMatrixArray()[i], Form(
"%s_PCA/D", Names[i].c_str()));
292 tree.Branch(Form(
"%s_PCA_Prop", Names[i].c_str()), &
_fParPropPCA.GetMatrixArray()[i], Form(
"%s_PCA_Prop/D", Names[i].c_str()));
311 MACH3LOG_ERROR(
"Parameter {} is PCA decomposed can't fix this", Names[i]);
316 else MACH3LOG_INFO(
"Setting un-decomposed {}(parameter {}/{} in PCA base) free", Names[i], i, isDecom);
323 double** throwMatrixCholDecomp,
326 const std::vector<double>& fPreFitValue,
327 const std::vector<double>& fLowBound,
328 const std::vector<double>& fUpBound,
329 const int _fNumPar) {
331 #pragma GCC diagnostic push
332 #pragma GCC diagnostic ignored "-Wuseless-cast"
340 (*_pPropVal)[i] =
static_cast<M3::float_t>(fPreFitValue[i] + corr_throw[i]);
343 while ((*
_pPropVal)[i] > fUpBound[i] || (*_pPropVal)[i] < fLowBound[i]) {
346 (*_pPropVal)[i] =
static_cast<M3::float_t>(fPreFitValue[i] + corr_throw_single);
351 MACH3LOG_WARN(
"Tried {} times to throw parameter {} but failed",
throws, i);
354 (*_pPropVal)[i] =
static_cast<M3::float_t>(fPreFitValue[i]);
358 (*_pCurrVal)[i] = (*_pPropVal)[i];
368 for (
int i = 0; i < _fNumPar; ++i) {
371 (*_pPropVal)[i] = std::max(up, std::min((*
_pPropVal)[i], low));
372 (*_pCurrVal)[i] = (*_pPropVal)[i];
374 #pragma GCC diagnostic pop
#define _noexcept_
KS: noexcept can help with performance but is terrible for debugging, this is meant to help easy way ...
#define _restrict_
KS: Using restrict limits the effects of pointer aliasing, aiding optimizations. While reading I foun...
Custom exception class used throughout MaCh3.
std::vector< int > isDecomposedPCA
If param is decomposed this will return -1, if not this will return enumerator to param in normal bas...
void ThrowParameters(const std::vector< std::unique_ptr< TRandom3 >> &random_number, double **throwMatrixCholDecomp, double *randParams, double *corr_throw, const std::vector< double > &fPreFitValue, const std::vector< double > &fLowBound, const std::vector< double > &fUpBound, int _fNumPar)
Throw the parameters according to the covariance matrix. This shouldn't be used in MCMC code ase it c...
void ToggleFixAllParameters(const std::vector< std::string > &Names)
fix parameters at prior values
TMatrixD TransferMat
Matrix used to converting from PCA base to normal base.
std::vector< double > eigen_values_master
Eigen values which have dimension equal to _fNumParPCA, and can be used in CorrelateSteps.
void SetBranches(TTree &tree, const bool SaveProposal, const std::vector< std::string > &Names)
set branches for output file
TMatrixD eigen_vectors
Eigen vectors only of params which are being decomposed.
TVectorD _fParPropPCA
CW: Current parameter value in PCA base.
bool IsParameterFixedPCA(const int i) const
Is parameter fixed in PCA base or not.
void SetupPointers(std::vector< double > *fCurr_Val, std::vector< M3::float_t > *fProp_Val)
KS: Setup pointers to current and proposed parameter value which we need to convert them to PCA base ...
double GetParPropPCA(const int i) const
Get current parameter value using PCA.
int NumParPCA
Number of parameters in PCA base.
void SetInitialParameters()
KS: Transfer the starting parameters to the PCA basis, you don't want to start with zero....
std::vector< M3::float_t > * _pPropVal
Pointer to proposed value of the parameter.
std::vector< double > * _pCurrVal
Pointer to current value of the parameter.
TMatrixD TransferMatT
Matrix used to converting from normal base to PCA base.
void AcceptStep() _noexcept_
Accepted this step.
void CorrelateSteps(const std::vector< double > &IndivStepScale, const double GlobalStepScale, const double *_restrict_ randParams, const double *_restrict_ corr_throw) _noexcept_
Use Cholesky throw matrix for better step proposal.
void SetParPropPCA(const int i, const double value)
Set proposed value for parameter in PCA base.
void TransferToPCA()
Transfer param values from normal base to PCA base.
virtual ~PCAHandler()
Destructor.
double GetPreFitValuePCA(const int i) const
Get current parameter value using PCA.
bool IsParameterDecomposed(const int i) const
Check if parameter in PCA base is decomposed or not.
TVectorD eigen_values
Eigen value only of particles which are being decomposed.
void TransferToParam()
Transfer param values from PCA base to normal base.
int LastPCAdpar
Index of the last param that is being decomposed.
int nKeptPCApars
Total number that remained after applying PCA Threshold.
std::vector< double > _fErrorPCA
Tells if parameter is fixed in PCA base or not.
std::vector< double > _fPreFitValuePCA
Prefit value for PCA params.
void ToggleFixParameter(const int i, const std::vector< std::string > &Names)
fix parameters at prior values
void SetParCurrPCA(const int i, const double value)
Set current value for parameter in PCA base.
void Print() const
KS: Print info about PCA parameters.
TVectorD _fParCurrPCA
CW: Proposed parameter value in PCA base.
void SanitisePCA(TMatrixDSym *CovMatrix)
KS: Make sure decomposed matrix isn't correlated with undecomposed.
void ConstructPCA(TMatrixDSym *CovMatrix, const int firstPCAd, const int lastPCAd, const double eigen_thresh, const int _fNumPar)
CW: Calculate eigen values, prepare transition matrices and remove param based on defined threshold.
int FirstPCAdpar
Index of the first param that is being decomposed.
double eigen_threshold
CW: Threshold based on which we remove parameters in eigen base.
int GetThreadIndex()
thread index inside parallel loop
double MatrixVectorMultiSingle(double **_restrict_ matrix, const double *_restrict_ vector, const int Length, const int i)
KS: Custom function to perform multiplication of matrix and single element which is thread safe.
void DebugPCA(const double sum, const TMatrixD &temp, const TMatrixD &eigen_vectors, const TVectorD &eigen_values, const TMatrixD &TransferMat, const TMatrixD &TransferMatT, const int NumPar, const int FirstPCAdpar, const int LastPCAdpar, const int nKeptPCApars, const double eigen_threshold)
KS: Let's dump all useful matrices to properly validate PCA.