Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

NCContourFinder Namespace Reference


Classes

class  NCContourFinder::Coord
class  NCContourFinder::ICallableND
class  NCContourFinder::ICallable2D
class  NCContourFinder::FindMinSimple
class  NCContourFinder::FixVars
class  NCContourFinder::MarginalizeSimple
class  NCContourFinder::MinuitForCallable
class  NCContourFinder::MarginalizeHybrid

Typedefs

typedef std::vector< double > CoordNDim

Functions

void ReportProgress (double est_frac, TStopwatch &sw)
double FindMinMinuit (const ICallableND *chiSqrFunc, const std::vector< NCParameter > params, CoordNDim &ret, TMinuit **ppMinu)
std::vector< CoordFindContour (const ICallable2D *func, const Coord &minCoord, const double &height, const Coord &precision, std::vector< TGraph > &marg_graphs)
TMatrix FindCovarianceMatrix (const ICallableND *func, const CoordNDim &minCoord, const std::vector< NCParameter > params)
TH2D * GetLowResGrid (const ICallable2D *func, const Coord min, const Coord max, const Coord prec)
TGraph * CreateOneDimProjection (const ICallable2D *func, const NCParameter param, const double minVal, double &leftErr, double &rightErr, std::vector< TGraph > &marg_graphs)
void PrintGridSearch (const ICallableND *func, const std::vector< NCParameter > &params, std::ostream &out)


Typedef Documentation

typedef std::vector<double> NCContourFinder::CoordNDim
 

Definition at line 26 of file NCContourFinder.h.

Referenced by NCContourFinder::MarginalizeHybrid::AlreadyAtMinimum(), NCContourFinder::FindMinSimple::BeginSearchPos(), CreateOneDimProjection(), NCContourFinder::MinuitForCallable::Eval(), NCExtrapolation::FillResultHistograms(), FindContour(), FindCovarianceMatrix(), NCExtrapolation::GetBestFitPoint(), NCExtrapolationJK_fit::GetChiSqrForMap(), GetLowResGrid(), NCContourFinder::MarginalizeSimple::MarginalizeSimple(), NCExtrapolation::GetChiSqrFromDerived::operator()(), NCContourFinder::MarginalizeSimple::operator()(), NCContourFinder::FindMinSimple::operator()(), NCExtrapolationJK_fit::PredictSpectrum(), and PrintGridSearch().


Function Documentation

TGraph * NCContourFinder::CreateOneDimProjection const ICallable2D *  func,
const NCParameter  param,
const double  minVal,
double &  leftErr,
double &  rightErr,
std::vector< TGraph > &  marg_graphs
 

Definition at line 436 of file NCContourFinder.cxx.

References CoordNDim, NCParameter::max, NCParameter::min, MSG, NCParameter::prec, ReportProgress(), and NCParameter::shortName.

Referenced by NCExtrapolation::Get1DProjection().

00442   {
00443     // +.5 makes us round to nearest int instead of toward zero.
00444     assert(param.prec);
00445     const int steps = int(.5+(param.max-param.min)/param.prec);
00446     assert(steps);
00447 
00448     vector<double> x, y;
00449 
00450     TStopwatch sw; // starts automatically
00451 
00452     double minproj = 1e10;
00453 
00454     for(int nx = 0; nx <= steps; ++nx){
00455       const double xhere = param.min+nx*param.prec;
00456 
00457       ReportProgress(double(nx)/steps, sw);
00458 
00459       CoordNDim bestfit;
00460       double upVal = (*func)(Coord(xhere, -999), bestfit);
00461       x.push_back(xhere);
00462       y.push_back(upVal);
00463 
00464       std::stringstream op;
00465       op << "CreateOneDimProjection: " << param.shortName << " = " << xhere << " chisq = " << upVal << " other variables: ";
00466       for(uint n = 0; n < bestfit.size(); ++n)
00467         op << " " << bestfit[n];
00468       op << endl;
00469       MSG("NCContourFinder", Msg::kVerbose) << op.str();
00470 
00471 
00472       if(upVal < minproj) minproj = upVal;
00473 
00474       for(uint n = 0; n < bestfit.size(); ++n){
00475         // If it's our first time through we need to create the graphs too.
00476         if(nx == 0) marg_graphs.push_back(TGraph());
00477         marg_graphs[n].Set(marg_graphs[n].GetN()+1);
00478         marg_graphs[n].SetPoint(marg_graphs[n].GetN()-1, xhere, bestfit[n]);
00479       }
00480     }
00481 
00482     MSG("NCContourFinder", Msg::kInfo) << "CreateOneDimProjection: min chisq = " << minproj
00483                                        << " cf minimizer's " << minVal << endl;
00484 
00485 
00486     bool needLeftErr = true;
00487     bool needRightErr = true;
00488 
00489     // Initialize right error for downward sloping projections.
00490     // .5 is to be consistent with binning elsewhere.
00491     rightErr = param.max+.5*param.prec;
00492 
00493     for(int nx = 0; nx <= steps; ++nx){
00494       y[nx] -= minproj;
00495 
00496       const double upVal = y[nx];
00497 
00498       if(needRightErr && !needLeftErr && upVal > 1){
00499         needRightErr = false;
00500         rightErr = x[nx];
00501       }
00502       if(needLeftErr && upVal < 1){
00503         needLeftErr = false;
00504         leftErr = x[nx]-param.prec;
00505       }
00506     }
00507 
00508     TGraph* ret = new TGraph(steps+1, &x[0], &y[0]);
00509 
00510     return ret;
00511   }

std::vector< Coord > NCContourFinder::FindContour const ICallable2D *  func,
const Coord &  minCoord,
const double &  height,
const Coord &  precision,
std::vector< TGraph > &  marg_graphs
 

Definition at line 203 of file NCContourFinder.cxx.

References atan2(), CoordNDim, MSG, ReportProgress(), NCContourFinder::Coord::x, and NCContourFinder::Coord::y.

Referenced by NCExtrapolation::GetContour().

00208   {
00209     assert(marg_graphs.empty());
00210 
00211     const double dx = precision.x;
00212     const double dy = precision.y;
00213     assert(dx > 0); assert(dy > 0);
00214 
00215     typedef pair<int, int> Box;    // first == left, second == top
00216 
00217     std::map<Box, bool> results;   // Is this box already in the result set?
00218     std::vector<Box> todo;         // Boxes to investigate
00219     std::map<Box, double> heights; // Boxes whose topleft corner has already been evaluated, used as cache.
00220 
00221     // Top left corner of the box containing the best fit.
00222     const int bfxi = int(minCoord.x/dx);
00223     const int bfyi = int(minCoord.y/dy);
00224 
00225     MSG("NCContourFinder", Msg::kVerbose) << "Contour: walking left" << endl;
00226     // Walk to the left
00227     for(int x = bfxi; ; --x){
00228       // As soon as we exceed the contour
00229       MSG("NCContourFinder", Msg::kVerbose) << "Contour: at " << x << endl;
00230       CoordNDim bestfit;
00231       if((*func)(Coord(x*dx, bfyi*dy), bestfit) > height){
00232         // Create enough graphs to save our marginalisation progress
00233         //(2 extra to save the two variables actually in the contour)
00234         for(uint n = 0; n < 4*(2+bestfit.size()); ++n) marg_graphs.push_back(TGraph());
00235 
00236         // make it the first element in the todo list
00237         todo.push_back(Box(x, bfyi));
00238         // and stop going left.
00239         break;
00240       }
00241     }
00242 
00243     // NB - for some reason while writing this I decided that increasing y is downward.
00244 
00245     std::vector<Coord> contour;
00246 
00247     TStopwatch sw; // starts automatically
00248 
00249     int gxi = -1; // position on the x axis of the marg graphs.
00250 
00251     while(!todo.empty()){
00252       Box now = todo.back();
00253       todo.pop_back();
00254 
00255       ++gxi;
00256 
00257       // We end up evaluating the function multiple times at each point, so are
00258       // relying heavily on the cacheing done in GetChiSqrFromDerived()
00259 
00260       MSG("NCContourFinder", Msg::kVerbose) << "Contour: at " << now.first << "," << now.second << endl;
00261 
00262       // Set by the loop below.
00263       double topleft, topright, bottomleft, bottomright;
00264 
00265       // Evaluate the function at all the corners.
00266       for(int cx = 0; cx <= 1; ++cx){
00267         for(int cy = 0; cy <= 1; ++cy){
00268           Box corner(now.first+cx, now.second+cy);
00269           const std::map<Box, double>::const_iterator it = heights.find(corner);
00270           double heightHere;
00271           if(it == heights.end()){
00272             CoordNDim bestfit;
00273             heightHere = (*func)(Coord((now.first+cx)*dx, (now.second+cy)*dy), bestfit);
00274 
00275             const int dn = cx+2*cy;
00276 
00277             marg_graphs[dn].Set(marg_graphs[dn].GetN()+1);
00278             marg_graphs[dn].SetPoint(marg_graphs[dn].GetN()-1, gxi, (now.first+cx)*dx);
00279             marg_graphs[4+dn].Set(marg_graphs[4+dn].GetN()+1);
00280             marg_graphs[4+dn].SetPoint(marg_graphs[4+dn].GetN()-1, gxi, (now.second+cy)*dy);
00281             for(uint n = 0; n < bestfit.size(); ++n){
00282               marg_graphs[8+4*n+dn].Set(marg_graphs[8+4*n+dn].GetN()+1);
00283               marg_graphs[8+4*n+dn].SetPoint(marg_graphs[8+4*n+dn].GetN()-1, gxi, bestfit[n]);
00284             }
00285 
00286             heights[corner] = heightHere;
00287           }
00288           else{
00289             heightHere = heights[corner];
00290           }
00291           if(cx == 0 && cy == 0) topleft = heightHere;
00292           if(cx == 1 && cy == 0) topright = heightHere;
00293           if(cx == 0 && cy == 1) bottomleft = heightHere;
00294           if(cx == 1 && cy == 1) bottomright = heightHere;
00295         }
00296       }
00297 
00298       MSG("NCContourFinder", Msg::kVerbose) << "Contour: tl,tr,bl,br=" << topleft << " "
00299                                             << topright << " " << bottomleft << " "
00300                                             << bottomright << endl;
00301 
00302       if(now.first-bfxi){
00303         const double est_frac = (M_PI+atan2(now.second-bfyi-.01, now.first-bfxi))/(2*M_PI);
00304         ReportProgress(est_frac, sw);
00305       }
00306 
00307 
00308       // For each side of the box: see if one corner is high and the other low.
00309       // If so, and if the box adjacent on this side isn't already part of the
00310       // results, then append the adjacent box to the todo list and linearly
00311       // interpolate to find where to put the contour point on that edge.
00312 
00313       if( (topright-height)*(bottomright-height) <= 0){
00314         Box right(now.first+1, now.second);
00315         if(!results[right]){
00316           MSG("NCContourFinder", Msg::kVerbose) << "Contour: went right" << endl;
00317           todo.push_back(right);
00318           results[right] = true;
00319           const double rightdiff = (bottomright-topright) ? bottomright-topright : 1;
00320           contour.push_back(Coord((now.first+1)*dx, (now.second+(height-topright)/rightdiff)*dy));
00321         }
00322       }
00323       if( (topleft-height)*(bottomleft-height) <= 0){
00324         Box left(now.first-1, now.second);
00325         if(!results[left]){
00326           MSG("NCContourFinder", Msg::kVerbose) << "Contour: went left" << endl;
00327           todo.push_back(left);
00328           results[left] = true;
00329           const double leftdiff = (bottomleft-topleft) ? bottomleft-topleft : 1;
00330           contour.push_back(Coord(now.first*dx, (now.second+(height-topleft)/leftdiff)*dy));
00331         }
00332       }
00333       if( (bottomleft-height)*(bottomright-height) <= 0){
00334         Box down(now.first, now.second+1);
00335         if(!results[down]){
00336           MSG("NCContourFinder", Msg::kVerbose) << "Contour: went down" << endl;
00337           todo.push_back(down);
00338           results[down] = true;
00339           const double bottomdiff = (bottomright-bottomleft) ? bottomright-bottomleft : 1;
00340           contour.push_back(Coord((now.first+(height-bottomleft)/(bottomdiff))*dx, (now.second+1)*dy));
00341         }
00342       }
00343       if( (topleft-height)*(topright-height) <= 0 ){
00344         Box up(now.first, now.second-1);
00345         if(!results[up]){
00346           MSG("NCContourFinder", Msg::kVerbose) << "Contour: went up" << endl;
00347           todo.push_back(up);
00348           results[up] = true;
00349           const double topdiff = (topright-topleft) ? topright-topleft : 1;
00350           contour.push_back(Coord((now.first+(height-topleft)/topdiff)*dx, now.second*dy));
00351         }
00352       }
00353     }
00354 
00355     if(contour.size()) contour.push_back(contour[0]); // Close the loop.
00356     return contour;
00357   }

TMatrix NCContourFinder::FindCovarianceMatrix const ICallableND *  func,
const CoordNDim minCoord,
const std::vector< NCParameter params
 

Definition at line 361 of file NCContourFinder.cxx.

References CoordNDim.

Referenced by NCExtrapolation::MakeDeltaChiSqrMaps().

00364   {
00365     assert(params.size() == minCoord.size());
00366 
00367     TMatrix ret(params.size(), params.size());
00368 
00369     const double bestFitVal = (*func)(minCoord);
00370 
00371     // First, do the 2nd derivatives in one variable
00372     for(uint i = 0; i < params.size(); ++i){
00373       const double step = params[i].prec;
00374       CoordNDim plus = minCoord;
00375       plus[i] += step;
00376       CoordNDim minus = minCoord;
00377       minus[i] -= step;
00378       const double dii = ((*func)(plus)+(*func)(minus)-2*bestFitVal)/(step*step);
00379       ret(i, i) = dii;
00380     }
00381 
00382     // Now do all the off-diagonal derivatives
00383     for(uint i = 0; i < params.size()-1; ++i){
00384       for(uint j = i+1; j < params.size(); ++j){
00385         const double di = params[i].prec;
00386         const double dj = params[j].prec;
00387 
00388         CoordNDim pp = minCoord;
00389         pp[i] += di; pp[j] += dj;
00390         CoordNDim pi = minCoord;
00391         pi[i] += di;
00392         CoordNDim pj = minCoord;
00393         pj[j] += dj;
00394 
00395         const double dij = ((*func)(pp)+bestFitVal-(*func)(pi)-(*func)(pj))/(di*dj);
00396         ret(i, j) = dij;
00397         ret(j, i) = dij;
00398       }
00399     }
00400 
00401     ret.Invert();
00402     return ret;
00403   }

double NCContourFinder::FindMinMinuit const ICallableND *  chiSqrFunc,
const std::vector< NCParameter params,
CoordNDim ret,
TMinuit **  minu = 0
 

Definition at line 155 of file NCContourFinder.cxx.

References MSG.

Referenced by NCExtrapolation::MakeDeltaChiSqrMaps().

00159   {
00160     ret.resize(params.size());
00161 
00162     TMinuit* minu = new MinuitForCallable(chiSqrFunc, params.size());
00163     minu->SetPrintLevel(-1); // Shut Minuit up.
00164     minu->Command("set strategy 2"); // Be careful, instead of fast.
00165 
00166     for(int n = 0; n < int(params.size()); ++n)
00167       // NB - no parameter limits imposed.
00168       minu->DefineParameter(n, params[n].shortName.c_str(),
00169                             (params[n].min+params[n].max)/2, (params[n].max-params[n].min)/4,
00170                             0, 0);
00171 
00172     // Minuit tries to return a lot of parameters we don't want to keep.
00173     double junkd; int junki; TString junks;
00174 
00175     if(minu->Migrad()){
00176       MSG("NCContourFinder", Msg::kWarning) << "Migrad failed, falling back to Simplex.\n";
00177       minu->SetPrintLevel(0); // Things are going wrong, we should let the user see.
00178       minu->mnsimp();
00179       minu->Migrad();
00180     }
00181 
00182     double minChiSqr;
00183     minu->mnstat(minChiSqr, junkd, junkd, junki, junki, junki);
00184 
00185     for(unsigned int n = 0; n < params.size(); ++n)
00186       minu->GetParameter(n, ret[n], junkd);
00187 
00188     if(ppMinu)
00189       *ppMinu = minu;
00190     else
00191       delete minu;
00192 
00193     return minChiSqr;
00194   }

TH2D * NCContourFinder::GetLowResGrid const ICallable2D *  func,
const Coord  min,
const Coord  max,
const Coord  prec
 

Definition at line 407 of file NCContourFinder.cxx.

References CoordNDim, max, min, MSG, NCContourFinder::Coord::x, and NCContourFinder::Coord::y.

Referenced by NCExtrapolation::Get2DGrid().

00411   {
00412     const int Nx = int((max.x-min.x)/prec.x+.5);
00413     const int Ny = int((max.y-min.y)/prec.y+.5);
00414 
00415     TH2D* ret = new TH2D("foo", "bar", Nx, min.x, max.x, Ny, min.y, max.y);
00416 
00417     for(int nx = 0; nx < Nx ; ++nx){
00418       for(int ny = 0; ny < Ny; ++ny){
00419         const double x = min.x+(max.x-min.x)/double(Nx)*(nx+.5);
00420         const double y = min.y+(max.y-min.y)/double(Ny)*(ny+.5);
00421         CoordNDim bestfit;
00422         const double f = (*func)(Coord(x, y), bestfit);
00423         MSG("NCContourFinder", Msg::kVerbose) << "GetLowResGrid: "
00424                                               << nx << "," << ny
00425                                               << " (" << x << "," << y << ") "
00426                                               << "-> " << f << endl;
00427         ret->Fill(x, y, f);
00428       }
00429     }
00430 
00431     return ret;
00432   }

void NCContourFinder::PrintGridSearch const ICallableND *  func,
const std::vector< NCParameter > &  params,
std::ostream &  out
 

Definition at line 714 of file NCContourFinder.cxx.

References base, CoordNDim, and min.

Referenced by NCExtrapolation::MakeDeltaChiSqrMaps().

00717   {
00718     std::vector<NCParameter> lowResParams = params;
00719     for(unsigned int n = 0; n < lowResParams.size(); ++n)
00720       lowResParams[n].prec *= 10;
00721 
00722     std::vector<CoordNDim> evalAt;
00723 
00724     CoordNDim first;
00725     for(unsigned int n = 0; n < lowResParams.size(); ++n)
00726       first.push_back(lowResParams[n].min);
00727 
00728     evalAt.push_back(first);
00729 
00730     for(unsigned int d = 0; d < lowResParams.size(); ++d){
00731       unsigned int maxn = evalAt.size();
00732       for(unsigned int n = 0; n < maxn; ++n){
00733         for(unsigned int nx = 1; ; ++nx){
00734           CoordNDim base = evalAt[n];
00735           base[d] += lowResParams[d].prec*nx;
00736           if(base[d] > lowResParams[d].max) break;
00737           evalAt.push_back(base);
00738         }
00739       }
00740     }
00741 
00742     for(unsigned int d = 0; d < lowResParams.size(); ++d)
00743       out << lowResParams[d].shortName << "\t";
00744     out << "chisq" << endl;
00745 
00746     for(unsigned int n = 0; n < evalAt.size(); ++n){
00747       for(unsigned int d = 0; d < evalAt[n].size(); ++d){
00748         out << evalAt[n][d]<<"\t";
00749       }
00750       out << (*func)(evalAt[n])<<endl;
00751     }
00752   }

void ReportProgress double  est_frac,
TStopwatch &  sw
[static]
 

Private utility function. Prints estimated time remaining

Definition at line 26 of file NCContourFinder.cxx.

References MSG.

Referenced by CreateOneDimProjection(), and FindContour().

00027   {
00028     const double elapsed = sw.RealTime();
00029     sw.Start(kFALSE);
00030 
00031     const int remain = est_frac ? int(elapsed*(1/est_frac-1)) : 0;
00032 
00033     MSG("NCContourFinder", Msg::kInfo) << "Estimated " << int(100*est_frac) << "% complete - "
00034                                        << remain/3600 << "h" << (remain/60)%60 << "m" << remain%60 << "s remain.\n";
00035   }


Generated on Mon Jun 16 15:04:18 2008 for loon by  doxygen 1.3.9.1