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< Coord > | FindContour (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 > ¶ms, std::ostream &out) |
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
1.3.9.1