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

NC::Fitter Namespace Reference


Classes

class  NC::Fitter::ConstrainRange
 This class supports the function flipping in MinFinderSimple. More...
class  NC::Fitter::Discretizer
class  NC::Fitter::Penalizer
class  NC::Fitter::PenalizerInt
class  NC::Fitter::FuncCache
class  NC::Fitter::FuncCacheInt
class  NC::Fitter::MinFinderSimple
class  NC::Fitter::MinFinderSimpleInt
class  NC::Fitter::FixVars
 Effectively reduce the number of arguments taken by fun. More...
class  NC::Fitter::FixVarsInt
 Effectively reduce the number of arguments taken by fun. More...
class  NC::Fitter::MarginalizeSimple
 Minimize callable f with respect to all its arguments except xcoord and (optionally) ycoord. More...
class  NC::Fitter::MarginalizeSimpleInt
 Minimize callable f with respect to all its arguments except xcoord and (optionally) ycoord. More...
class  NC::Fitter::MinuitForCallable
class  NC::Fitter::MarginalizeHybrid
class  NC::Fitter::CoordBase< T >
 Base class for coordinate types. More...
struct  NC::Fitter::Coord
 A simple two-dimensional coordinate. More...
class  NC::Fitter::ICallableND
 Interface to a general function in many dimensions. More...
class  NC::Fitter::ICallableInt
 Interface to a function on integers in many dimensions. More...
class  NC::Fitter::ICallable2D
 Interface to a function on two-dimensional coordinates. More...

Typedefs

typedef CoordBase< double > CoordNDim
 An N-dimensional coordinate CoordBase.
typedef CoordBase< int > CoordInt
 An N-dimensional coordinate in integer space CoordBase.

Functions

CoordNDim ConvertCoord (const CoordInt &c, std::vector< NCParameter > ps)
CoordNDim ConvertContourCoord (const CoordNDim &c, vector< NCParameter > ps)
 This final one is intended to be used on the output of FindContourInt.
ostream & operator<< (ostream &os, const FuncCache &c)
ostream & operator<< (ostream &os, const FuncCacheInt &c)
double MinFinderMinuit (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)
 Find contour of height height in the function func.
TMatrix FindCovarianceMatrix (const ICallableND *func, const CoordNDim &minCoord, const std::vector< NCParameter > params)
bool Interpolate (double val1, double val2, double target, double &ret)
std::vector< CoordNDimFindContourInt (const ICallableInt *func_org, const CoordInt &minCoord, const double height, std::vector< TGraph > *marg_graphs)
 Find contour of height height in the function func.
TH2D * GetLowResGrid (const ICallable2D *func, const Coord min, const Coord max, const Coord prec)
TH2D * GridSearchInt (const ICallableInt *func, const CoordInt min, const CoordInt max)
TH2D * ConvertGrid (const TH2D *intgrid, const NCParameter &xp, const NCParameter &yp)
TGraph * CreateOneDimProjection (const ICallable2D *func, const NCParameter param, const double minVal, double &leftErr, double &rightErr, std::vector< TGraph > &marg_graphs)
TGraph CreateOneDimProjectionInt (const ICallableInt *func, int minstep, int maxstep, double &leftErr, double &rightErr)
vector< TGraph > MakeSlices (const ICallableND *func, const vector< NCParameter > &ps, const CoordNDim &minpos)
vector< TH2D * > Make2DSlices (const ICallableND *func, const vector< NCParameter > &ps, const CoordNDim &minpos)
void PrintGridSearch (const ICallableND *func, const std::vector< NCParameter > &params, std::ostream &out)
ostream & operator<< (ostream &os, const CoordNDim &c)
ostream & operator<< (ostream &os, const CoordInt &c)


Typedef Documentation

typedef CoordBase<int> NC::Fitter::CoordInt
 

An N-dimensional coordinate in integer space CoordBase.

Definition at line 53 of file NCFitterTypes.h.

Referenced by NC::Fitter::MinFinderSimpleInt::BeginScale(), NC::Fitter::MinFinderSimpleInt::BeginSearchPos(), ConvertCoord(), CreateOneDimProjectionInt(), NC::Fitter::ICallableInt::EvalAt(), NC::Fitter::FixVarsInt::EvalAt(), NC::Fitter::PenalizerInt::EvalAt(), NC::Fitter::Discretizer::EvalAt(), NC::Fitter::ICallableInt::EvalAtEx(), NC::Fitter::MarginalizeSimpleInt::EvalAtEx(), NC::Fitter::FuncCacheInt::EvalAtEx(), FindContourInt(), NC::Fitter::MinFinderSimpleInt::FindMin(), NC::Fitter::FixVarsInt::FixVarsInt(), GridSearchInt(), NC::Fitter::MarginalizeSimpleInt::MarginalizeSimpleInt(), operator<<(), and NC::Fitter::FixVarsInt::SetFixed().

typedef CoordBase<double> NC::Fitter::CoordNDim
 

An N-dimensional coordinate CoordBase.

Definition at line 51 of file NCFitterTypes.h.

Referenced by NC::Fitter::MarginalizeHybrid::AlreadyAtMinimum(), NC::Fitter::MinFinderSimple::BeginSearchPos(), NC::CoordinateConverter::ChooseValue(), ConvertContourCoord(), ConvertCoord(), NC::CoordinateConverter::CoordNDimFromOscPars(), CreateOneDimProjection(), NC::Fitter::MinuitForCallable::Eval(), NC::Fitter::MarginalizeHybrid::EvalAtEx(), NC::Fitter::MarginalizeSimple::EvalAtEx(), NC::Fitter::ConstrainRange::EvalAtEx(), NC::Fitter::FixVars::EvalAtEx(), NC::Fitter::FuncCache::EvalAtEx(), NC::Fitter::Penalizer::EvalAtEx(), NC::GetChiSqrFromDerived::EvalAtEx(), FindContour(), FindContourInt(), FindCovarianceMatrix(), NC::Fitter::MinFinderSimple::FindMin(), NC::Fitter::MinFinderSimple::FindMinPartitions(), NC::Fitter::FixVars::FixVars(), NCExtrapolation::GetBestFitCoordNDim(), GetLowResGrid(), Make2DSlices(), MakeSlices(), NC::Fitter::MarginalizeSimple::MarginalizeSimple(), MinFinderMinuit(), operator<<(), PrintGridSearch(), NC::FitMaster::SetBestFitCoordNDim(), NCExtrapolation::SetBestFitCoordNDim(), and NC::Fitter::FixVars::SetFixed().


Function Documentation

CoordNDim ConvertContourCoord const CoordNDim c,
vector< NCParameter ps
 

This final one is intended to be used on the output of FindContourInt.

Definition at line 63 of file NCFitter.cxx.

References CoordNDim.

00064   {
00065     assert(c.size() == ps.size());
00066 
00067     CoordNDim ret(c.size());
00068     for(unsigned int n = 0; n < c.size(); ++n)
00069       ret[n] = ps[n].ValFromStep(c[n]);
00070 
00071     return ret;
00072   }

CoordNDim NC::Fitter::ConvertCoord const CoordInt c,
std::vector< NCParameter ps
 

Definition at line 51 of file NCFitter.cxx.

References CoordInt, and CoordNDim.

Referenced by NC::Fitter::Discretizer::EvalAt().

00052   {
00053     assert(c.size() == ps.size());
00054 
00055     CoordNDim ret(c.size());
00056     for(unsigned int n = 0; n < c.size(); ++n)
00057       ret[n] = ps[n].ValFromStep(c[n]);
00058 
00059     return ret;
00060   }

TH2D * NC::Fitter::ConvertGrid const TH2D *  intgrid,
const NCParameter xp,
const NCParameter yp
 

Definition at line 1063 of file NCFitter.cxx.

References NCParameter::LatexName(), and NCParameter::ValFromStep().

01066   {
01067     const int nx = intgrid->GetNbinsX();
01068     const int ny = intgrid->GetNbinsY();
01069 
01070     double* xb = new double[nx+1];
01071     double* yb = new double[ny+1];
01072 
01073     for(int x = 0; x <= nx; ++x) xb[x] = xp.ValFromStep(x);
01074     for(int y = 0; y <= ny; ++y) yb[y] = yp.ValFromStep(y);
01075 
01076     TH2D* ret = new TH2D("", TString::Format(";%s;%s;",
01077                                              xp.LatexName().c_str(),
01078                                              yp.LatexName().c_str()).Data(),
01079                          nx, xb, ny, yb);
01080 
01081     delete[] xb;
01082     delete[] yb;
01083 
01084     for(int x = 0; x <= nx; ++x)
01085       for(int y = 0; y <= ny; ++y)
01086         ret->SetBinContent(x, y, intgrid->GetBinContent(x, y));
01087 
01088     return ret;
01089   }

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

Definition at line 1093 of file NCFitter.cxx.

References CoordNDim, NC::Fitter::ICallable2D::EvalAtEx(), NCParameter::Max(), NCParameter::Min(), MSG, NCParameter::Precision(), NC::Utility::ReportProgress(), and NCParameter::ShortName().

01099   {
01100     // +.5 makes us round to nearest int instead of toward zero.
01101     assert(param.Precision());
01102     const int steps = int(.5+(param.Max()-param.Min())/param.Precision());
01103     assert(steps);
01104 
01105     vector<double> x, y;
01106 
01107     TStopwatch sw; // starts automatically
01108 
01109     double minproj = 1e10;
01110 
01111     for(int nx = 0; nx <= steps; ++nx){
01112       const double xhere = param.Min()+nx*param.Precision();
01113 
01114       ReportProgress(double(nx)/steps, sw);
01115 
01116       CoordNDim bestfit;
01117       double upVal = func->EvalAtEx(Coord(xhere, -999), bestfit);
01118       x.push_back(xhere);
01119       y.push_back(upVal);
01120 
01121       std::stringstream op;
01122       op << "CreateOneDimProjection: "
01123          << param.ShortName() << " = " << xhere << " chisq = " << upVal
01124          << " other variables: ";
01125       for(unsigned int n = 0; n < bestfit.size(); ++n)
01126             op << " " << bestfit[n];
01127       op << endl;
01128       MSG("NCFitter", Msg::kVerbose) << op.str();
01129 
01130 
01131       if(upVal < minproj) minproj = upVal;
01132 
01133       for(unsigned int n = 0; n < bestfit.size(); ++n){
01134         // If it's our first time through we need to create the graphs too.
01135         //      if(nx == 0) marg_graphs.push_back(TGraph());
01136         // TODO Something is broken with the marg graphs, but I'm too lazy
01137         // to fix it, so for now just do this.
01138         if(marg_graphs.size() == n) marg_graphs.push_back(TGraph());
01139         marg_graphs[n].Set(marg_graphs[n].GetN()+1);
01140         marg_graphs[n].SetPoint(marg_graphs[n].GetN()-1, xhere, bestfit[n]);
01141       }
01142     }
01143 
01144     MSG("NCFitter", Msg::kInfo) << "CreateOneDimProjection: "
01145                                 << "min chisq = " << minproj
01146                                 << " cf minimizer's " << minVal << endl;
01147 
01148 #if 0
01149     cout << "Beginning backtrack test...\n";
01150     for(int nx = steps; nx >= 0; --nx){
01151       const double xhere = param.Min()+nx*param.Precision();
01152       CoordNDim bestfit;
01153       double upVal = func->EvalAt(Coord(xhere, -999), bestfit);
01154       //      x.push_back(xhere);
01155       //      y.push_back(upVal);
01156       const double diff = upVal - y[nx];
01157       if(diff < -1e-4){
01158         cout << "WARNING - GOT BETTER RESULT TRACKING BACKWARD, FIXING\n";
01159         y[nx] = upVal;
01160       }
01161 
01162       if(upVal < minproj) minproj = upVal;
01163       /*
01164       for(unsigned int n = 0; n < bestfit.size(); ++n){
01165         // If it's our first time through we need to create the graphs too.
01166         if(nx == 0) marg_graphs.push_back(TGraph());
01167         marg_graphs[n].Set(marg_graphs[n].GetN()+1);
01168         marg_graphs[n].SetPoint(marg_graphs[n].GetN()-1, xhere, bestfit[n]);
01169       }
01170       */
01171     }
01172 #endif
01173 
01174     bool needLeftErr = true;
01175     bool needRightErr = true;
01176 
01177     // Initialize right error for downward sloping projections.
01178     // .5 is to be consistent with binning elsewhere.
01179     rightErr = param.Max()+.5*param.Precision();
01180 
01181     for(int nx = 0; nx <= steps; ++nx){
01182       y[nx] -= minproj;
01183 
01184       const double upVal = y[nx];
01185 
01186       if(needRightErr && !needLeftErr && upVal > 1){
01187         needRightErr = false;
01188         rightErr = x[nx];
01189       }
01190       if(needLeftErr && upVal < 1){
01191         needLeftErr = false;
01192         leftErr = x[nx]-param.Precision();
01193       }
01194     }
01195 
01196     TGraph* ret = new TGraph(steps+1, &x[0], &y[0]);
01197 
01198     return ret;
01199   }

TGraph NC::Fitter::CreateOneDimProjectionInt const ICallableInt *  func,
int  minstep,
int  maxstep,
double &  leftErr,
double &  rightErr
 

Definition at line 1203 of file NCFitter.cxx.

References CoordInt, NC::Fitter::ICallableInt::EvalAt(), MSG, and NC::Utility::ReportProgress().

01208   {
01209     vector<double> xs, ys;
01210 
01211     TStopwatch sw; // starts automatically
01212 
01213     double minproj = 1e10;
01214 
01215     for(int x = minstep; x <= maxstep; ++x){
01216       ReportProgress(double(x-minstep)/(maxstep-minstep), sw);
01217 
01218       //      CoordInt bestfit;
01219       CoordInt pos; pos.push_back(x);
01220       const double upVal = func->EvalAt(pos);//, bestfit);
01221       xs.push_back(x);
01222       ys.push_back(upVal);
01223 
01224       if(upVal < minproj) minproj = upVal;
01225       /*
01226       for(unsigned int n = 0; n < bestfit.size(); ++n){
01227         // If it's our first time through we need to create the graphs too.
01228         if(nx == 0) marg_graphs.push_back(TGraph());
01229         marg_graphs[n].Set(marg_graphs[n].GetN()+1);
01230         marg_graphs[n].SetPoint(marg_graphs[n].GetN()-1, xhere, bestfit[n]);
01231       }
01232       */
01233     }
01234 
01235     MSG("NCFitter", Msg::kInfo) << "CreateOneDimProjection: "
01236                                 << "min chisq = " << minproj << endl;
01237 
01238 
01239     bool needLeftErr = true;
01240     bool needRightErr = true;
01241 
01242     // Find the intersections using a linear interpolation
01243     for(int x = 0; x <= maxstep-minstep; ++x){
01244       ys[x] -= minproj;
01245 
01246       const double upVal = ys[x];
01247 
01248       if(needRightErr && !needLeftErr && upVal > 1){
01249         needRightErr = false;
01250         //      rightErr = minstep+x;
01251 
01252         rightErr = (minstep+x-1)+(1-ys[x-1])/(ys[x]-ys[x-1]);
01253       }
01254       if(needLeftErr && upVal < 1){
01255         needLeftErr = false;
01256         //      leftErr = minstep+x;
01257 
01258         if(x == 0)
01259           leftErr = minstep;
01260         else
01261           leftErr = (minstep+x-1)+(1-ys[x-1])/(ys[x]-ys[x-1]);
01262       }
01263     }
01264 
01265     if(needRightErr) rightErr = maxstep;
01266 
01267     TGraph ret(maxstep-minstep, &xs[0], &ys[0]);
01268     return ret;
01269   }

std::vector< Coord > NC::Fitter::FindContour const ICallable2D *  func,
const Coord &  minCoord,
const double  height,
const Coord &  precision,
std::vector< TGraph > *  marg_graphs = 0
 

Find contour of height height in the function func.

Search will be to precision precision. You must pass the previously located minimum of the function in minCoord. The contour must be continuous, finite and closed.

Definition at line 658 of file NCFitter.cxx.

References CoordNDim, NC::Fitter::ICallable2D::EvalAtEx(), MSG, NC::Utility::ReportProgress(), NC::Fitter::Coord::x, and NC::Fitter::Coord::y.

00663   {
00664     assert(!marg_graphs || marg_graphs->empty());
00665 
00666     const double dx = precision.x;
00667     const double dy = precision.y;
00668     assert(dx > 0); assert(dy > 0);
00669 
00670     typedef pair<int, int> Box;    // first == left, second == top
00671 
00672     std::map<Box, bool> results;   // Is this box already in the result set?
00673     std::vector<Box> todo;         // Boxes to investigate
00674     // Boxes whose topleft corner has already been evaluated, used as cache.
00675     std::map<Box, double> heights;
00676 
00677     // Top left corner of the box containing the best fit.
00678     const int bfxi = int(minCoord.x/dx);
00679     const int bfyi = int(minCoord.y/dy);
00680 
00681     MSG("NCFitter", Msg::kVerbose) << "Contour: walking left" << endl;
00682     // Walk to the left
00683     for(int x = bfxi; ; --x){
00684       // As soon as we exceed the contour
00685       MSG("NCFitter", Msg::kVerbose) << "Contour: at " << x << endl;
00686       CoordNDim bestfit;
00687       if(func->EvalAtEx(Coord(x*dx, bfyi*dy), bestfit) > height){
00688         // Create enough graphs to save our marginalisation progress
00689         //(2 extra to save the two variables actually in the contour)
00690         if(marg_graphs)
00691           for(unsigned int n = 0; n < 4*bestfit.size(); ++n)
00692             marg_graphs->push_back(TGraph());
00693 
00694         // make it the first element in the todo list
00695         todo.push_back(Box(x, bfyi));
00696         // and stop going left.
00697         break;
00698       }
00699     }
00700 
00701     // NB - for some reason while writing this I decided
00702     // that increasing y is downward.
00703 
00704     std::vector<Coord> contour;
00705 
00706     TStopwatch sw; // starts automatically
00707 
00708     int gxi = -1; // position on the x axis of the marg graphs.
00709 
00710     while(!todo.empty()){
00711       Box now = todo.back();
00712       todo.pop_back();
00713 
00714       ++gxi;
00715 
00716       // We end up evaluating the function multiple times at each point, so are
00717       // relying heavily on the cacheing done in GetChiSqrFromDerived()
00718 
00719       MSG("NCFitter", Msg::kVerbose) << "Contour: at "
00720                                      << now.first << ","
00721                                      << now.second << endl;
00722 
00723       // Set by the loop below.
00724       double topleft, topright, bottomleft, bottomright;
00725 
00726       // Evaluate the function at all the corners.
00727       for(int cx = 0; cx <= 1; ++cx){
00728         for(int cy = 0; cy <= 1; ++cy){
00729           Box corner(now.first+cx, now.second+cy);
00730           const std::map<Box, double>::const_iterator it = heights.find(corner);
00731           double heightHere;
00732           if(it == heights.end()){
00733             CoordNDim bestfit;
00734             heightHere = func->EvalAtEx(Coord((now.first+cx)*dx,
00735                                               (now.second+cy)*dy), bestfit);
00736 
00737             /* TODO - hacked out marg graphs because they are broken somehow. FIX!
00738             if(marg_graphs){
00739               const int dn = cx+2*cy;
00740 
00741               for(unsigned int n = 0; n < bestfit.size(); ++n){
00742                 marg_graphs->at(4*n+dn).SetPoint(marg_graphs->at(4*n+dn).
00743                                                  GetN(), gxi, bestfit[n]);
00744               }
00745             }
00746             */
00747 
00748             heights[corner] = heightHere;
00749           }
00750           else{
00751             heightHere = heights[corner];
00752           }
00753           if(cx == 0 && cy == 0) topleft = heightHere;
00754           if(cx == 1 && cy == 0) topright = heightHere;
00755           if(cx == 0 && cy == 1) bottomleft = heightHere;
00756           if(cx == 1 && cy == 1) bottomright = heightHere;
00757         }
00758       }
00759 
00760       MSG("NCFitter", Msg::kVerbose) << "Contour: tl,tr,bl,br="
00761                                      << topleft << " "
00762                                      << topright << " "
00763                                      << bottomleft << " "
00764                                      << bottomright << endl;
00765 
00766       if(now.first-bfxi){
00767         const double est_frac = (M_PI+atan2(now.second-bfyi-.01,
00768                                             double(now.first-bfxi)))/(2*M_PI);
00769         ReportProgress(est_frac, sw);
00770       }
00771 
00772 
00773       // For each side of the box: see if one corner is high and the other low.
00774       // If so, and if the box adjacent on this side isn't already part of the
00775       // results, then append the adjacent box to the todo list and linearly
00776       // interpolate to find where to put the contour point on that edge.
00777 
00778       if((topright-height)*(bottomright-height) <= 0){
00779         Box right(now.first+1, now.second);
00780         if(!results[right]){
00781           MSG("NCFitter", Msg::kVerbose) << "Contour: went right" << endl;
00782           todo.push_back(right);
00783           results[right] = true;
00784           const double rightdiff = (bottomright-topright) ?
00785             bottomright-topright : 1;
00786           contour.push_back(Coord((now.first+1)*dx,
00787                                   (now.second+(height-topright)/rightdiff)*dy));
00788         }
00789       }
00790       if( (topleft-height)*(bottomleft-height) <= 0){
00791         Box left(now.first-1, now.second);
00792         if(!results[left]){
00793           MSG("NCFitter", Msg::kVerbose) << "Contour: went left" << endl;
00794           todo.push_back(left);
00795           results[left] = true;
00796           const double leftdiff = (bottomleft-topleft)
00797             ? bottomleft-topleft : 1;
00798           contour.push_back(Coord(now.first*dx,
00799                                   (now.second+(height-topleft)/leftdiff)*dy));
00800         }
00801       }
00802       if( (bottomleft-height)*(bottomright-height) <= 0){
00803         Box down(now.first, now.second+1);
00804         if(!results[down]){
00805           MSG("NCFitter", Msg::kVerbose) << "Contour: went down" << endl;
00806           todo.push_back(down);
00807           results[down] = true;
00808           const double bottomdiff = (bottomright-bottomleft) ?
00809             bottomright-bottomleft : 1;
00810           contour.push_back(Coord((now.first+
00811                                    (height-bottomleft)/(bottomdiff))*dx,
00812                                   (now.second+1)*dy));
00813         }
00814       }
00815       if( (topleft-height)*(topright-height) <= 0 ){
00816         Box up(now.first, now.second-1);
00817         if(!results[up]){
00818           MSG("NCFitter", Msg::kVerbose) << "Contour: went up" << endl;
00819           todo.push_back(up);
00820           results[up] = true;
00821           const double topdiff = (topright-topleft) ? topright-topleft : 1;
00822           contour.push_back(Coord((now.first+(height-topleft)/topdiff)*dx,
00823                                   now.second*dy));
00824         }
00825       }
00826     }
00827 
00828     ReportProgress(1, sw);
00829 
00830     if(contour.size()) contour.push_back(contour[0]); // Close the loop.
00831     return contour;
00832   }

std::vector< CoordNDim > NC::Fitter::FindContourInt const ICallableInt *  func,
const CoordInt minCoord,
const double  height,
std::vector< TGraph > *  marg_graphs = 0
 

Find contour of height height in the function func.

Search will be to precision precision. You must pass the previously located minimum of the function in minCoord. The contour must be continuous, finite and closed.

Definition at line 899 of file NCFitter.cxx.

References abs(), CoordInt, CoordNDim, NC::Fitter::FuncCacheInt::EvalAtEx(), Interpolate(), MSG, NC::Utility::ReportProgress(), NC::Fitter::CoordBase< T >::x(), and NC::Fitter::CoordBase< T >::y().

00903   {
00904     assert(!marg_graphs || marg_graphs->empty());
00905     assert(minCoord.size() == 2);
00906 
00907     // Put a cache in front of ourselves
00908     FuncCacheInt* func = new FuncCacheInt(func_org);
00909 
00910     std::map<CoordInt, bool> results; // Is this box already in the result set?
00911     std::vector<CoordInt> todo;       // Boxes to investigate
00912 
00913     MSG("NCFitter", Msg::kVerbose) << "Contour: walking left" << endl;
00914     // Walk to the left
00915     for(int x = minCoord.x(); ; --x){
00916       // As soon as we exceed the contour
00917       MSG("NCFitter", Msg::kVerbose) << "Contour: at " << x << endl;
00918       CoordInt evalAt(x, minCoord.y());
00919       CoordInt bestfit;
00920       if(func->EvalAtEx(evalAt, &bestfit) > height){
00921         // Create enough graphs to save our marginalisation progress
00922         //(2 extra to save the two variables actually in the contour)
00923         if(marg_graphs)
00924           for(unsigned int n = 0; n < 2+bestfit.size(); ++n)
00925             marg_graphs->push_back(TGraph());
00926 
00927         // make it the first element in the todo list
00928         todo.push_back(evalAt);
00929         // and stop going left.
00930         break;
00931       }
00932     }
00933 
00934     std::vector<CoordNDim> contour;
00935 
00936     TStopwatch sw; // starts automatically
00937 
00938     while(!todo.empty()){
00939       CoordInt now = todo.back();
00940       todo.pop_back();
00941 
00942       MSG("NCFitter", Msg::kVerbose) << "Contour: at " << now << endl;
00943 
00944       const double est_frac = (M_PI+
00945                                atan2(-double(now.y()-minCoord.y()-.01),
00946                                      double(now.x()-minCoord.x())))/(2*M_PI);
00947       ReportProgress(est_frac, sw);
00948 
00949 
00950       // For each side of the box: see if one corner is high and the other low.
00951       // If so, and if the box adjacent on this side isn't already part of the
00952       // results, then append the adjacent box to the todo list and linearly
00953       // interpolate to find where to put the contour point on that edge.
00954 
00955       for(int dx = -1; dx <= 1; ++dx){
00956         for(int dy = -1; dy <= 1; ++dy){
00957           // no diagonals, don't stay stationary
00958           if(abs(dx+dy) != 1) continue;
00959 
00960           // where we're trying to go
00961           const CoordInt newpos(now.x()+dx, now.y()+dy);
00962 
00963           // offset to the first corner of the box we're considering
00964           const int cx = int(dx > 0);
00965           const int cy = int(dy > 0);
00966 
00967           // vector to the second corner we're considering
00968           const int ix = abs(dy);
00969           const int iy = abs(dx);
00970 
00971           // The values at said corners. Reevaluating them is fine,
00972           // because 'func' is cached.
00973           CoordInt bf1, bf2;
00974           const double h1 = func->EvalAtEx(CoordInt(now.x()+cx,
00975                                                     now.y()+cy), &bf1);
00976           const double h2 = func->EvalAtEx(CoordInt(now.x()+cx+ix,
00977                                                     now.y()+cy+iy), &bf2);
00978 
00979           double interp;
00980           if(!results[newpos] && Interpolate(h1, h2, height, interp)){
00981             todo.push_back(newpos);
00982             results[newpos] = true;
00983             contour.push_back(CoordNDim(now.x()+cx+ix*interp,
00984                                         now.y()+cy+iy*interp));
00985 
00986             if(marg_graphs){
00987               marg_graphs->at(0).SetPoint(marg_graphs->at(0).GetN(),
00988                                           marg_graphs->at(0).GetN(), now.x());
00989               marg_graphs->at(1).SetPoint(marg_graphs->at(1).GetN(),
00990                                           marg_graphs->at(1).GetN(), now.y());
00991               for(unsigned int n = 0; n < bf1.size(); ++n){
00992                 const double bf = bf1[n]+interp*(bf2[n]-bf1[n]);
00993                 marg_graphs->at(2+n).SetPoint(marg_graphs->at(2+n).GetN(),
00994                                               marg_graphs->at(2+n).GetN(), bf);
00995               }
00996             } // end if marg_graphs
00997           }
00998         } // end for dy
00999       } // end for dx
01000     } // end while todo
01001 
01002     if(!contour.empty()) contour.push_back(contour[0]); // Close the loop.
01003 
01004     delete func; // our cache
01005 
01006     return contour;
01007   }

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

Definition at line 836 of file NCFitter.cxx.

References CoordNDim, and NC::Fitter::ICallableND::EvalAtEx().

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

00839   {
00840     assert(params.size() == minCoord.size());
00841 
00842     TMatrix ret(params.size(), params.size());
00843 
00844     CoordNDim junk;
00845     const double bestFitVal = func->EvalAtEx(minCoord, &junk);
00846 
00847     // First, do the 2nd derivatives in one variable
00848     for(unsigned int i = 0; i < params.size(); ++i){
00849       const double step = params[i].Precision();
00850       CoordNDim plus = minCoord;
00851       plus[i] += step;
00852       CoordNDim minus = minCoord;
00853       minus[i] -= step;
00854       const double dii = (func->EvalAtEx(plus, &junk)+
00855                           func->EvalAtEx(minus, &junk)-
00856                           2*bestFitVal)/(step*step);
00857       ret(i, i) = dii;
00858     }
00859 
00860     // Now do all the off-diagonal derivatives
00861     for(unsigned int i = 0; i < params.size()-1; ++i){
00862       for(unsigned int j = i+1; j < params.size(); ++j){
00863         const double di = params[i].Precision();
00864         const double dj = params[j].Precision();
00865 
00866         CoordNDim pp = minCoord;
00867         pp[i] += di; pp[j] += dj;
00868         CoordNDim pi = minCoord;
00869         pi[i] += di;
00870         CoordNDim pj = minCoord;
00871         pj[j] += dj;
00872 
00873         const double dij = (func->EvalAtEx(pp, &junk)+bestFitVal-
00874                             func->EvalAtEx(pi, &junk)-
00875                             func->EvalAtEx(pj, &junk))/(di*dj);
00876         ret(i, j) = dij;
00877         ret(j, i) = dij;
00878       }
00879     }
00880 
00881     ret.Invert();
00882     return ret;
00883   }

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

Definition at line 1011 of file NCFitter.cxx.

References CoordNDim, NC::Fitter::ICallable2D::EvalAtEx(), max, min, MSG, NC::Fitter::Coord::x, and NC::Fitter::Coord::y.

01015   {
01016     const int Nx = int((max.x-min.x)/prec.x+.5);
01017     const int Ny = int((max.y-min.y)/prec.y+.5);
01018 
01019     TH2D* ret = new TH2D("foo", "bar", Nx, min.x, max.x, Ny, min.y, max.y);
01020 
01021     for(int nx = 0; nx < Nx ; ++nx){
01022       for(int ny = 0; ny < Ny; ++ny){
01023         const double x = min.x+(max.x-min.x)/double(Nx)*(nx+.5);
01024         const double y = min.y+(max.y-min.y)/double(Ny)*(ny+.5);
01025         CoordNDim bestfit;
01026         const double f = func->EvalAtEx(Coord(x, y), bestfit);
01027         MSG("NCFitter", Msg::kVerbose) << "GetLowResGrid: "
01028                                        << nx << "," << ny
01029                                        << " (" << x << "," << y << ") "
01030                                        << "-> " << f << endl;
01031         ret->Fill(x, y, f);
01032       }
01033     }
01034     return ret;
01035   }

TH2D * NC::Fitter::GridSearchInt const ICallableInt *  func,
const CoordInt  min,
const CoordInt  max
 

Definition at line 1039 of file NCFitter.cxx.

References CoordInt, NC::Fitter::ICallableInt::EvalAt(), max, min, NC::Utility::ReportProgress(), NC::Fitter::CoordBase< T >::x(), and NC::Fitter::CoordBase< T >::y().

01042   {
01043     assert(min.size() == 2 && max.size() == 2);
01044 
01045     TStopwatch sw;
01046 
01047     TH2D* ret = new TH2D("", "", max.x()-min.x(), min.x(), max.x(),
01048                                  max.y()-min.y(), min.y(), max.y());
01049 
01050     for(int ny = min.y(); ny < max.y(); ++ny){
01051       for(int nx = min.x(); nx < max.x() ; ++nx){
01052         const double f = func->EvalAt(CoordInt(nx, ny));
01053         ret->Fill(nx, ny, f);
01054       }
01055       ReportProgress(double(ny)/(max.y()-min.y()), sw);
01056     }
01057 
01058     return ret;
01059   }

bool Interpolate double  val1,
double  val2,
double  target,
double &  ret
 

Definition at line 885 of file NCFitter.cxx.

Referenced by FindContourInt().

00886   {
00887     if( (val1-target)*(val2-target) > 0) return false;
00888     const double diff = (val2-val1) ? val2-val1 : 1;
00889     ret = (target-val1)/diff;
00890     return true;
00891   }

vector<TH2D*> Make2DSlices const ICallableND *  func,
const vector< NCParameter > &  ps,
const CoordNDim minpos
 

Definition at line 1317 of file NCFitter.cxx.

References CoordNDim, NC::Fitter::ICallableND::EvalAtEx(), NCParameter::LatexName(), NCParameter::Max(), NCParameter::Min(), NCParameter::Precision(), NC::Utility::ReportProgress(), and NCParameter::ShortName().

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

01320   {
01321     vector<TH2D*> ret;
01322     for(unsigned int p = 0; p < ps.size(); ++p){
01323       for(unsigned int q = 0; q < p; ++q){
01324         // +.5 makes us round to nearest int instead of toward zero.
01325         assert(ps[p].Precision());
01326         assert(ps[q].Precision());
01327 
01328         NCParameter px=ps[p];
01329         NCParameter py=ps[q];
01330 
01331         const int Nx = int((px.Max()-px.Min())/px.Precision()+.5);
01332         const int Ny = int((py.Max()-py.Min())/py.Precision()+.5);
01333 
01334         TH2D* h = new TH2D("foo", "bar", Nx, px.Min(), px.Max(),
01335                            Ny, py.Min(), py.Max());
01336         h->SetName(TString::Format("2dslice_%s_%s", px.ShortName().c_str(),
01337                                    py.ShortName().c_str() ));
01338 
01339         h->GetXaxis()->SetTitle(px.LatexName().c_str());
01340         h->GetYaxis()->SetTitle(py.LatexName().c_str());
01341 
01342         TStopwatch sw; // starts automatically
01343 
01344         for(int nx = 1; nx <= Nx; ++nx){
01345           ReportProgress(double(nx)/Nx, sw);
01346           const double xhere = px.Min()+nx*px.Precision();
01347           for(int ny = 1; ny <= Ny; ++ny){
01348             const double yhere = py.Min()+ny*py.Precision();
01349             CoordNDim evalAt = minpos;
01350             evalAt[p] = xhere; evalAt[q] = yhere;
01351             CoordNDim junk;
01352             h->SetBinContent(nx, ny, func->EvalAtEx(evalAt, &junk));
01353           } // end for ny
01354         } // end for nx
01355 
01356         ret.push_back(h);
01357       }
01358     }
01359 
01360     return ret;
01361   }

vector<TGraph> MakeSlices const ICallableND *  func,
const vector< NCParameter > &  ps,
const CoordNDim minpos
 

Definition at line 1272 of file NCFitter.cxx.

References CoordNDim, NC::Fitter::ICallableND::EvalAtEx(), MSG, and NC::Utility::ReportProgress().

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

01275   {
01276     vector<TGraph> ret;
01277     for(unsigned int p = 0; p < ps.size(); ++p){
01278       MSG("NCFitter", Msg::kInfo) << "Taking slice in "
01279                                   << ps[p].ShortName()
01280                                   << "..." << endl;
01281 
01282       // +.5 makes us round to nearest int instead of toward zero.
01283       assert(ps[p].Precision());
01284       const int steps = int(.5+(ps[p].Max()-ps[p].Min())/ps[p].Precision());
01285       assert(steps);
01286 
01287       vector<double> x, y;
01288 
01289       TStopwatch sw; // starts automatically
01290 
01291       for(int nx = 0; nx <= steps; ++nx){
01292         const double xhere = ps[p].Min()+nx*ps[p].Precision();
01293 
01294         ReportProgress(double(nx)/steps, sw);
01295 
01296         CoordNDim evalAt = minpos;
01297         evalAt[p] = xhere;
01298         CoordNDim junk;
01299         double upVal = func->EvalAtEx(evalAt, &junk);
01300         x.push_back(xhere);
01301         y.push_back(upVal);
01302       } // end for nx
01303 
01304       MSG("NCFitter", Msg::kInfo) << endl;
01305 
01306       TGraph g = TGraph(steps+1, &x[0], &y[0]);
01307       g.SetName(TString::Format("slice_%s", ps[p].ShortName().c_str()));
01308       g.SetTitle(TString::Format("Slice;%s;#chi^{2}",
01309                                  ps[p].LatexName().c_str()));
01310       ret.push_back(g);
01311     }
01312 
01313     return ret;
01314   }

double NC::Fitter::MinFinderMinuit const ICallableND *  chiSqrFunc,
const std::vector< NCParameter params,
CoordNDim ret,
TMinuit **  minu = 0
 

Definition at line 606 of file NCFitter.cxx.

References CoordNDim, and MSG.

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

00610   {
00611     ret.resize(params.size());
00612 
00613     TMinuit* minu = new MinuitForCallable(chiSqrFunc, params.size());
00614     minu->SetPrintLevel(-1); // Shut Minuit up.
00615     minu->Command("set strategy 2"); // Be careful, instead of fast.
00616 
00617     for(int n = 0; n < int(params.size()); ++n)
00618       // NB - no parameter limits imposed.
00619       minu->DefineParameter(n, params[n].ShortName().c_str(),
00620                             (params[n].Min()+params[n].Max())/2,
00621                             (params[n].Max()-params[n].Min())/4,
00622                             0, 0);
00623 
00624     // Minuit tries to return a lot of parameters we don't want to keep.
00625     double junkd; int junki; TString junks;
00626 
00627     if(minu->Migrad()){
00628       MSG("NCFitter", Msg::kWarning) << "Migrad failed, "
00629                                             << "falling back to Simplex.\n";
00630       // Things are going wrong, we should let the user see.
00631       minu->SetPrintLevel(0);
00632       minu->mnsimp();
00633       minu->Migrad();
00634     }
00635 
00636     double minChiSqr;
00637     minu->mnstat(minChiSqr, junkd, junkd, junki, junki, junki);
00638 
00639     for(unsigned int n = 0; n < params.size(); ++n)
00640       minu->GetParameter(n, ret[n], junkd);
00641 
00642     if(ppMinu)
00643       *ppMinu = minu;
00644     else
00645       delete minu;
00646 
00647     return minChiSqr;
00648   }

ostream& operator<< ostream &  os,
const CoordInt c
 

Definition at line 39 of file NCFitterTypes.cxx.

References CoordInt, and NC::Fitter::CoordBase< T >::Print().

00040   {
00041     return c.Print(os);
00042   }

ostream& operator<< ostream &  os,
const CoordNDim c
 

Definition at line 33 of file NCFitterTypes.cxx.

References CoordNDim, and NC::Fitter::CoordBase< T >::Print().

00034   {
00035     return c.Print(os);
00036   }

ostream & NC::Fitter::operator<< ostream &  os,
const FuncCacheInt &  c
 

Definition at line 197 of file NCFitter.cxx.

References NC::Fitter::FuncCacheInt::fFunc, NC::Fitter::FuncCacheInt::fNhit, and NC::Fitter::FuncCacheInt::fNmiss.

00198   {
00199     os << "FuncCacheInt for callable at " << c.fFunc
00200        << " with " << c.fNhit+c.fNmiss << " calls "
00201        << "of which " << c.fNhit << " hit and "
00202        << c.fNmiss << " missed." << endl;
00203     return os;
00204   }

ostream & NC::Fitter::operator<< ostream &  os,
const FuncCache &  c
 

Definition at line 162 of file NCFitter.cxx.

References NC::Fitter::FuncCache::fFunc, NC::Fitter::FuncCache::fNhit, and NC::Fitter::FuncCache::fNmiss.

00163   {
00164     os << "FuncCache for callable at " << c.fFunc
00165        << " with " << c.fNhit+c.fNmiss << " calls "
00166        << "of which " << c.fNhit << " hit and "
00167        << c.fNmiss << " missed." << endl;
00168     return os;
00169   }

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

Definition at line 1657 of file NCFitter.cxx.

References base, CoordNDim, and NC::Fitter::ICallableND::EvalAtEx().

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

01660   {
01661     std::vector<NCParameter> lowResParams = params;
01662     for(unsigned int n = 0; n < lowResParams.size(); ++n)
01663       lowResParams[n].SetPrecision(lowResParams[n].Precision()*10);
01664 
01665     std::vector<CoordNDim> evalAt;
01666 
01667     CoordNDim first;
01668     for(unsigned int n = 0; n < lowResParams.size(); ++n)
01669       first.push_back(lowResParams[n].Min());
01670 
01671     evalAt.push_back(first);
01672 
01673     for(unsigned int d = 0; d < lowResParams.size(); ++d){
01674       unsigned int maxn = evalAt.size();
01675       for(unsigned int n = 0; n < maxn; ++n){
01676         for(unsigned int nx = 1; ; ++nx){
01677           CoordNDim base = evalAt[n];
01678           base[d] += lowResParams[d].Precision()*nx;
01679           if(base[d] > lowResParams[d].Max()) break;
01680           evalAt.push_back(base);
01681         }
01682       }
01683     }
01684 
01685     for(unsigned int d = 0; d < lowResParams.size(); ++d)
01686       out << lowResParams[d].ShortName() << "\t";
01687     out << "chisq" << endl;
01688 
01689     for(unsigned int n = 0; n < evalAt.size(); ++n){
01690       for(unsigned int d = 0; d < evalAt[n].size(); ++d){
01691         out << evalAt[n][d]<<"\t";
01692       }
01693       CoordNDim junk;
01694       out << func->EvalAtEx(evalAt[n], &junk) << endl;
01695     }
01696   }


Generated on Mon Feb 15 11:10:39 2010 for loon by  doxygen 1.3.9.1