MaCh3  2.6.0
Reference Guide
Public Member Functions | Private Attributes | Static Private Attributes | List of all members
PSO Class Reference

Class PSO, consist of a vector of object Class Particle and global best Takes in the size (number of particle) and number of iteration functions includes: finding global best, updating velocity, actual minimisation function. More...

#include <Fitters/PSO.h>

Inheritance diagram for PSO:
[legend]
Collaboration diagram for PSO:
[legend]

Public Member Functions

 PSO (Manager *const fitMan)
 constructor More...
 
virtual ~PSO ()
 Destructor. More...
 
particleget_best_particle ()
 
void set_best_particle (particle *n)
 
std::vector< std::vector< double > > bisection (const std::vector< double > &position, const double minimum, const double range, const double precision)
 
std::vector< std::vector< double > > calc_uncertainty (const std::vector< double > &position, const double minimum)
 
void init ()
 
void uncertainty_check (const std::vector< double > &previous_pos)
 
void run ()
 
void WriteOutput ()
 
void RunMCMC () final
 Actual implementation of PSO Fit algorithm. More...
 
double CalcChi2 (const double *x) final
 Chi2 calculation over all included samples and syst objects. More...
 
double rastriginFunc (const double *x)
 Evaluates the Rastrigin function for a given parameter values. More...
 
double swarmIterate ()
 
std::vector< double > vector_multiply (std::vector< double > velocity, const double mul)
 
std::vector< double > vector_add (const std::vector< double > &v1, const std::vector< double > &v2)
 
std::vector< double > vector_subtract (const std::vector< double > &v1, const std::vector< double > &v2)
 
std::vector< double > three_vector_addition (std::vector< double > vec1, const std::vector< double > &vec2, const std::vector< double > &vec3)
 
std::vector< double > four_vector_addition (std::vector< double > vec1, const std::vector< double > &vec2, const std::vector< double > &vec3, const std::vector< double > &vec4)
 
double CalcChi (std::vector< double > x)
 
- Public Member Functions inherited from LikelihoodFit
 LikelihoodFit (Manager *const fitMan)
 Constructor. More...
 
virtual ~LikelihoodFit ()
 Destructor. More...
 
int GetNPars () const
 Get total number of params, this sums over all covariance objects. More...
 
- Public Member Functions inherited from FitterBase
 FitterBase (Manager *const fitMan)
 Constructor. More...
 
virtual ~FitterBase ()
 Destructor for the FitterBase class. More...
 
void AddSampleHandler (SampleHandlerInterface *sample)
 This function adds a sample PDF object to the analysis framework. The sample PDF object will be utilized in fitting procedures or likelihood scans. More...
 
void AddSystObj (ParameterHandlerBase *cov)
 This function adds a Covariance object to the analysis framework. The Covariance object will be utilized in fitting procedures or likelihood scans. More...
 
void DragRace (const int NLaps=100)
 Calculates the required time for each sample or covariance object in a drag race simulation. Inspired by Dan's feature. More...
 
void RunLLHScan ()
 Perform a 1D likelihood scan. More...
 
void RunLLHMap ()
 Perform a general multi-dimensional likelihood scan. More...
 
void GetStepScaleBasedOnLLHScan (const std::string &filename="")
 LLH scan is good first estimate of step scale. More...
 
void Run2DLLHScan ()
 Perform a 2D likelihood scan. More...
 
void RunSigmaVar ()
 Perform a 1D/2D sigma var for all samples. More...
 
virtual void StartFromPreviousFit (const std::string &FitName)
 Allow to start from previous fit/chain. More...
 
std::string GetName () const
 Get name of class. More...
 

Private Attributes

particlebest_particle
 
double fBestValue
 
std::vector< double > prior
 
std::vector< bool > fixed
 
std::vector< double > ranges_max
 
std::vector< double > ranges_min
 
std::vector< std::unique_ptr< particle > > system
 
double fInertia
 
double fOne
 
double fTwo
 
double fConvergence
 
int fIterations
 
double fConstriction
 
std::vector< std::vector< double > > uncertainties
 
int fParticles
 
std::vector< std::vector< double > > paramlist
 
double vel [kMaxParticles]
 
int fDim
 

Static Private Attributes

constexpr static const int kMaxParticles = 10000
 

Additional Inherited Members

- Protected Member Functions inherited from LikelihoodFit
void PrepareFit ()
 prepare output and perform sanity checks More...
 
- Protected Member Functions inherited from FitterBase
void ProcessMCMC ()
 Process MCMC output. More...
 
void PrepareOutput ()
 Prepare the output file. More...
 
void SaveOutput ()
 Save output and close files. More...
 
void SanitiseInputs ()
 Remove obsolete memory and make other checks before fit starts. More...
 
void SaveSettings ()
 Save the settings that the MCMC was run with. More...
 
bool GetScanRange (std::map< std::string, std::vector< double >> &scanRanges) const
 YSP: Set up a mapping to store parameters with user-specified ranges, suggested by D. Barrow. More...
 
void GetParameterScanRange (const ParameterHandlerBase *cov, const int i, double &CentralValue, double &lower, double &upper, const int n_points, const std::string &suffix="") const
 Helper function to get parameter scan range, central value. More...
 
bool CheckSkipParameter (const std::vector< std::string > &SkipVector, const std::string &ParamName) const
 KS: Check whether we want to skip parameter using skip vector. More...
 
void CustomRange (const std::string &ParName, const double sigma, double &ParamShiftValue) const
 For comparison with other fitting frameworks (like P-Theta) we usually have to apply different parameter values then usual 1, 3 sigma. More...
 
- Protected Attributes inherited from LikelihoodFit
int NPars
 Number of all parameters from all covariances. More...
 
int NParsPCA
 Number of all parameters from all covariances in PCA base. More...
 
bool fMirroring
 Flag telling if mirroring is used or not. More...
 
- Protected Attributes inherited from FitterBase
ManagerfitMan
 The manager for configuration handling. More...
 
unsigned int step
 current state More...
 
double logLCurr
 current likelihood More...
 
double logLProp
 proposed likelihood More...
 
double accProb
 current acceptance prob More...
 
int accCount
 counts accepted steps More...
 
unsigned int stepStart
 step start, by default 0 if we start from previous chain then it will be different More...
 
std::vector< double > sample_llh
 store the llh breakdowns More...
 
std::vector< double > syst_llh
 systematic llh breakdowns More...
 
std::vector< SampleHandlerInterface * > samples
 Sample holder. More...
 
unsigned int TotalNSamples
 Total number of samples used, single SampleHandler can store more than one analysis sample! More...
 
std::vector< ParameterHandlerBase * > systematics
 Systematic holder. More...
 
std::unique_ptr< TStopwatch > clock
 tells global time how long fit took More...
 
std::unique_ptr< TStopwatch > stepClock
 tells how long single step/fit iteration took More...
 
double stepTime
 Time of single step. More...
 
std::unique_ptr< TRandom3 > random
 Random number. More...
 
TFile * outputFile
 Output. More...
 
TDirectory * CovFolder
 Output cov folder. More...
 
TDirectory * SampleFolder
 Output sample folder. More...
 
TTree * outTree
 Output tree with posteriors. More...
 
int auto_save
 auto save every N steps More...
 
bool fTestLikelihood
 Necessary for some fitting algorithms like PSO. More...
 
bool FileSaved
 Checks if file saved not repeat some operations. More...
 
bool SettingsSaved
 Checks if setting saved not repeat some operations. More...
 
bool OutputPrepared
 Checks if output prepared not repeat some operations. More...
 
std::string AlgorithmName
 Name of fitting algorithm that is being used. More...
 

Detailed Description

Class PSO, consist of a vector of object Class Particle and global best Takes in the size (number of particle) and number of iteration functions includes: finding global best, updating velocity, actual minimisation function.

Author
Emily Ip
Mark Scott
Date
24/2/2023

Definition at line 79 of file PSO.h.

Constructor & Destructor Documentation

◆ PSO()

PSO::PSO ( Manager *const  fitMan)

constructor

Definition at line 6 of file PSO.cpp.

6  : LikelihoodFit(man) {
7 // ***************
8  AlgorithmName = "PSO";
9  fConstriction = Get<double>(fitMan->raw()["General"]["PSO"]["Constriction"], __FILE__, __LINE__);
10  fInertia = Get<double>(fitMan->raw()["General"]["PSO"]["Inertia"], __FILE__, __LINE__) * fConstriction;
11  fOne = Get<double>(fitMan->raw()["General"]["PSO"]["One"], __FILE__, __LINE__) * fConstriction;
12  fTwo = Get<double>(fitMan->raw()["General"]["PSO"]["Two"], __FILE__, __LINE__) * fConstriction;
13  fParticles = Get<int>(fitMan->raw()["General"]["PSO"]["Particles"], __FILE__, __LINE__);
14  fIterations = Get<int>(fitMan->raw()["General"]["PSO"]["Iterations"], __FILE__, __LINE__);
15  fConvergence = Get<double>(fitMan->raw()["General"]["PSO"]["Convergence"], __FILE__, __LINE__);
16 
17  fDim = 0;
18 
19  if(fTestLikelihood)
20  {
21  fDim = Get<int>(fitMan->raw()["General"]["PSO"]["TestLikelihoodDim"], __FILE__, __LINE__);
22  }
23 }
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
bool fTestLikelihood
Necessary for some fitting algorithms like PSO.
Definition: FitterBase.h:163
LikelihoodFit(Manager *const fitMan)
Constructor.
YAML::Node const & raw() const
Return config.
Definition: Manager.h:47
double fConstriction
Definition: PSO.h:159
double fTwo
Definition: PSO.h:156
double fInertia
Definition: PSO.h:154
int fParticles
Definition: PSO.h:162
double fOne
Definition: PSO.h:155
int fIterations
Definition: PSO.h:158
double fConvergence
Definition: PSO.h:157
int fDim
Definition: PSO.h:166

◆ ~PSO()

virtual PSO::~PSO ( )
inlinevirtual

Destructor.

Definition at line 84 of file PSO.h.

84 {};

Member Function Documentation

◆ bisection()

std::vector< std::vector< double > > PSO::bisection ( const std::vector< double > &  position,
const double  minimum,
const double  range,
const double  precision 
)

Definition at line 158 of file PSO.cpp.

159  {
160 // *************************
161  std::vector<std::vector<double>> uncertainties_list;
162  for (unsigned int i = 0; i< position.size(); ++i) {
163  MACH3LOG_INFO("{}", i);
164  //std::vector<double> uncertainties;
165  std::vector<double> new_position = position; new_position[i] = position[i]-range;
166  double val_1 = CalcChi(new_position)-minimum-1.0;
167  while (val_1*-1.0 > 0.0){
168  new_position[i] -= range;
169  val_1 = CalcChi(new_position)-minimum-1.0;
170  }
171  std::vector<double> bisect_position = position; bisect_position[i] = bisect_position[i] - (position[i]-new_position[i])/2;
172  std::vector<std::vector<double>> position_list{new_position,bisect_position,position};
173  double val_2 = CalcChi(bisect_position)-minimum-1.0;
174  std::vector<double> value_list{val_1,val_2, -1.0};
175  double res = 1.0;
176  while (res > precision){
177  if (value_list[0] * value_list[1] < 0){
178  std::vector<double> new_bisect_position = position_list[0];
179  new_bisect_position[i] =new_bisect_position[i]+ (position_list[1][i]-position_list[0][i])/2;
180  double new_val = CalcChi(new_bisect_position)-minimum-1.0;
181  position_list[2] = position_list[1];
182  value_list[2] = value_list[1];
183  value_list[1] = new_val;
184  position_list[1] = new_bisect_position;
185  res = std::abs(position[2]-position[0]);
186  }
187  else{
188  std::vector<double> new_bisect_position = position_list[1];
189  new_bisect_position[i] += (position_list[2][i]-position_list[1][i])/2;
190  double new_val = CalcChi(new_bisect_position)-minimum-1.0;
191  position_list[0] = position_list[1];
192  value_list[0] = value_list[1];
193  value_list[1] = new_val;
194  position_list[1] = new_bisect_position;
195  res = std::abs(position_list[2][i]-position_list[1][i]);
196  }
197  }
198  //do the same thing for position uncertainty
199  std::vector<double> new_position_p = position; new_position_p[i] = position[i]+range;
200  double val_1_p = CalcChi(new_position_p)-minimum-1.0;
201  while (val_1_p * -1.0 > 0.0){
202  new_position_p[i] += range;
203  val_1_p = CalcChi(new_position_p)-minimum-1.0;
204  }
205  std::vector<double> bisect_position_p = position; bisect_position_p[i] = bisect_position_p[i] += (new_position_p[i]-position[i])/2;
206  std::vector<std::vector<double>> position_list_p{position,bisect_position_p,new_position_p};
207  double val_2_p = CalcChi(bisect_position_p)-minimum-1.0;
208  std::vector<double> value_list_p{-1.0,val_2_p, val_1_p};
209  double res_p = 1.0;
210  while (res_p > precision){
211  if (value_list_p[0] * value_list_p[1] < 0){
212  std::vector<double> new_bisect_position_p = position_list_p[0];new_bisect_position_p[i] += (position_list_p[1][i]-position_list_p[0][i])/2;
213  double new_val_p = CalcChi(new_bisect_position_p)-minimum-1.0;
214  position_list_p[2] = position_list_p[1];
215  value_list_p[2] = value_list_p[1];
216  value_list_p[1] = new_val_p;
217  position_list_p[1] = new_bisect_position_p;
218  res = std::abs(position[2]-position[0]);
219  res_p = std::abs(position_list_p[1][i]-position_list_p[0][i]);
220  MACH3LOG_TRACE("Pos midpoint is {:.2f}", position_list_p[1][i]);
221  }
222  else{
223  std::vector<double> new_bisect_position_p = position_list_p[1];new_bisect_position_p[i] += (position_list_p[2][i]-position_list_p[1][i])/2;
224  double new_val_p = CalcChi(new_bisect_position_p)-minimum-1.0;
225  position_list_p[0] = position_list_p[1];
226  value_list_p[0] = value_list_p[1];
227  value_list_p[1] = new_val_p;
228  position_list_p[1] = new_bisect_position_p;
229  res_p = std::abs(position_list_p[2][i]-position_list_p[1][i]);
230  MACH3LOG_TRACE("Pos midpoint is {:.2f}", position_list_p[1][i]);
231  }
232  }
233  uncertainties_list.push_back({std::abs(position[i]-position_list[1][i]),std::abs(position[i]-position_list_p[1][i])});
234  MACH3LOG_INFO("Uncertainty finished for d = {}", i);
235  MACH3LOG_INFO("LLR values for ± positive and negative uncertainties are {:<10.2f} and {:<10.2f}",
236  CalcChi(position_list[1]), CalcChi(position_list_p[1]));
237  }
238  return uncertainties_list;
239 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33
double CalcChi(std::vector< double > x)
Definition: PSO.h:141

◆ calc_uncertainty()

std::vector< std::vector< double > > PSO::calc_uncertainty ( const std::vector< double > &  position,
const double  minimum 
)

Definition at line 242 of file PSO.cpp.

242  {
243 // *************************
244  std::vector<double> pos_uncertainty(position.size());
245  std::vector<double> neg_uncertainty(position.size());
246  constexpr int num = 200;
247  std::vector<double> pos = position;
248  for (unsigned int i = 0; i < position.size(); ++i) {
249  double curr_ival = pos[i];
250 
251  double neg_stop = position[i] - 5e-2;
252  double pos_stop = position[i] + 5e-2;
253  double start = position[i];
254  std::vector<double> x(num);
255  std::vector<double> y(num);
256  double StepPoint = (start-neg_stop) / (num - 1);
257  double value = start;
258  for (int j = 0; j < num; ++j) {
259  pos[i] = value;
260  double LLR = CalcChi(position) - minimum - 1.0;
261  x[j] = value;
262  y[j] = LLR;
263  value -= StepPoint;
264  }
265  pos[i] = curr_ival;
266 
267  int closest_index = 0;
268  double closest_value = std::abs(y[0]); // Initialize with the first element
269  for (unsigned int ii = 1; ii < y.size(); ++ii) {
270  double abs_y = std::abs(y[ii]);
271  if (abs_y < closest_value) {
272  closest_index = ii;
273  closest_value = abs_y;
274  }
275  }
276  neg_uncertainty[i] = x[closest_index];
277  MACH3LOG_INFO("Neg");
278  x.assign(num, 0);
279  y.assign(num, 0);
280  StepPoint = (pos_stop-start) / (num - 1);
281  value = start;
282  for (int j = 0; j < num; ++j) {
283  pos[i] = value;
284  double LLR = CalcChi(position) - minimum - 1.0;
285  x[j] = value;
286  y[j] = LLR;
287  value += StepPoint;
288  }
289  pos[i] = curr_ival;
290  closest_index = 0;
291  closest_value = std::abs(y[0]); // Initialize with the first element
292  for (unsigned int ii = 1; ii < y.size(); ++ii) {
293  double abs_y = std::abs(y[ii]);
294  if (abs_y < closest_value) {
295  closest_index = ii;
296  closest_value = abs_y;
297  }
298  }
299  pos_uncertainty[i] = x[closest_index];
300  }
301  std::vector<std::vector<double>> res{neg_uncertainty,pos_uncertainty};
302  return res;
303 }

◆ CalcChi()

double PSO::CalcChi ( std::vector< double >  x)
inline

Definition at line 141 of file PSO.h.

141  {
142  double* a = &x[0];
143  return CalcChi2(a);
144  };
double CalcChi2(const double *x) final
Chi2 calculation over all included samples and syst objects.
Definition: PSO.cpp:536

◆ CalcChi2()

double PSO::CalcChi2 ( const double *  x)
finalvirtual

Chi2 calculation over all included samples and syst objects.

Reimplemented from LikelihoodFit.

Definition at line 536 of file PSO.cpp.

536  {
537 // *******************
538  if(fTestLikelihood) {
539  return rastriginFunc(x);
540  } else {
541  return LikelihoodFit::CalcChi2(x);
542  }
543 }
virtual double CalcChi2(const double *x)
Chi2 calculation over all included samples and syst objects.
double rastriginFunc(const double *x)
Evaluates the Rastrigin function for a given parameter values.
Definition: PSO.cpp:546

◆ four_vector_addition()

std::vector<double> PSO::four_vector_addition ( std::vector< double >  vec1,
const std::vector< double > &  vec2,
const std::vector< double > &  vec3,
const std::vector< double > &  vec4 
)
inline

Definition at line 133 of file PSO.h.

134  {
135  for (size_t i = 0; i < vec1.size(); ++i) {
136  vec1[i] += vec2[i] + vec3[i] + vec4[i];
137  }
138  return vec1;
139  };

◆ get_best_particle()

particle* PSO::get_best_particle ( )
inline

Definition at line 86 of file PSO.h.

86  {
87  return best_particle;
88  }
particle * best_particle
Definition: PSO.h:144

◆ init()

void PSO::init ( )

Definition at line 58 of file PSO.cpp.

58  {
59 // *************************
61 
62  //KS: For none PCA this will be equal to normal parameters
63  //const int NparsPSOFull = NPars;
64  //const int NparsPSO = NParsPCA;
65 
66  MACH3LOG_INFO("Preparing PSO");
67  // Initialise bounds on parameters
68  if(fTestLikelihood){
69  for (int i = 0; i < fDim; i++){
70  // Test function ranges
71  ranges_min.push_back(-5);
72  ranges_max.push_back(5);
73  fixed.push_back(0);
74  }
75  }
76  else{
77  for (std::vector<ParameterHandlerBase*>::iterator it = systematics.begin(); it != systematics.end(); ++it){
78  if(!(*it)->IsPCA())
79  {
80  fDim += (*it)->GetNumParams();
81  for(int i = 0; i < (*it)->GetNumParams(); ++i)
82  {
83  double curr = (*it)->GetParPreFit(i);
84  double lim = 10.0*(*it)->GetDiagonalError(i);
85  double low = (*it)->GetLowerBound(i);
86  double high = (*it)->GetUpperBound(i);
87  if(low > curr - lim) ranges_min.push_back(low);
88  else ranges_min.push_back(curr - lim);
89  if(high < curr + lim) ranges_min.push_back(high);
90  else ranges_min.push_back(curr + lim);
91  prior.push_back(curr);
92 
93  if((*it)->IsParameterFixed(i)){
94  fixed.push_back(1);
95  }
96  else{
97  fixed.push_back(0);
98  }
99  }
100  }
101  else
102  {
103  fDim += (*it)->GetNParameters();
104  for(int i = 0; i < (*it)->GetNParameters(); ++i)
105  {
106  ranges_min.push_back(-100.0);
107  ranges_max.push_back(100.0);
108  prior.push_back((*it)->GetParPreFit(i));
109  if((*it)->GetPCAHandler()->IsParameterFixedPCA(i)){
110  fixed.push_back(1);
111  }
112  else{
113  fixed.push_back(0);
114  }
115  }
116  }
117  }
118  }
119 
120  MACH3LOG_INFO("Printing Minimums and Maximums of Variables to be minimized");
121  for (int i = 0; i < fDim; i++){
122  MACH3LOG_INFO("Variable {} : {:.2f}, {:.2f}", i, ranges_min[i], ranges_max[i]);
123  }
124 
125  // Initialise particle positions
126  for (int i = 0; i < fParticles; ++i){
127  std::vector<double> init_position;
128  std::vector<double> init_velocity;
129 
130  //Initialising in +/- 5sigma of prior value from BANFF interface
131  for (int j=0; j<fDim; ++j){
132  if(fixed[j]){
133  init_position.push_back(prior[j]);
134  init_velocity.push_back(0.0);
135  }
136  else{
137  double dist = fabs(ranges_max[j]-ranges_min[j]);
138  //Initialise to random position uniform in space
139  init_position.push_back(ranges_min[j] + random->Rndm()*dist);
140  //Initialise velocity to random position uniform in space
141  init_velocity.push_back((2.0*random->Rndm()-1.0));//*dist);
142  }
143  }
144  system.emplace_back(std::make_unique<particle>(init_position, init_velocity));
145  auto& new_particle = system.back();
146  new_particle->set_personal_best_position(init_position);
147  double new_value = CalcChi(init_position);
148  new_particle->set_personal_best_value(new_value);
149  new_particle->set_value(new_value);
150  if(new_value < fBestValue){
151  fBestValue = new_value;
152  set_best_particle(system.back().get());
153  }
154  }
155 }
std::unique_ptr< TRandom3 > random
Random number.
Definition: FitterBase.h:149
std::vector< ParameterHandlerBase * > systematics
Systematic holder.
Definition: FitterBase.h:139
std::vector< std::unique_ptr< particle > > system
Definition: PSO.h:153
std::vector< double > ranges_max
Definition: PSO.h:151
std::vector< bool > fixed
Definition: PSO.h:150
void set_best_particle(particle *n)
Definition: PSO.h:89
double fBestValue
Definition: PSO.h:148
std::vector< double > ranges_min
Definition: PSO.h:152
std::vector< double > prior
Definition: PSO.h:149
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

◆ rastriginFunc()

double PSO::rastriginFunc ( const double *  x)

Evaluates the Rastrigin function for a given parameter values.

Definition at line 546 of file PSO.cpp.

546  {
547 // *************************
548  stepClock->Start();
549 
550  //Search range: [-5.12, 5.12]
551  constexpr double A = 10.0;
552  double sum = 0.0;
553  for (int i = 0; i < fDim; ++i) {
554  sum += x[i] * x[i] - A * cos(2.0 * 3.14 * x[i]);
555  }
556  double llh = A * fDim + sum;
557 
558  accProb = 1;
559 
560  stepClock->Stop();
561  stepTime = stepClock->RealTime();
562 
563  return llh;
564 }
double accProb
current acceptance prob
Definition: FitterBase.h:122
double stepTime
Time of single step.
Definition: FitterBase.h:146
std::unique_ptr< TStopwatch > stepClock
tells how long single step/fit iteration took
Definition: FitterBase.h:144

◆ run()

void PSO::run ( )

Definition at line 404 of file PSO.cpp.

404  {
405 // *************************
406  double mean_dist_sq = 0;
407 
408  int iter = 0;
409  for(int i = 0; i < fIterations; ++i, ++iter){
410  mean_dist_sq = swarmIterate();
411  //double meanVel = std::accumulate(vel, vel + fParticles, 0) / fParticles;
412 
413  // Weight inertia randomly but scaled by total distance of swarm from global minimum - proxy for total velocity
414  // fWeight = ((random->Rndm()+1.0)*0.5)*(10.0/meanVel);
415 
417 
418  outTree->Fill();
419  // Auto save the output
420  if (step % auto_save == 0) outTree->AutoSave();
421  step++;
422  accCount++;
423 
424  if (i%100 == 0){
425  MACH3LOG_INFO("Mean Dist Sq = {:.2f}", mean_dist_sq);
426  MACH3LOG_INFO("Current LLR = {:.2f}", fBestValue);
427  MACH3LOG_INFO("Position:");
428  for (int j = 0; j < fDim; ++j){
429  MACH3LOG_INFO(" Dim {} = {:<10.2f}", j, get_best_particle()->get_personal_best_position()[j]);
430  }
431  }
432  if(fConvergence > 0.0){
433  if(mean_dist_sq < fConvergence){
434  break;
435  }
436  }
437  }
438  MACH3LOG_INFO("Finished after {} runs out of {}", iter, fIterations);
439  MACH3LOG_INFO("Mean Dist: {:.2f}", mean_dist_sq);
440  MACH3LOG_INFO("Best LLR: {:.2f}", get_best_particle()->get_personal_best_value());
441  uncertainties = bisection(get_best_particle()->get_personal_best_position(),get_best_particle()->get_personal_best_value(),0.5,0.005);
442  MACH3LOG_INFO("Position for Global Minimum = ");
443  for (int i = 0; i< fDim; ++i){
444  MACH3LOG_INFO(" Dim {} = {:<10.2f} +{:.2f}, -{:.2f}", i, get_best_particle()->get_personal_best_position()[i], uncertainties[i][1], uncertainties[i][0]);
445  }
446 }
int accCount
counts accepted steps
Definition: FitterBase.h:124
unsigned int step
current state
Definition: FitterBase.h:116
double logLCurr
current likelihood
Definition: FitterBase.h:118
int auto_save
auto save every N steps
Definition: FitterBase.h:160
TTree * outTree
Output tree with posteriors.
Definition: FitterBase.h:158
std::vector< std::vector< double > > bisection(const std::vector< double > &position, const double minimum, const double range, const double precision)
Definition: PSO.cpp:158
particle * get_best_particle()
Definition: PSO.h:86
std::vector< std::vector< double > > uncertainties
Definition: PSO.h:160
double swarmIterate()
Definition: PSO.cpp:344

◆ RunMCMC()

void PSO::RunMCMC ( )
finalvirtual

Actual implementation of PSO Fit algorithm.

Implements FitterBase.

Definition at line 26 of file PSO.cpp.

26  {
27 // ***************
28  PrepareFit();
29 
30  // Remove obsolete memory and make other checks before fit starts
32 
33  // Sanitise the adaptive MCMC
34  for (const auto &syst : systematics) {
35  if (syst->GetDoAdaption()) {
36  MACH3LOG_ERROR("Param Handler {} has enabled Adaption, this is not needed for {} so please turn it off", syst->GetName(), GetName());
37  throw MaCh3Exception(__FILE__ , __LINE__ );
38  }
39  }
40 
41  if(fTestLikelihood){
42  outTree->Branch("nParts", &fParticles, "nParts/I");
43  for(int i = 0; i < fDim; ++i){
44  paramlist.emplace_back(fParticles);
45  outTree->Branch(Form("Parameter_%d", i), paramlist[i].data(), Form("Parameter_%d[nParts]/D",i));
46  }
47 // vel = new double[fParticles];
48  outTree->Branch("vel", vel, "vel[nParts]/D");
49  }
50 
51  init();
52  run();
53  WriteOutput();
54  return;
55 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
std::string GetName() const
Get name of class.
Definition: FitterBase.h:75
void SanitiseInputs()
Remove obsolete memory and make other checks before fit starts.
Definition: FitterBase.cpp:221
void PrepareFit()
prepare output and perform sanity checks
Custom exception class used throughout MaCh3.
void init()
Definition: PSO.cpp:58
std::vector< std::vector< double > > paramlist
Definition: PSO.h:163
double vel[kMaxParticles]
Definition: PSO.h:165
void run()
Definition: PSO.cpp:404
void WriteOutput()
Definition: PSO.cpp:449

◆ set_best_particle()

void PSO::set_best_particle ( particle n)
inline

Definition at line 89 of file PSO.h.

89  {
90  best_particle = n;
91  }

◆ swarmIterate()

double PSO::swarmIterate ( )

Definition at line 344 of file PSO.cpp.

344  {
345 // *************************
346  std::vector<double> total_pos(fDim,0.0);
347 
348  for (int i = 0; i < fParticles; ++i) {
349  std::vector<double> part1 = vector_multiply(system[i]->get_velocity(), fInertia);
350  std::vector<double> part2 = vector_multiply(vector_subtract(system[i]->get_personal_best_position(), system[i]->get_position()), (fOne * random->Rndm()));
351  std::vector<double> part3 = vector_multiply(vector_subtract(get_best_particle()->get_personal_best_position(), system[i]->get_position()),(fTwo * random->Rndm()));
352  std::vector<double> new_velocity = three_vector_addition(part1, part2, part3);
353  std::vector<double> new_pos = vector_add(system[i]->get_position(), new_velocity);
354  transform(total_pos.begin(), total_pos.end(), new_pos.begin(), total_pos.begin(),[](double x, double y) {return x+y;});
355 
356  for (int j = 0; j < fDim; ++j) {
357  // Check if out of bounds and reflect if so
358  if(ranges_min[j] > new_pos[j]){
359  new_pos[j] = ranges_min[j];
360  }
361  else if(new_pos[j] > ranges_max[j]) {
362  new_pos[j] = ranges_max[j];
363  }
364  // If parameter fixed don't update it
365  if(fixed[j]) new_pos[j] = system[i]->get_position()[j];
366  }
367 
368  if(fTestLikelihood){
369  double velo = 0.0;
370  for (int j = 0; j < fDim; ++j) {
371  paramlist[j][i] = new_pos[j];
372  velo += new_velocity[j]*new_velocity[j];
373  }
374  vel[i] = sqrt(velo);
375  }
376 
377  system[i]->set_velocity(new_velocity);
378  system[i]->set_position(new_pos);
379  double new_value = CalcChi(new_pos);
380  if(new_value <= system[i]->get_personal_best_value()) {
381  system[i]->set_personal_best_value(new_value);
382  system[i]->set_personal_best_position(new_pos);
383  if(new_value < fBestValue){
384  fBestValue = new_value;
385  set_best_particle(system[i].get());
386  }
387  }
388  }
389 
390  std::vector<double> best_pos = get_best_particle()->get_personal_best_position();
391  std::vector<double> result(best_pos.size(), 0.0);
392  transform(total_pos.begin(), total_pos.end(), total_pos.begin(), [this](double val){return val/fParticles;});
393  transform(total_pos.begin(),total_pos.end(),best_pos.begin(),result.begin(),[](double x, double y) {return x-y;});
394 
395  double mean_dist_sq = 0;
396  for (int i = 0; i<fDim; i++){
397  mean_dist_sq += result[i]*result[i];
398  }
399 
400  return mean_dist_sq;
401 }
std::vector< double > vector_subtract(const std::vector< double > &v1, const std::vector< double > &v2)
Definition: PSO.h:120
std::vector< double > vector_multiply(std::vector< double > velocity, const double mul)
Definition: PSO.h:107
std::vector< double > three_vector_addition(std::vector< double > vec1, const std::vector< double > &vec2, const std::vector< double > &vec3)
Definition: PSO.h:125
std::vector< double > vector_add(const std::vector< double > &v1, const std::vector< double > &v2)
Definition: PSO.h:115
std::vector< double > get_personal_best_position()
Definition: PSO.h:36

◆ three_vector_addition()

std::vector<double> PSO::three_vector_addition ( std::vector< double >  vec1,
const std::vector< double > &  vec2,
const std::vector< double > &  vec3 
)
inline

Definition at line 125 of file PSO.h.

127  {
128  for (size_t i = 0; i < vec1.size(); ++i) {
129  vec1[i] += vec2[i] + vec3[i];
130  }
131  return vec1;
132  };

◆ uncertainty_check()

void PSO::uncertainty_check ( const std::vector< double > &  previous_pos)

Definition at line 306 of file PSO.cpp.

306  {
307 // *************************
308  std::vector<std::vector<double >> x_list;
309  std::vector<std::vector<double >> y_list;
310  std::vector<double> position = previous_pos;
311  constexpr int num = 5000;
312  for (unsigned int i = 0;i<previous_pos.size();++i){
313  double curr_ival = position[i];
314  double start = previous_pos[i] - 1e-1;
315  double stop = previous_pos[i] + 1e-1;
316  std::vector<double> x(num);
317  std::vector<double> y(num);
318  double StepPoint = (stop - start) / (num - 1);
319  double value = start;
320  MACH3LOG_TRACE("result for fDim: {}", 1);
321  for (int j = 0;j < num; ++j) {
322  position[i] = value;
323  double LLR = CalcChi(position);
324  x[j] = value;
325  y[j] = LLR;
326  value += StepPoint;
327  }
328  position[i] = curr_ival;
329  MACH3LOG_INFO("");
330  MACH3LOG_INFO("For fDim{} x list is", i+1);
331  for (unsigned int k = 0; k < x.size(); ++k){
332  MACH3LOG_INFO(" {}", x[k]);
333  }
334  MACH3LOG_INFO("");
335  MACH3LOG_INFO("For fDim{} y list is", i+1);
336  for (unsigned int k = 0; k < x.size(); ++k){
337  MACH3LOG_INFO(" {}", y[k]);
338  }
339  MACH3LOG_INFO("");
340  }
341 }

◆ vector_add()

std::vector<double> PSO::vector_add ( const std::vector< double > &  v1,
const std::vector< double > &  v2 
)
inline

Definition at line 115 of file PSO.h.

115  {
116  std::vector<double> v3;
117  transform(v1.begin(), v1.end(), v2.begin(), back_inserter(v3), std::plus<double>());
118  return v3;
119  };

◆ vector_multiply()

std::vector<double> PSO::vector_multiply ( std::vector< double >  velocity,
const double  mul 
)
inline

Definition at line 107 of file PSO.h.

107  {
108  // std::bind1st deprecated since C++11, removed in c++17
109  // transform(velocity.begin(),velocity.end(),velocity.begin(),std::bind1st(std::multiplies<double>(),mul));
110  std::transform(velocity.begin(), velocity.end(), velocity.begin(),
111  std::bind(std::multiplies<double>(), mul, std::placeholders::_1));
112  return velocity;
113  };

◆ vector_subtract()

std::vector<double> PSO::vector_subtract ( const std::vector< double > &  v1,
const std::vector< double > &  v2 
)
inline

Definition at line 120 of file PSO.h.

120  {
121  std::vector<double> v3 ;
122  transform(v1.begin(), v1.end(), v2.begin(), back_inserter(v3), std::minus<double>());
123  return v3;
124  };

◆ WriteOutput()

void PSO::WriteOutput ( )

Definition at line 449 of file PSO.cpp.

449  {
450 // *************************
451  outputFile->cd();
452 
453  TVectorD* PSOParValue = new TVectorD(fDim);
454  TVectorD* PSOParError = new TVectorD(fDim);
455 
456  for(int i = 0; i < fDim; ++i)
457  {
458  (*PSOParValue)(i) = 0;
459  (*PSOParError)(i) = 0;
460  }
461 
462  std::vector<double> minimum = get_best_particle()->get_personal_best_position();
463 
464  int ParCounter = 0;
465 
466  if(fTestLikelihood){
467  for(int i = 0; i < fDim; ++i){
468  (*PSOParValue)(i) = minimum[i];
469  (*PSOParError)(i) = (uncertainties[i][0]+uncertainties[i][1])/2.0;
470  }
471  }
472  else{
473  for (auto& ParHandler : systematics)
474  {
475  if(!ParHandler->IsPCA())
476  {
477  for(int i = 0; i < ParHandler->GetNumParams(); ++i, ++ParCounter)
478  {
479  double ParVal = minimum[ParCounter];
480  //KS: Basically apply mirroring for parameters out of bounds
481  (*PSOParValue)(ParCounter) = ParVal;
482  (*PSOParError)(ParCounter) = (uncertainties[ParCounter][0]+uncertainties[ParCounter][1])/2.0;
483  //KS: For fixed params HESS will not calcuate error so we need to pass prior error
484  if(ParHandler->IsParameterFixed(i))
485  {
486  (*PSOParError)(ParCounter) = ParHandler->GetDiagonalError(i);
487  }
488  }
489  }
490  else
491  {
492  //KS: We need to convert parameters from PCA to normal base
493  TVectorD ParVals(ParHandler->GetNumParams());
494  TVectorD ParVals_PCA(ParHandler->GetNParameters());
495 
496  TVectorD ErrorVals(ParHandler->GetNumParams());
497  TVectorD ErrorVals_PCA(ParHandler->GetNParameters());
498 
499  //First save them
500  //KS: This code is super convoluted as MaCh3 can store separate matrices while PSO has one matrix. In future this will be simplified, keep it like this for now.
501  const int StartVal = ParCounter;
502  for(int i = 0; i < ParHandler->GetNParameters(); ++i, ++ParCounter)
503  {
504  ParVals_PCA(i) = minimum[ParCounter];
505  ErrorVals_PCA(i) = (uncertainties[ParCounter][0]+uncertainties[ParCounter][1])/2.0;
506  }
507  ParVals = (ParHandler->GetPCAHandler()->GetTransferMatrix())*ParVals_PCA;
508  ErrorVals = (ParHandler->GetPCAHandler()->GetTransferMatrix())*ErrorVals_PCA;
509 
510  ParCounter = StartVal;
511  //KS: Now after going from PCA to normal let';s save it
512  for(int i = 0; i < ParHandler->GetNumParams(); ++i, ++ParCounter)
513  {
514  (*PSOParValue)(ParCounter) = ParVals(i);
515  (*PSOParError)(ParCounter) = std::fabs(ErrorVals(i));
516  //int ParCounterMatrix = StartVal;
517  //If fixed take prior
518  if(ParHandler->GetPCAHandler()->IsParameterFixedPCA(i))
519  {
520  (*PSOParError)(ParCounter) = ParHandler->GetDiagonalError(i);
521  }
522  }
523  }
524  }
525  }
526 
527  PSOParValue->Write("PSOParValue");
528  PSOParError->Write("PSOParError");
529  delete PSOParValue;
530  delete PSOParError;
531  // Save all the output
532  SaveOutput();
533 }
void SaveOutput()
Save output and close files.
Definition: FitterBase.cpp:229
TFile * outputFile
Output.
Definition: FitterBase.h:152

Member Data Documentation

◆ best_particle

particle* PSO::best_particle
private

Definition at line 147 of file PSO.h.

◆ fBestValue

double PSO::fBestValue
private

Definition at line 148 of file PSO.h.

◆ fConstriction

double PSO::fConstriction
private

Definition at line 159 of file PSO.h.

◆ fConvergence

double PSO::fConvergence
private

Definition at line 157 of file PSO.h.

◆ fDim

int PSO::fDim
private

Definition at line 166 of file PSO.h.

◆ fInertia

double PSO::fInertia
private

Definition at line 154 of file PSO.h.

◆ fIterations

int PSO::fIterations
private

Definition at line 158 of file PSO.h.

◆ fixed

std::vector<bool> PSO::fixed
private

Definition at line 150 of file PSO.h.

◆ fOne

double PSO::fOne
private

Definition at line 155 of file PSO.h.

◆ fParticles

int PSO::fParticles
private

Definition at line 162 of file PSO.h.

◆ fTwo

double PSO::fTwo
private

Definition at line 156 of file PSO.h.

◆ kMaxParticles

constexpr static const int PSO::kMaxParticles = 10000
staticconstexprprivate

Definition at line 164 of file PSO.h.

◆ paramlist

std::vector<std::vector<double> > PSO::paramlist
private

Definition at line 163 of file PSO.h.

◆ prior

std::vector<double> PSO::prior
private

Definition at line 149 of file PSO.h.

◆ ranges_max

std::vector<double> PSO::ranges_max
private

Definition at line 151 of file PSO.h.

◆ ranges_min

std::vector<double> PSO::ranges_min
private

Definition at line 152 of file PSO.h.

◆ system

std::vector<std::unique_ptr<particle> > PSO::system
private

Definition at line 153 of file PSO.h.

◆ uncertainties

std::vector<std::vector<double> > PSO::uncertainties
private

Definition at line 160 of file PSO.h.

◆ vel

double PSO::vel[kMaxParticles]
private

Definition at line 165 of file PSO.h.


The documentation for this class was generated from the following files: