#include <NCFitter.h>
Public Member Functions | |
| MinFinderSimpleInt (const std::vector< NCParameter > &ps, const bool limits, const ICallableInt *f) | |
| double | FindMin (CoordInt *ret=0, std::vector< TGraph > *min_graphs=0) const |
Protected Member Functions | |
| CoordInt | BeginSearchPos () const |
| CoordInt | BeginScale () const |
| Find a good step size to begin the search. | |
Protected Attributes | |
| std::vector< NCParameter > | fParams |
| bool | fRespectParameterLimits |
| CoordInt | fPrevBest |
| const ICallableInt * | fFunc |
|
||||||||||||||||
|
Definition at line 175 of file NCFitter.h. 00178 :fParams(ps), fRespectParameterLimits(limits), fFunc(f){}
|
|
|
Find a good step size to begin the search. Find a power of 2 step size in each direction that is larger than one quarter of the number of steps between max and min in that direction so that the first step will get at least halfway to the edge. If we are remembering a fPrevBest than assume it is nearly perfect and return all 1's for the step sizes. Definition at line 468 of file NCFitter.cxx. References NC::Fitter::CoordInt, fParams, and fPrevBest. Referenced by FindMin(). 00469 {
00470 CoordInt ret(fParams.size());
00471 for(unsigned int n = 0; n < ret.size(); ++n) ret[n] = 1;
00472
00473 if(!fPrevBest.empty()) return ret;
00474
00475 for(unsigned int n = 0; n < fParams.size(); ++n){
00476 bool bigEnough = false;
00477 while(!bigEnough){
00478 ret[n] *= 2;
00479 bigEnough = ret[n] > .25*fParams[n].Steps();
00480 }
00481 }
00482
00483 return ret;
00484 }
|
|
|
Definition at line 441 of file NCFitter.cxx. References NC::Fitter::CoordInt, fParams, and fPrevBest. Referenced by FindMin(). 00442 {
00443 assert(fPrevBest.size() == fParams.size() || fPrevBest.empty());
00444
00445 if(fPrevBest.empty()){
00446 CoordInt ret;
00447 for(unsigned int n = 0; n < fParams.size(); ++n){
00448 // ret.push_back((fParams[n].Min()+fParams[n].Max())/2);
00449 // ret.push_back(fParams[n].Min()+.25*(fParams[n].Max()-fParams[n].Min()));
00450 ret.push_back(int((fParams[n].Max()-fParams[n].Min())/
00451 fParams[n].Precision())/2);
00452 }
00453 return ret;
00454 }
00455
00456 return fPrevBest;
00457 }
|
|
||||||||||||
|
The logic here is to get a good starting position and scale from BeginSearchPos and BeginScale. Then we try fowards and backwards in every direction in turn, looking for a lower function value. If we find one then repeat, trying that direction first. If we go the same way twice then double the step size in that direction. If no directions improve then halve the step size in all directions. If all step sizes were already minimal, then we have found the minimum and return. Definition at line 496 of file NCFitter.cxx. References BeginScale(), BeginSearchPos(), NC::Fitter::CoordInt, NC::Fitter::ICallableInt::EvalAt(), fFunc, fParams, fPrevBest, and MSG. Referenced by NC::Fitter::MarginalizeSimpleInt::EvalAtEx(). 00498 {
00499 // We need this because eg we move one way and
00500 // then immediately test where we just were.
00501 FuncCacheInt f(fFunc);
00502
00503 if(ret) ret->resize(fParams.size());
00504
00505 // One extra for chisq value
00506 if(min_graphs) min_graphs->resize(1+fParams.size());
00507
00508 CoordInt curPos = BeginSearchPos();
00509 double curHeight = f.EvalAt(curPos);
00510
00511 // Appear to have started inside some kind of penalty zone
00512 if(curHeight > 9e5 && !fPrevBest.empty()){
00513 fPrevBest.clear(); // So, forget where we were before
00514 // and try again.
00515 curPos = BeginSearchPos();
00516 curHeight = f.EvalAt(curPos);
00517 }
00518
00519 CoordInt scale = BeginScale();
00520
00521 // What way did we last move?
00522 unsigned int lastDir = 0;
00523 int lastSign = 0;
00524
00525 // How many times in a row we have moved in this direction, at this scale
00526 vector<int> numGoodMoves(fParams.size(), 0);
00527
00528 while(true){
00529 loopTop:
00530 MSG("NCFitter", Msg::kVerbose) << "MinSimpleInt: at "
00531 << curPos << endl;
00532
00533 // Try the previous direction first
00534 for(int tryLast = true; tryLast >= false; --tryLast){
00535 // What direction to look in
00536 for(unsigned int dir = 0; dir < curPos.size(); ++dir){
00537 // In what sense
00538 for(int sign = -1; sign <= +1; sign += 2){
00539 if(tryLast && (dir != lastDir || sign != lastSign)) continue;
00540
00541 CoordInt newPos = curPos;
00542 newPos[dir] += sign*scale[dir];
00543
00544 // TODO - wrong
00545 // if(fRespectParameterLimits && (newPos[dir] < fParams[dir].Min() || newPos[dir] > fParams[dir].Max()))
00546 // continue;
00547
00548 const double heightHere = f.EvalAt(newPos);
00549
00550 if(heightHere < curHeight){
00551 if(min_graphs){
00552 min_graphs->at(0).SetPoint(min_graphs->at(0).GetN(),
00553 min_graphs->at(0).GetN(),
00554 heightHere);
00555
00556 for(unsigned int n = 0; n < newPos.size(); ++n)
00557 min_graphs->at(n+1).SetPoint(min_graphs->at(n+1).GetN(),
00558 min_graphs->at(n+1).GetN(),
00559 newPos[n]);
00560 }
00561
00562 curHeight = heightHere;
00563 curPos = newPos;
00564 lastDir = dir;
00565 lastSign = sign;
00566
00567 ++numGoodMoves[dir];
00568 // As soon as we move twice in a direction,
00569 // then double the scale that way.
00570 // The tryLast stuff will make sure we try again
00571 // in this direction first.
00572 if(numGoodMoves[dir] == 2){
00573 numGoodMoves[dir] = 0;
00574 scale[dir] *= 2;
00575 }
00576 goto loopTop; // Try again from this new position
00577 } // end if better
00578 } // end for s
00579 } //end for d
00580 } // end for tryLast
00581
00582 // If we got here then no direction was an improvement.
00583 // If we are at the minimum scale then quit.
00584 bool quit = true;
00585 for(unsigned int n = 0; n < scale.size(); ++n) if(scale[n] != 1) quit = false;
00586 if(quit) break;
00587
00588 // Otherwise reduce the scale in every direction we can.
00589 for(unsigned int n = 0; n < scale.size(); ++n){
00590 if(scale[n] > 1){
00591 scale[n] /= 2;
00592 numGoodMoves[n] = 0;
00593 }
00594 }
00595
00596 } // end infinite loop
00597
00598 if(curHeight < 9e5) fPrevBest = curPos;
00599 if(ret) *ret = curPos;
00600
00601 return curHeight;
00602 }
|
|
|
Definition at line 187 of file NCFitter.h. Referenced by FindMin(). |
|
|
Definition at line 184 of file NCFitter.h. Referenced by BeginScale(), BeginSearchPos(), and FindMin(). |
|
|
Definition at line 186 of file NCFitter.h. Referenced by BeginScale(), BeginSearchPos(), and FindMin(). |
|
|
Definition at line 185 of file NCFitter.h. |
1.3.9.1