MaCh3  2.2.3
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 () override
 Actual implementation of PSO Fit algorithm. More...
 
double CalcChi2 (const double *x) override
 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 ()
 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 (SampleHandlerBase *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 GetStepScaleBasedOnLLHScan ()
 LLH scan is good first estimate of step scale. More...
 
void Run2DLLHScan ()
 Perform a 2D likelihood scan. More...
 
void RunSigmaVar ()
 Perform a 2D and 1D sigma var for all samples. More...
 
void RunSigmaVarFD ()
 Perform a 1D 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< particle * > system
 
double fInertia
 
double fOne
 
double fTwo
 
double fConvergence
 
int fIterations
 
double fConstriction
 
std::vector< std::vector< double > > uncertainties
 
int fParticles
 
std::vector< double * > paramlist
 
double vel [kMaxParticles]
 
double * par
 
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 GetScaneRange (std::map< std::string, std::vector< double >> &scanRanges)
 YSP: Set up a mapping to store parameters with user-specified ranges, suggested by D. Barrow. 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)
 For comparison with 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. 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< SampleHandlerBase * > samples
 Sample holder. More...
 
unsigned int TotalNSamples
 Total number of samples used. 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 77 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 }
MaCh3Plotting::PlottingManager * man
manager * fitMan
The manager.
Definition: FitterBase.h:110
std::string AlgorithmName
Name of fitting algorithm that is being used.
Definition: FitterBase.h:170
bool fTestLikelihood
Necessary for some fitting algorithms like PSO.
Definition: FitterBase.h:160
LikelihoodFit(manager *const fitMan)
Constructor.
double fConstriction
Definition: PSO.h:157
double fTwo
Definition: PSO.h:154
double fInertia
Definition: PSO.h:152
int fParticles
Definition: PSO.h:160
double fOne
Definition: PSO.h:153
int fIterations
Definition: PSO.h:156
double fConvergence
Definition: PSO.h:155
int fDim
Definition: PSO.h:166
YAML::Node const & raw()
Return config.
Definition: Manager.h:41

◆ ~PSO()

virtual PSO::~PSO ( )
inlinevirtual

Destructor.

Definition at line 82 of file PSO.h.

82 {};

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 152 of file PSO.cpp.

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

◆ calc_uncertainty()

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

Definition at line 237 of file PSO.cpp.

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

◆ CalcChi()

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

Definition at line 139 of file PSO.h.

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

◆ CalcChi2()

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

Chi2 calculation over all included samples and syst objects.

Reimplemented from LikelihoodFit.

Definition at line 531 of file PSO.cpp.

531  {
532 // *******************
533  if(fTestLikelihood) {
534  return rastriginFunc(x);
535  } else {
536  return LikelihoodFit::CalcChi2(x);
537  }
538 }
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:541

◆ 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 131 of file PSO.h.

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

◆ get_best_particle()

particle* PSO::get_best_particle ( )
inline

Definition at line 84 of file PSO.h.

84  {
85  return best_particle;
86  }
particle * best_particle
Definition: PSO.h:142

◆ init()

void PSO::init ( )

Definition at line 51 of file PSO.cpp.

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

◆ rastriginFunc()

double PSO::rastriginFunc ( const double *  x)

Evaluates the Rastrigin function for a given parameter values.

Definition at line 541 of file PSO.cpp.

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

◆ run()

void PSO::run ( )

Definition at line 399 of file PSO.cpp.

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

◆ RunMCMC()

void PSO::RunMCMC ( )
overridevirtual

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  if(fTestLikelihood){
34  outTree->Branch("nParts", &fParticles, "nParts/I");
35  for(int i = 0; i < fDim; ++i){
36  par = new double[fParticles];
37  paramlist.push_back(par);
38  outTree->Branch(Form("Parameter_%d", i), paramlist[i], Form("Parameter_%d[nParts]/D",i));
39  }
40 // vel = new double[fParticles];
41  outTree->Branch("vel", vel, "vel[nParts]/D");
42  }
43 
44  init();
45  run();
46  WriteOutput();
47  return;
48 }
void SanitiseInputs()
Remove obsolete memory and make other checks before fit starts.
Definition: FitterBase.cpp:222
void PrepareFit()
prepare output and perform sanity checks
void init()
Definition: PSO.cpp:51
std::vector< double * > paramlist
Definition: PSO.h:161
double vel[kMaxParticles]
Definition: PSO.h:163
double * par
Definition: PSO.h:164
void run()
Definition: PSO.cpp:399
void WriteOutput()
Definition: PSO.cpp:444

◆ set_best_particle()

void PSO::set_best_particle ( particle n)
inline

Definition at line 87 of file PSO.h.

87  {
88  best_particle = n;
89  }

◆ swarmIterate()

double PSO::swarmIterate ( )

Definition at line 339 of file PSO.cpp.

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

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

◆ uncertainty_check()

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

Definition at line 301 of file PSO.cpp.

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

◆ vector_add()

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

Definition at line 113 of file PSO.h.

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

◆ vector_multiply()

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

Definition at line 105 of file PSO.h.

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

◆ vector_subtract()

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

Definition at line 118 of file PSO.h.

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

◆ WriteOutput()

void PSO::WriteOutput ( )

Definition at line 444 of file PSO.cpp.

444  {
445 // *************************
446  outputFile->cd();
447 
448  TVectorD* PSOParValue = new TVectorD(fDim);
449  TVectorD* PSOParError = new TVectorD(fDim);
450 
451  for(int i = 0; i < fDim; ++i)
452  {
453  (*PSOParValue)(i) = 0;
454  (*PSOParError)(i) = 0;
455  }
456 
457  std::vector<double> minimum = get_best_particle()->get_personal_best_position();
458 
459  int ParCounter = 0;
460 
461  if(fTestLikelihood){
462  for(int i = 0; i < fDim; ++i){
463  (*PSOParValue)(i) = minimum[i];
464  (*PSOParError)(i) = (uncertainties[i][0]+uncertainties[i][1])/2.0;
465  }
466  }
467  else{
468  for (std::vector<ParameterHandlerBase*>::iterator it = systematics.begin(); it != systematics.end(); ++it)
469  {
470  if(!(*it)->IsPCA())
471  {
472  for(int i = 0; i < (*it)->GetNumParams(); ++i, ++ParCounter)
473  {
474  double ParVal = minimum[ParCounter];
475  //KS: Basically apply mirroring for parameters out of bounds
476  (*PSOParValue)(ParCounter) = ParVal;
477  (*PSOParError)(ParCounter) = (uncertainties[ParCounter][0]+uncertainties[ParCounter][1])/2.0;
478  //KS: For fixed params HESS will not calcuate error so we need to pass prior error
479  if((*it)->IsParameterFixed(i))
480  {
481  (*PSOParError)(ParCounter) = (*it)->GetDiagonalError(i);
482  }
483  }
484  }
485  else
486  {
487  //KS: We need to convert parameters from PCA to normal base
488  TVectorD ParVals((*it)->GetNumParams());
489  TVectorD ParVals_PCA((*it)->GetNParameters());
490 
491  TVectorD ErrorVals((*it)->GetNumParams());
492  TVectorD ErrorVals_PCA((*it)->GetNParameters());
493 
494  //First save them
495  //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.
496  const int StartVal = ParCounter;
497  for(int i = 0; i < (*it)->GetNParameters(); ++i, ++ParCounter)
498  {
499  ParVals_PCA(i) = minimum[ParCounter];
500  ErrorVals_PCA(i) = (uncertainties[ParCounter][0]+uncertainties[ParCounter][1])/2.0;
501  }
502  ParVals = ((*it)->GetPCAHandler()->GetTransferMatrix())*ParVals_PCA;
503  ErrorVals = ((*it)->GetPCAHandler()->GetTransferMatrix())*ErrorVals_PCA;
504 
505  ParCounter = StartVal;
506  //KS: Now after going from PCA to normal let';s save it
507  for(int i = 0; i < (*it)->GetNumParams(); ++i, ++ParCounter)
508  {
509  (*PSOParValue)(ParCounter) = ParVals(i);
510  (*PSOParError)(ParCounter) = std::fabs(ErrorVals(i));
511  //int ParCounterMatrix = StartVal;
512  //If fixed take prior
513  if((*it)->GetPCAHandler()->IsParameterFixedPCA(i))
514  {
515  (*PSOParError)(ParCounter) = (*it)->GetDiagonalError(i);
516  }
517  }
518  }
519  }
520  }
521 
522  PSOParValue->Write("PSOParValue");
523  PSOParError->Write("PSOParError");
524  delete PSOParValue;
525  delete PSOParError;
526  // Save all the output
527  SaveOutput();
528 }
void SaveOutput()
Save output and close files.
Definition: FitterBase.cpp:230
TFile * outputFile
Output.
Definition: FitterBase.h:149

Member Data Documentation

◆ best_particle

particle* PSO::best_particle
private

Definition at line 145 of file PSO.h.

◆ fBestValue

double PSO::fBestValue
private

Definition at line 146 of file PSO.h.

◆ fConstriction

double PSO::fConstriction
private

Definition at line 157 of file PSO.h.

◆ fConvergence

double PSO::fConvergence
private

Definition at line 155 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 152 of file PSO.h.

◆ fIterations

int PSO::fIterations
private

Definition at line 156 of file PSO.h.

◆ fixed

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

Definition at line 148 of file PSO.h.

◆ fOne

double PSO::fOne
private

Definition at line 153 of file PSO.h.

◆ fParticles

int PSO::fParticles
private

Definition at line 160 of file PSO.h.

◆ fTwo

double PSO::fTwo
private

Definition at line 154 of file PSO.h.

◆ kMaxParticles

constexpr static const int PSO::kMaxParticles = 10000
staticconstexprprivate

Definition at line 162 of file PSO.h.

◆ par

double* PSO::par
private

Definition at line 164 of file PSO.h.

◆ paramlist

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

Definition at line 161 of file PSO.h.

◆ prior

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

Definition at line 147 of file PSO.h.

◆ ranges_max

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

Definition at line 149 of file PSO.h.

◆ ranges_min

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

Definition at line 150 of file PSO.h.

◆ system

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

Definition at line 151 of file PSO.h.

◆ uncertainties

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

Definition at line 158 of file PSO.h.

◆ vel

double PSO::vel[kMaxParticles]
private

Definition at line 163 of file PSO.h.


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