#include <NCFitter.h>
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 | |
| 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< NCParameter > | fParams |
| bool | fRespectParameterLimits |
| bool | reuseOld |
| CoordNDim | fPrevBest |
| const ICallableND * | fFunc |
Static Protected Attributes | |
| std::vector< std::string > | sfPartNames |
| std::vector< double > | sfPartPositions |
|
||||||||||||||||||||
|
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 }
|
|
|
Definition at line 250 of file NCFitter.cxx. References fParams, fPrevBest, 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 }
|
|
|
Definition at line 234 of file NCFitter.cxx. References NC::Fitter::CoordNDim, fParams, fPrevBest, 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 }
|
|
||||||||||||||||
|
Definition at line 348 of file NCFitter.cxx. References BeginScale(), BeginSearchPos(), NC::Fitter::CoordNDim, NC::Fitter::ICallableND::EvalAtEx(), fFunc, FindMinPartitions(), fParams, fPrevBest, MSG, NC::Utility::ReportProgress(), and sfPartNames. Referenced by NC::Fitter::MarginalizeSimple::EvalAtEx(), 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 }
|
|
||||||||||||
|
Helper function for FindMin.
Definition at line 277 of file NCFitter.cxx. References NC::Fitter::CoordNDim, fFunc, fParams, fRespectParameterLimits, MinFinderSimple(), 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 }
|
|
||||||||||||
|
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.
Referenced by NC::FitMaster::FitMaster(). |
|
|
Definition at line 164 of file NCFitter.h. Referenced by FindMin(), and FindMinPartitions(). |
|
|
Definition at line 160 of file NCFitter.h. Referenced by BeginScale(), BeginSearchPos(), FindMin(), and FindMinPartitions(). |
|
|
Definition at line 163 of file NCFitter.h. Referenced by BeginScale(), BeginSearchPos(), and FindMin(). |
|
|
Definition at line 161 of file NCFitter.h. Referenced by FindMinPartitions(). |
|
|
Definition at line 162 of file NCFitter.h. Referenced by BeginScale(), BeginSearchPos(), and FindMinPartitions(). |
|
|
Definition at line 219 of file NCFitter.cxx. Referenced by FindMin(), and FindMinPartitions(). |
|
|
Definition at line 220 of file NCFitter.cxx. Referenced by FindMinPartitions(). |
1.3.9.1