NC::Fitter::MinFinderSimple Class Reference

#include <NCFitter.h>

List of all members.

Public Member Functions

 MinFinderSimple (const std::vector< NCParameter > &ps, const bool limits, const bool reuse, const ICallableND *f)
double FindMin (CoordNDim &ret, bool progress=false, bool ignorePartitions=false) const

Static Public Member Functions

static void SetSpacePartitions (std::vector< std::string > names, std::vector< double > poss)
 Educate MinFinderSimple about degeneracies in your function.

Protected Member Functions

CoordNDim BeginSearchPos () const
int BeginScale () const
double FindMinPartitions (CoordNDim &ret, bool progress) const
 Helper function for FindMin.

Protected Attributes

std::vector< NCParameterfParams
bool fRespectParameterLimits
bool reuseOld
CoordNDim fPrevBest
const ICallableNDfFunc

Static Protected Attributes

static std::vector< std::string > sfPartNames
static std::vector< double > sfPartPositions

Detailed Description

Definition at line 134 of file NCFitter.h.


Constructor & Destructor Documentation

NC::Fitter::MinFinderSimple::MinFinderSimple ( const std::vector< NCParameter > &  ps,
const bool  limits,
const bool  reuse,
const ICallableND f 
)

Definition at line 222 of file NCFitter.cxx.

Referenced by FindMinPartitions().

00226     :fParams(ps),
00227      fRespectParameterLimits(limits),
00228      reuseOld(reuse),
00229      fFunc(f)
00230   {
00231   }


Member Function Documentation

int NC::Fitter::MinFinderSimple::BeginScale (  )  const [protected]

Definition at line 250 of file NCFitter.cxx.

References fParams, fPrevBest, n, and reuseOld.

Referenced by FindMin().

00251   {
00252     int initScale = 1;
00253     if(!reuseOld || fPrevBest.empty()){
00254       bool bigEnough = false;
00255       while(!bigEnough){
00256         initScale *= 2;
00257         bigEnough = true;
00258         for(unsigned int n = 0; n < fParams.size(); ++n){
00259           if(initScale*fParams[n].Precision() <
00260              (fParams[n].Max()-fParams[n].Min())/4)
00261             bigEnough = false;
00262         }
00263       }
00264     }
00265     return initScale;
00266   }

CoordNDim NC::Fitter::MinFinderSimple::BeginSearchPos (  )  const [protected]

Definition at line 234 of file NCFitter.cxx.

References fParams, fPrevBest, n, and reuseOld.

Referenced by FindMin().

00235   {
00236     assert(fPrevBest.size() == fParams.size() || fPrevBest.size() == 0);
00237 
00238     if(!reuseOld || fPrevBest.empty()){
00239       CoordNDim ret;
00240       for(unsigned int n = 0; n < fParams.size(); ++n){
00241         ret.push_back((fParams[n].Min()+fParams[n].Max())/2);
00242       }
00243       return ret;
00244     }
00245 
00246     return fPrevBest;
00247   }

double NC::Fitter::MinFinderSimple::FindMin ( CoordNDim ret,
bool  progress = false,
bool  ignorePartitions = false 
) const

Definition at line 348 of file NCFitter.cxx.

References BeginScale(), BeginSearchPos(), NC::Fitter::ICallableND::EvalAtEx(), fFunc, FindMinPartitions(), fParams, fPrevBest, Msg::kVerbose, MSG, NC::Utility::ReportProgress(), and sfPartNames.

Referenced by NC::Fitter::MarginalizeSimple::EvalAtEx(), NC::FitMaster::MargWithFixedVals(), and NC::FitMaster::Run().

00351   {
00352     if(!sfPartNames.empty() && !ignorePartitions)
00353       return FindMinPartitions(ret, progress);
00354 
00355     ret.resize(fParams.size());
00356 
00357     CoordNDim curPos = BeginSearchPos();
00358     assert(curPos.size() == fParams.size());
00359 
00360     CoordNDim junk;
00361     double curHeight = fFunc->EvalAtEx(curPos, &junk);
00362     /*
00363     if(curHeight > 9e5 && !fPrevBest.empty()){   // Appear to have started inside some kind of penalty zone
00364       fPrevBest.clear();    // So, forget where we were before
00365       // and try again.
00366       curPos = BeginSearchPos();
00367       curHeight = func->EvalAt(curPos);
00368     }
00369     */
00370 
00371     std::vector<int> curIntPos(curPos.size(), 0);
00372 
00373     int initScale = BeginScale();
00374 
00375     std::map<std::vector<int>, bool> alreadyBeen;
00376     unsigned int lastDir = 0;
00377 
00378     CoordNDim curEx;
00379 
00380     TStopwatch sw;
00381 
00382     for(int scale = initScale; scale >= 1; scale /= 2){
00383       if(progress) ReportProgress(1-log((float)scale)/log((float)initScale), sw);
00384     scaleTop:
00385       MSG("NCFitter", Msg::kVerbose) << "MinSimple: at "
00386                                      << curPos << endl;
00387       // Try the previous direction first
00388       for(int tryLast = true; tryLast >= false; --tryLast){
00389         // What direction to look in
00390         for(unsigned int dir = 0; dir < curPos.size(); ++dir){
00391           // In what sense
00392           for(int sign = -1; sign <= +1; sign += 2){
00393             if(tryLast && dir != lastDir) continue;
00394 
00395             CoordNDim newPos = curPos;
00396             newPos[dir] += sign*fParams[dir].Precision()*scale;
00397 
00398             //      if(fRespectParameterLimits && (newPos[dir] < fParams[dir].Min() || newPos[dir] > fParams[dir].Max()))
00399             //continue;
00400 
00401             std::vector<int> newIntPos = curIntPos;
00402             newIntPos[dir] += sign*scale;
00403 
00404             if(alreadyBeen[newIntPos]) continue;
00405 
00406             alreadyBeen[newIntPos] = true;
00407 
00408             CoordNDim ex;
00409 
00410             double heightHere = fFunc->EvalAtEx(newPos, &ex);
00411 
00412             if(heightHere < curHeight){
00413               curHeight = heightHere;
00414               curPos = newPos;
00415               curIntPos = newIntPos;
00416               curEx = ex;
00417               lastDir = dir;
00418 
00419               //              cout << "Moved to ";
00420               //              for (unsigned int n = 0; n < fParams.size(); ++n)
00421               //                cout << fParams[n].ShortName() << "=" << curPos[n] << " ";
00422               //              cout << endl;
00423 
00424               goto scaleTop; // Repeat all these loops with the same value of scale.
00425             } // end if better
00426           } // end for s
00427         } //end for d
00428       } // end for tryLast
00429     } // end for scale
00430 
00431     //    if(curHeight < 9e5)
00432     fPrevBest = curPos;
00433 
00434     if(curEx.empty()) ret = curPos; else ret = curEx;
00435 
00436     return curHeight;
00437   }

double NC::Fitter::MinFinderSimple::FindMinPartitions ( CoordNDim ret,
bool  progress 
) const [protected]

Helper function for FindMin.

Definition at line 277 of file NCFitter.cxx.

References fFunc, fParams, fRespectParameterLimits, Munits::m, Munits::m2, MinFinderSimple(), n, reuseOld, sfPartNames, and sfPartPositions.

Referenced by FindMin().

00279   {
00280     assert(sfPartNames.size() == sfPartPositions.size());
00281     assert(!sfPartNames.empty());
00282 
00283     // Start with `this` as a template to copy the minimizers from
00284     vector<const MinFinderSimple*> minimizers;
00285     minimizers.push_back(this);
00286 
00287     for(unsigned int n = 0; n < sfPartNames.size(); ++n){
00288       for(unsigned int i = 0; i < fParams.size(); ++i){
00289         // If we find we're fitting a parameter we ought to be partitioning
00290         if(fParams[i].ShortName() == sfPartNames[n]){
00291           // Take every minimizer that already exists and split it into
00292           // two, one for each side of the partition
00293           const unsigned int M = minimizers.size();
00294           for(unsigned int m = 0; m < M; ++m){
00295             // The parameter ranges inform the fitter where to begin
00296             vector<NCParameter> ps1 = fParams;
00297             ps1[i].SetRange(fParams[i].Min(), sfPartPositions[n]);
00298             vector<NCParameter> ps2 = fParams;
00299             ps2[i].SetRange(sfPartPositions[n], fParams[i].Max());
00300 
00301             // Constrain the ranges in [-infinity, partition point]
00302             // and [partition point, +infinity]
00303             ICallableND* f1 = new ConstrainRange(minimizers[m]->fFunc, i,
00304                                                  -1e50, sfPartPositions[n]);
00305             ICallableND* f2 = new ConstrainRange(minimizers[m]->fFunc, i,
00306                                                  sfPartPositions[n], +1e50);
00307 
00308             MinFinderSimple* m1 = new MinFinderSimple(ps1,
00309                                                       fRespectParameterLimits,
00310                                                       reuseOld,
00311                                                       f1);
00312             MinFinderSimple* m2 = new MinFinderSimple(ps2,
00313                                                       fRespectParameterLimits,
00314                                                       reuseOld,
00315                                                       f2);
00316             minimizers.push_back(m1);
00317             minimizers.push_back(m2);
00318           } // end for m
00319           // The first M of the minimizers are the ones before we split them
00320           // in half. We don't need them anymore.
00321           for(unsigned int m = 0; m < M; ++m){
00322             if(minimizers[m] != this) delete minimizers[m];
00323             minimizers.erase(minimizers.begin());
00324           } // end for m
00325         } // end if matches
00326       } // end for i
00327     } // end for n
00328 
00329     // Minimize using all the minimizers and pick the best result. Ensure
00330     // that ret is filled properly too. We pass true for ignorePartitions
00331     // otherwise we'd end up here again instead of actually minimizing.
00332     double lowest = 1e50;
00333     for(unsigned int m = 0; m < minimizers.size(); ++m){
00334       CoordNDim thisRet;
00335       const double height = minimizers[m]->FindMin(thisRet, progress, true);
00336       if(height < lowest){
00337         lowest = height;
00338         ret = thisRet;
00339       }
00340       // Don't need it anymore
00341       if(minimizers[m] != this) delete minimizers[m];
00342     }
00343 
00344     return lowest;
00345   }

static void NC::Fitter::MinFinderSimple::SetSpacePartitions ( std::vector< std::string >  names,
std::vector< double >  poss 
) [static]

Educate MinFinderSimple about degeneracies in your function.

If you are aware of multiple local minima in a parameter, on different sides of some symmetry point, you can instruct MinFinderSimple to perform seperate searches on each side of this partition, and then pick the lowest minimum.

Parameters:
names List of NCParameter::ShortName
poss For each of names the position at which the space should be partitioned

Referenced by NC::FitMaster::FitMaster().


Member Data Documentation

Definition at line 168 of file NCFitter.h.

Referenced by FindMin(), and FindMinPartitions().

Definition at line 164 of file NCFitter.h.

Referenced by BeginScale(), BeginSearchPos(), FindMin(), and FindMinPartitions().

Definition at line 167 of file NCFitter.h.

Referenced by BeginScale(), BeginSearchPos(), and FindMin().

Definition at line 165 of file NCFitter.h.

Referenced by FindMinPartitions().

Definition at line 166 of file NCFitter.h.

Referenced by BeginScale(), BeginSearchPos(), and FindMinPartitions().

vector< string > NC::Fitter::MinFinderSimple::sfPartNames [static, protected]

Definition at line 170 of file NCFitter.h.

Referenced by FindMin(), and FindMinPartitions().

Definition at line 171 of file NCFitter.h.

Referenced by FindMinPartitions().


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

Generated on 16 Jan 2018 for loon by  doxygen 1.6.1