MaCh3  2.5.1
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:170
Manager * fitMan
The manager for configuration handling.
Definition: FitterBase.h:110
bool fTestLikelihood
Necessary for some fitting algorithms like PSO.
Definition: FitterBase.h:160
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 150 of file PSO.cpp.

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

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

◆ 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:528

◆ CalcChi2()

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

Chi2 calculation over all included samples and syst objects.

Reimplemented from LikelihoodFit.

Definition at line 528 of file PSO.cpp.

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

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

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

538  {
539 // *************************
540  stepClock->Start();
541 
542  //Search range: [-5.12, 5.12]
543  constexpr double A = 10.0;
544  double sum = 0.0;
545  for (int i = 0; i < fDim; ++i) {
546  sum += x[i] * x[i] - A * cos(2.0 * 3.14 * x[i]);
547  }
548  double llh = A * fDim + sum;
549 
550  accProb = 1;
551 
552  stepClock->Stop();
553  stepTime = stepClock->RealTime();
554 
555  return llh;
556 }
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 396 of file PSO.cpp.

396  {
397 // *************************
398  double mean_dist_sq = 0;
399 
400  int iter = 0;
401  for(int i = 0; i < fIterations; ++i, ++iter){
402  mean_dist_sq = swarmIterate();
403  //double meanVel = std::accumulate(vel, vel + fParticles, 0) / fParticles;
404 
405  // Weight inertia randomly but scaled by total distance of swarm from global minimum - proxy for total velocity
406  // fWeight = ((random->Rndm()+1.0)*0.5)*(10.0/meanVel);
407 
409 
410  outTree->Fill();
411  // Auto save the output
412  if (step % auto_save == 0) outTree->AutoSave();
413  step++;
414  accCount++;
415 
416  if (i%100 == 0){
417  MACH3LOG_INFO("Mean Dist Sq = {:.2f}", mean_dist_sq);
418  MACH3LOG_INFO("Current LLR = {:.2f}", fBestValue);
419  MACH3LOG_INFO("Position:");
420  for (int j = 0; j < fDim; ++j){
421  MACH3LOG_INFO(" Dim {} = {:<10.2f}", j, get_best_particle()->get_personal_best_position()[j]);
422  }
423  }
424  if(fConvergence > 0.0){
425  if(mean_dist_sq < fConvergence){
426  break;
427  }
428  }
429  }
430  MACH3LOG_INFO("Finished after {} runs out of {}", iter, fIterations);
431  MACH3LOG_INFO("Mean Dist: {:.2f}", mean_dist_sq);
432  MACH3LOG_INFO("Best LLR: {:.2f}", get_best_particle()->get_personal_best_value());
433  uncertainties = bisection(get_best_particle()->get_personal_best_position(),get_best_particle()->get_personal_best_value(),0.5,0.005);
434  MACH3LOG_INFO("Position for Global Minimum = ");
435  for (int i = 0; i< fDim; ++i){
436  MACH3LOG_INFO(" Dim {} = {:<10.2f} +{:.2f}, -{:.2f}", i, get_best_particle()->get_personal_best_position()[i], uncertainties[i][1], uncertainties[i][0]);
437  }
438 }
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:150
particle * get_best_particle()
Definition: PSO.h:86
std::vector< std::vector< double > > uncertainties
Definition: PSO.h:160
double swarmIterate()
Definition: PSO.cpp:336

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

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

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

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

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

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

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: