TFitterMinuit.cxx

Go to the documentation of this file.
00001 #include "TROOT.h"
00002 #include "TFitterMinuit.h"
00003 #include "TF1.h"
00004 #include "TH1.h"
00005 #include "TGraph.h"
00006 
00007 #include "TChi2FCN.h"
00008 #include "TChi2ExtendedFCN.h"
00009 #include "TBinLikelihoodFCN.h"
00010 #include "TInterpreter.h"
00011 #include "TError.h"
00012 
00013 
00014 #include "Minuit2/MnMigrad.h"
00015 #include "Minuit2/MnMinos.h"
00016 #include "Minuit2/MnHesse.h"
00017 #include "Minuit2/MinuitParameter.h"
00018 #include "Minuit2/MnPrint.h"
00019 #include "Minuit2/FunctionMinimum.h"
00020 #include "Minuit2/VariableMetricMinimizer.h"
00021 #include "Minuit2/SimplexMinimizer.h"
00022 #include "Minuit2/CombinedMinimizer.h"
00023 #include "Minuit2/ScanMinimizer.h"
00024 
00025 #include <iomanip>
00026 
00027 using namespace ROOT::Minuit2;
00028 
00029 #ifndef ROOT_TMethodCall
00030 #include "TMethodCall.h"
00031 #endif
00032 
00033 //#define DEBUG 1
00034 
00035 //#define OLDFCN_INTERFACE
00036 #ifdef OLDFCN_INTERFACE
00037 extern void H1FitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00038 extern void H1FitLikelihood(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00039 extern void Graph2DFitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00040 extern void MultiGraphFitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00041 #endif
00042 
00043 //______________________________________________________________________________
00044 /**
00045 Interface to the new C++ Minuit package (MINUIT2) for ROOT. 
00046 It implements the TVirtualFitter interface using Minuit2
00047 For more information on the new C++ Minuit, see 
00048 BEGIN_HTML
00049  See:
00050 <ul>
00051 <li><a href="http://www.cern.ch/mathlibs/sw/Minuit2/html/index.html">Online doc for Minuit2 classes</a></li>
00052 <li><a href="http://seal.web.cern.ch/seal/documents/minuit/mnusersguide.pdf">C++ Minuit Users Guide
00053     </a></li>
00054 <li><a href="http://seal.cern.ch/documents/minuit/mntutorial.pdf">Minuit Tutorial on Function Minimization</a>, describing the Minuit algorithm</li>
00055 <li><a href="http://seal.cern.ch/documents/minuit/mnerror.pdf">The Interpretation of Errors in Minuit</a></li>
00056 </ul>
00057 <p>
00058 Minuit2 can be set as the default fitter to be used in method lik TH1::Fit, by doing 
00059 <pre>
00060 TVirtualFitter::SetDefaultFitter("Minuit2");
00061 </pre>
00062 This class can be used also directly by providing for the objective function either a global C function, like in TMinuit, or by passing a function class implementing the ROOT::Minuit2::FCNBase interface and used via the SetMinuitFCN method 
00063 END_HTML
00064 */
00065 
00066 
00067 
00068 ClassImp(TFitterMinuit);
00069 
00070 TFitterMinuit* gMinuit2 = 0;
00071 
00072 TFitterMinuit::TFitterMinuit() : fErrorDef(1.) , fEDMVal(0.), fGradient(false),
00073 fState(MnUserParameterState()), fMinosErrors(std::vector<MinosError>()), fMinimizer(0), fMinuitFCN(0), fDebug(1), fStrategy(1), fMinTolerance(0) {
00074    // Default constructor . Srategy and tolerance set to default values.
00075    Initialize();
00076 }
00077 
00078 
00079 TFitterMinuit::TFitterMinuit(Int_t /* maxpar */) : fErrorDef(1.) , fEDMVal(0.), fGradient(false), fState(MnUserParameterState()), fMinosErrors(std::vector<MinosError>()), fMinimizer(0), fMinuitFCN(0), fDebug(1), fStrategy(1), fMinTolerance(0) { 
00080    // Constructur needed by TVirtualFitter interface. Same behavior as default constructor.
00081    Initialize();
00082 }
00083 
00084 void TFitterMinuit::Initialize() {
00085    // initialize setting name and the global pointer
00086    SetName("Minuit2");
00087    gMinuit2 = this;
00088    gROOT->GetListOfSpecials()->Add(gMinuit2);
00089    
00090 }
00091 
00092 
00093 void TFitterMinuit::CreateMinimizer(EMinimizerType type) { 
00094    // create the minimizer engine and register the plugin in ROOT 
00095 #ifdef DEBUG
00096    std::cout<<"TFitterMinuit:create minimizer of type "<< type << std::endl;
00097 #endif
00098    if (fMinimizer) delete fMinimizer;
00099    
00100    switch (type) { 
00101       case kMigrad: 
00102          SetMinimizer( new VariableMetricMinimizer() );
00103          return;
00104       case kSimplex: 
00105          SetMinimizer( new SimplexMinimizer() );
00106          return;
00107       case kCombined: 
00108          SetMinimizer( new CombinedMinimizer() );
00109          return;
00110       case kScan: 
00111          SetMinimizer( new ScanMinimizer() );
00112          return;
00113       case kFumili: 
00114          std::cout << "TFitterMinuit::Error - Fumili Minimizer must be created from TFitterFumili " << std::endl;
00115          SetMinimizer(0);
00116          return;
00117       default: 
00118          //migrad minimizer
00119          SetMinimizer( new VariableMetricMinimizer() );
00120    }
00121 }
00122 
00123 
00124 
00125 TFitterMinuit::~TFitterMinuit() { 
00126 // destructor - deletes the minimizer and minuit fcn
00127 // if using TVirtualFitter one should use Clear() and not delete() 
00128 
00129 #ifdef DEBUG
00130    std::cout << "delete minimizer and FCN" << std::endl;
00131 #endif
00132    if (fMinuitFCN) delete fMinuitFCN; 
00133    if (fMinimizer) delete fMinimizer; 
00134    // delete minuit2 pointer from TROOT
00135    gROOT->GetListOfSpecials()->Remove(this);
00136    if (gMinuit2 == this) gMinuit2 = 0;
00137    
00138 }
00139 
00140 Double_t TFitterMinuit::Chisquare(Int_t npar, Double_t *params) const {
00141    // do chisquare calculations in case of likelihood fits 
00142    const TBinLikelihoodFCN * fcn = dynamic_cast<const TBinLikelihoodFCN *> (GetMinuitFCN() ); 
00143    if (fcn == 0) return 0;  
00144    std::vector<double> p(npar); 
00145    for (int i = 0; i < npar; ++i) 
00146       p[i] = params[i];
00147    return fcn->Chi2(p);
00148 }
00149 
00150 void TFitterMinuit::Clear(Option_t*) {
00151    // clear resources for consecutive fits
00152    
00153    //std::cout<<"clear "<<std::endl;
00154    
00155    fErrorDef = 1.; 
00156    fEDMVal = 0; 
00157    fGradient = false; 
00158    State() = MnUserParameterState();
00159    fMinosErrors.clear();
00160    //fDebug = 1;  
00161    fStrategy = 1;  
00162    fMinTolerance = 0;
00163    fCovar.clear();
00164    
00165 //    if (fMinuitFCN) { 
00166 //       delete fMinuitFCN;
00167 //       fMinuitFCN = 0; 
00168 //    }
00169    if (fMinimizer) { 
00170       delete fMinimizer; 
00171       fMinimizer = 0; 
00172    }
00173    
00174 }
00175 
00176 
00177 
00178 FunctionMinimum TFitterMinuit::DoMinimization( int nfcn, double edmval)  {
00179    // perform minimization using Minuit2 function
00180    // use always strategy 1 (2 is not yet fully tested)
00181 
00182    assert(GetMinuitFCN() != 0 );
00183    assert(GetMinimizer() != 0 );
00184 
00185    fMinuitFCN->SetErrorDef(fErrorDef); // set the error def
00186 
00187    if (fDebug >=1) { 
00188       std::cout << "TFitterMinuit - Minimize with max iterations = " << nfcn << " edmval = " << edmval << " errorDef = " << fMinuitFCN->Up() << std::endl;
00189    } 
00190 
00191    
00192    return GetMinimizer()->Minimize(*GetMinuitFCN(), State(), MnStrategy(fStrategy), nfcn, edmval);
00193 }
00194 
00195 
00196 
00197 int  TFitterMinuit::Minimize( int nfcn, double edmval)  { 
00198    // minimize (call DoMinimization() and analyze the result
00199    
00200    // min tolerance
00201    edmval = std::max(fMinTolerance, edmval);
00202 
00203    // switch off debugging if requested 
00204    int prevLevel = gErrorIgnoreLevel; 
00205    if (fDebug < 0)  // switch off printing of info messages in Minuit2
00206       gErrorIgnoreLevel = 1001;
00207    
00208    FunctionMinimum min = DoMinimization(nfcn,edmval);
00209 
00210    if (fDebug < 0) gErrorIgnoreLevel = prevLevel; // restore previous debug level 
00211 
00212    fState = min.UserState();
00213    return ExamineMinimum(min);
00214 }
00215 
00216 Int_t TFitterMinuit::ExecuteCommand(const char *command, Double_t *args, Int_t nargs){  
00217    // execute the command (Fortran Minuit compatible interface)
00218    
00219 #ifdef DEBUG
00220    std::cout<<"Execute command= "<<command<<std::endl;
00221 #endif
00222 
00223    
00224    // MIGRAD 
00225    if (strncmp(command,"MIG",3) == 0 || strncmp(command,"mig",3)  == 0) {
00226       int nfcn = 0; // default values for Minuit
00227       double edmval = 0.1;
00228       //     nfcn = GetMaxIterations();
00229       //     edmval = GetPrecision();
00230       if (nargs > 0) nfcn = int ( args[0] );
00231       if (nargs > 1) edmval = args[1];
00232       
00233       // create migrad minimizer
00234       CreateMinimizer(kMigrad);
00235       return  Minimize(nfcn, edmval);
00236       
00237       //     if(fGradient) {
00238       //       MnMigrad migrad(theFcn, State());
00239       //       theMinimum = migrad(theNFcn, fEDMVal);
00240       //       State() = theMinimum.userParameters();
00241       //     } else {
00242       //     std::cout<<"State(): "<<State()<<std::endl;
00243       //     std::cout<<"State(): "<<State()<<std::endl;
00244       //     }      
00245       
00246       
00247       
00248    } 
00249    //Minimize
00250    if (strncmp(command,"MINI",4) == 0 || strncmp(command,"mini",4)  == 0) {
00251       
00252       int nfcn = 0; // default values for Minuit
00253       double edmval = 0.1;
00254       if (nargs > 0) nfcn = int ( args[0] );
00255       if (nargs > 1) edmval = args[1];
00256       // create combined minimizer
00257       CreateMinimizer(kCombined);
00258       return Minimize(nfcn, edmval);
00259    }
00260    //Simplex
00261    if (strncmp(command,"SIM",3) == 0 || strncmp(command,"sim",3)  == 0) {
00262       
00263       int nfcn = 0; // default values for Minuit
00264       double edmval = 0.1;
00265       if (nargs > 0) nfcn = int ( args[0] );
00266       if (nargs > 1) edmval = args[1];
00267       // create combined minimizer
00268       CreateMinimizer(kSimplex);
00269       return Minimize(nfcn, edmval);
00270    }
00271    //SCan
00272    if (strncmp(command,"SCA",3) == 0 || strncmp(command,"sca",3)  == 0) {
00273       
00274       int nfcn = 0; // default values for Minuit
00275       double edmval = 0.1;
00276       if (nargs > 0) nfcn = int ( args[0] );
00277       if (nargs > 1) edmval = args[1];
00278       // create combined minimizer
00279       CreateMinimizer(kScan);
00280       return Minimize(nfcn, edmval);
00281    }
00282    // MINOS 
00283    else if (strncmp(command,"MINO",4) == 0 || strncmp(command,"mino",4)  == 0) {
00284 
00285       // switch off debugging if requested 
00286       int prevLevel = gErrorIgnoreLevel; 
00287       if (fDebug < 0)  // switch off printing of info messages in Minuit2
00288          gErrorIgnoreLevel = 1001;
00289       
00290       // recall minimize using default nfcn and edmval
00291       // should use maybe FunctionMinimum from previous call to migrad
00292       // need to keep a pointer to function minimum in the class
00293       FunctionMinimum min = DoMinimization();
00294       if (!min.IsValid() ) { 
00295          std::cout << "TFitterMinuit::MINOS failed due to invalid function minimum" << std::endl;
00296          if (fDebug < 0) gErrorIgnoreLevel = prevLevel; // restore previous debug level 
00297          return -10;
00298       }
00299       MnMinos minos( *fMinuitFCN, min);
00300       fMinosErrors.clear();
00301       for(unsigned int i = 0; i < State().VariableParameters(); i++) {
00302          if (fDebug>=3) std::cout << "Running Minos for parameter (ext#) " << State().ExtOfInt(i) << std::endl;
00303          MinosError me = minos.Minos(State().ExtOfInt(i));
00304          // print error message in Minos
00305          if (fDebug >= 0) {
00306             if ( !me.IsValid() )  
00307                std::cout << "Error running Minos for parameter " << State().ExtOfInt(i) << std::endl; 
00308          }
00309          if (fDebug >= 1) {
00310             if (!me.LowerValid() )  
00311                std::cout << "Minos:  Invalid lower error for parameter " << State().ExtOfInt(i) << std::endl; 
00312             if(me.AtLowerLimit()) 
00313                std::cout << "Minos:  Parameter  is at Lower limit."<<std::endl;
00314             if(me.AtLowerMaxFcn())
00315                std::cout << "Minos:  Maximum number of function calls exceeded when running for lower error" <<std::endl;   
00316             if(me.LowerNewMin() )
00317                std::cout << "Minos:  New Minimum found while running Minos for lower error" <<std::endl;     
00318             
00319             if (!me.UpperValid() )  
00320                std::cout << "Minos:  Invalid upper error for parameter " << State().ExtOfInt(i) << std::endl; 
00321             if(me.AtUpperLimit()) 
00322                std::cout << "Minos:  Parameter  is at Upper limit."<<std::endl;
00323             if(me.AtUpperMaxFcn())
00324                std::cout << "Minos:  Maximum number of function calls exceeded when running for upper error" <<std::endl;   
00325             if(me.UpperNewMin() )
00326                std::cout << "Minos:  New Minimum found while running Minos for upper error" <<std::endl;     
00327             
00328          }
00329          
00330          
00331          fMinosErrors.push_back(me);
00332       }
00333       if (fDebug >= 3) {
00334          for(std::vector<MinosError>::const_iterator ime = fMinosErrors.begin();
00335              ime != fMinosErrors.end(); ime++) 
00336             std::cout<<*ime<<std::endl;
00337       }
00338 
00339       if (fDebug < 0) gErrorIgnoreLevel = prevLevel; // restore previous debug level 
00340 
00341       return 0;
00342    } 
00343    //HESSE
00344    else if (strncmp(command,"HES",3) == 0 || strncmp(command,"hes",3)  == 0) {
00345 
00346       // switch off debugging if requested 
00347       int prevLevel = gErrorIgnoreLevel; 
00348       if (fDebug < 0)  // switch off printing of info messages in Minuit2
00349          gErrorIgnoreLevel = 1001;
00350 
00351       MnHesse hesse( GetStrategy() ); 
00352       // update the state
00353       const FCNBase * fcn = GetMinuitFCN();
00354       assert(fcn != 0);
00355       fState = hesse(*fcn, State(),100000 );
00356 
00357       if (fDebug < 0) gErrorIgnoreLevel = prevLevel; // restore previous debug level 
00358 
00359       if (!fState.IsValid() ) {
00360          std::cout << "TFitterMinuit::Hesse calculation failed " << std::endl;
00361          return -10;
00362       }
00363       return 0; 
00364    } 
00365    
00366    // FIX 
00367    else if (strncmp(command,"FIX",3) == 0 || strncmp(command,"fix",3)  == 0) {
00368       for(int i = 0; i < nargs; i++) {
00369          FixParameter(int(args[i])-1);
00370       }
00371       return 0;
00372    } 
00373    // SET LIMIT (uper and lower)
00374    else if (strncmp(command,"SET LIM",7) == 0 || strncmp(command,"set lim",7)  == 0) {
00375       assert(nargs >= 3);
00376       int ipar = int(args[0]);
00377       double low = args[1];
00378       double up = args[2];
00379       State().SetLimits(ipar, low, up);
00380       return 0; 
00381    } 
00382    // SET PRINT
00383    else if (strncmp(command,"SET PRINT",9) == 0 || strncmp(command,"set print",9)  == 0) {
00384       fDebug = int(args[0]);
00385       // if (fDebug >= 0) fDebug = 3;  // use print level of 3 (by default) - turn off with setprint(-1)
00386 #ifdef DEBUG
00387       fDebug = 3;
00388 #endif
00389       return 0; 
00390    } 
00391    // SET ERR
00392    else if (strncmp(command,"SET Err",7) == 0 || strncmp(command,"set err",7)  == 0) {
00393       fErrorDef = args[0];
00394       return 0; 
00395    } 
00396    // SET STRATEGY
00397    else if (strncmp(command,"SET STR",7) == 0 || strncmp(command,"set str",7)  == 0) {
00398       fStrategy = int(args[0]);
00399       return 0; 
00400    } 
00401    //SET GRAD (not impl.) 
00402    else if (strncmp(command,"SET GRA",7) == 0 || strncmp(command,"set gra",7)  == 0) {
00403       //     not yet available
00404       //     fGradient = true;
00405       return -1;
00406    } 
00407    // CALL FCN
00408    else if (strncmp(command,"CALL FCN",8) == 0 || strncmp(command,"call fcn",8)  == 0) {
00409       //     call fcn function 
00410       if (nargs < 1 || fFCN == 0) return -1;
00411       const std::vector<double> & params = State().Params();
00412       std::cout << State() << std::endl;
00413       int npar = params.size();
00414       double fval = 0; 
00415       (*fFCN)(npar, 0, fval, const_cast<double *>(&params.front()),int(args[0]) ) ;
00416       return 0; 
00417    } 
00418    else {
00419       // other commands passed 
00420       return 0;
00421    }
00422    
00423    
00424 }
00425 
00426 
00427 
00428 int  TFitterMinuit::ExamineMinimum(const FunctionMinimum & min) {  
00429    /// study the function minimum      
00430    
00431    // debug ( print all the states) 
00432    if (fDebug >= 3) { 
00433 #ifdef LATER     
00434       const std::vector<MinimumState>& iterationStates = min.States();
00435       std::cout << "Number of iterations " << iterationStates.size() << std::endl;
00436       for (unsigned int i = 0; i <  iterationStates.size(); ++i) {
00437          //std::cout << iterationStates[i] << std::endl;                                                                       
00438          const MinimumState & st =  iterationStates[i];
00439          std::cout << "----------> Iteration " << i << std::endl;
00440          int pr = std::cout.precision(18);
00441          std::cout << "            FVAL = " << st.Fval() << " Edm = " << st.Edm() << " Nfcn = " << st.NFcn() << std::endl;
00442          std::cout.precision(pr);
00443          std::cout << "            Error matrix change = " << st.Error().Dcovar() << std::endl;
00444          std::cout << "            Internal parameters : ";
00445          for (int j = 0; j < st.size() ; ++j) std::cout << " p" << j << " = " << st.Vec()(j);
00446          std::cout << std::endl;
00447       }
00448 #endif
00449    }
00450    // print result 
00451    if (min.IsValid() ) {
00452       if (fDebug >=1 ) { 
00453          std::cout << "Minimum Found" << std::endl; 
00454          int pr = std::cout.precision(18);
00455          std::cout << "FVAL  = " << State().Fval() << std::endl;
00456          std::cout << "Edm   = " << State().Edm() << std::endl;
00457          std::cout.precision(pr);
00458          std::cout << "Nfcn  = " << State().NFcn() << std::endl;
00459          std::vector<double> par = State().Params();
00460          std::vector<double> err = State().Errors();
00461          for (unsigned int i = 0; i < State().Params().size(); ++i) 
00462             std::cout << State().Parameter(i).Name() << "\t  = " << par[i] << "\t  +/-  " << err[i] << std::endl; 
00463       }
00464       return 0;
00465    }
00466    else { 
00467       if (fDebug >= 1)  {
00468          std::cout << "TFitterMinuit::Minimization DID not converge !" << std::endl; 
00469          std::cout << "FVAL  = " << State().Fval() << std::endl;
00470          std::cout << "Edm   = " << State().Edm() << std::endl;
00471          std::cout << "Nfcn  = " << State().NFcn() << std::endl;
00472       }
00473       if (min.HasMadePosDefCovar() ) { 
00474          if (fDebug >= 1) std::cout << "      Covar was made pos def" << std::endl;
00475          return -11; 
00476       }
00477       if (min.HesseFailed() ) { 
00478          if (fDebug >= 1) std::cout << "      Hesse is not valid" << std::endl;
00479          return -12; 
00480       }
00481       if (min.IsAboveMaxEdm() ) { 
00482          if (fDebug >= 1) std::cout << "      Edm is above max" << std::endl;
00483          return -13; 
00484       }
00485       if (min.HasReachedCallLimit() ) { 
00486          if (fDebug >= 1) std::cout << "      Reached call limit" << std::endl;
00487          return -14; 
00488       }
00489       return -10; 
00490    }
00491    return 0;
00492 }
00493 
00494 void TFitterMinuit::FixParameter(Int_t ipar) {
00495    // fix the paramter
00496    //   std::cout<<"FixParameter"<<std::endl;
00497    State().Fix(ipar);
00498 }
00499 
00500 Double_t* TFitterMinuit::GetCovarianceMatrix() const {
00501    // get the error matrix in a pointer to a NxN array.  
00502    // Since Minuit2 stores only the independent element need to copy in a 
00503    // cached vector
00504    unsigned int npar =  State().Covariance().Nrow();
00505    if ( int(npar) != GetNumberFreeParameters() ) { 
00506       // can happen if fit failes that npar is zero
00507       std::cout << "TFitterMinuit::GetCovarianceMatrix  Error - return null pointer" << std::endl;
00508       return 0; 
00509    }
00510    if (fCovar.size() !=  npar ) 
00511       fCovar.resize(npar*npar);
00512    
00513    for (unsigned int i = 0; i < npar; ++i) { 
00514       for (unsigned int j = 0; j < npar; ++j) {
00515          fCovar[j + npar*i] = State().Covariance()(i,j);
00516       }
00517    }
00518    return &(fCovar.front());
00519 }
00520 
00521 Double_t TFitterMinuit::GetCovarianceMatrixElement(Int_t i, Int_t j) const {
00522    // get error matrix element
00523    return State().Covariance()(i,j);
00524 }
00525 
00526 
00527 Int_t TFitterMinuit::GetErrors(Int_t ipar,Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &globcc) const {
00528    // get fit errors 
00529    //   std::cout<<"GetError"<<std::endl;
00530    eplus = 0.;
00531    eminus = 0.; 
00532 
00533    MinuitParameter mpar = State().Parameters().Parameter(ipar);
00534    if (mpar.IsFixed() || mpar.IsConst() )  return 0;
00535    if(fMinosErrors.empty()) return 0; 
00536    
00537    
00538    unsigned int nintern = State().IntOfExt(ipar);
00539    eplus = fMinosErrors[nintern].Upper();
00540    eminus = fMinosErrors[nintern].Lower();
00541    
00542    eparab = State().Error(ipar);
00543    globcc = State().GlobalCC().GlobalCC()[ipar];
00544    return 0;
00545 }
00546 
00547 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00548 // here is example of deficit of new Minuit interface
00549 //////////////////////////////////////////////
00550 Int_t TFitterMinuit::GetNumberTotalParameters() const {
00551    // number of total parameters (ugly interface)
00552    return State().Parameters().Parameters().size();
00553 }
00554 Int_t TFitterMinuit::GetNumberFreeParameters() const {
00555    // number of variable parameters
00556    return State().Parameters().VariableParameters();
00557 }
00558 
00559 
00560 Double_t TFitterMinuit::GetParError(Int_t ipar) const {
00561    // parameter error
00562    //   std::cout<<"GetParError"<<std::endl;
00563    return State().Error(ipar);
00564 }
00565 
00566 Double_t TFitterMinuit::GetParameter(Int_t ipar) const {
00567    // parameter value
00568    //   std::cout<<"GetParameter"<<std::endl;
00569    return State().Value(ipar);
00570 }
00571 
00572 Int_t TFitterMinuit::GetParameter(Int_t ipar,char *name,Double_t &value,Double_t &verr,Double_t &vlow, Double_t &vhigh) const {
00573    // get all parameter info (name, value, errors) 
00574    //   std::cout<<"GetParameter(Int_t ipar,char"<<std::endl;
00575    const MinuitParameter& mp = State().Parameter(ipar);
00576    //   std::cout<<"i= "<<ipar<<" verr= "<<mp.error()<<std::endl;
00577    std::string mpName = mp.Name();
00578    std::copy(mpName.c_str(), mpName.c_str() + mpName.size(), name);
00579    value = mp.Value();
00580    verr = mp.Error();
00581    vlow = mp.LowerLimit();
00582    vhigh = mp.UpperLimit();
00583    return 0;
00584 }
00585 
00586 const char *TFitterMinuit::GetParName(Int_t ipar) const {
00587    //   return name of parameter ipar
00588    const MinuitParameter& mp = State().Parameter(ipar);
00589    return mp.Name();
00590 }
00591 
00592 Int_t TFitterMinuit::GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx) const {
00593    // get fit statistical information
00594    //   std::cout<<"GetStats"<<std::endl;
00595    amin = State().Fval();
00596    edm = State().Edm();
00597    errdef = fErrorDef;
00598    nvpar = State().VariableParameters();
00599    nparx = State().Parameters().Parameters().size();
00600    return 0;
00601 }
00602 
00603 Double_t TFitterMinuit::GetSumLog(Int_t) {
00604    //   std::cout<<"GetSumLog"<<std::endl;
00605    return 0.;
00606 }
00607 
00608 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00609 Bool_t TFitterMinuit::IsFixed(Int_t ipar) const {
00610    // query if parameter ipar is fixed
00611    return State().Parameter(ipar).IsFixed();
00612 }
00613 
00614 
00615 void TFitterMinuit::PrintResults(Int_t level, Double_t) const {
00616    // print the fit result
00617    
00618    //   std::cout<<"PrintResults"<<std::endl;
00619    //   std::cout<<State().parameters()<<std::endl;
00620    if (fDebug >= 0 || level > 3) { 
00621       std::cout<<State()<<std::endl;
00622    }
00623    else { 
00624       // do no print covariance matrix
00625       if(!State().IsValid()) {
00626          std::cout <<  std::endl;
00627          std::cout << "WARNING: Minimum  is not valid."<<std::endl;
00628          std::cout <<  std::endl;
00629       }
00630    
00631       std::cout << "# of function calls: "<<State().NFcn()<<std::endl;
00632       std::cout << "function Value: "<< std::setprecision(12) << State().Fval()<<std::endl;
00633       std::cout << "expected distance to the Minimum (edm): "<< std::setprecision(8) << State().Edm()<<std::endl;
00634       std::cout << "fitted parameters: "<<State().Parameters()<<std::endl;
00635    }
00636 
00637    // print errors 
00638    if (level > 3) { 
00639       for(std::vector<MinosError>::const_iterator ime = fMinosErrors.begin();
00640           ime != fMinosErrors.end(); ime++) {
00641          std::cout<<*ime<<std::endl;
00642       }
00643    }
00644 }
00645 
00646 void TFitterMinuit::ReleaseParameter(Int_t ipar) {
00647    // release a fit parameter
00648    
00649    //   std::cout<<"ReleaseParameter"<<std::endl;
00650    State().Release(ipar);
00651 }
00652 
00653 
00654 
00655 void TFitterMinuit::SetFitMethod(const char *name) {
00656    // set fit method (i.e. chi2 or likelihood)
00657    // according to the method the appropriate FCN function will be created   
00658       
00659 #ifdef DEBUG
00660    std::cout<<"SetFitMethod to "<< name << std::endl;
00661 #endif
00662    if (!strcmp(name,"H1FitChisquare")) {
00663       // old way of passing
00664 #ifdef OLDFCN_INTERFACE 
00665       SetFCN(H1FitChisquare);
00666 #else 
00667       // call function (because overloaded by derived class)
00668       CreateChi2FCN();
00669 #endif
00670       return;
00671    }
00672    if (!strcmp(name,"GraphFitChisquare")) {
00673 #ifdef OLDFCN_INTERFACE 
00674       SetFCN(GraphFitChisquare);
00675 #else 
00676       // use for graph extended chi2 to include error in X coordinate
00677       if (!GetFitOption().W1) 
00678          CreateChi2ExtendedFCN( );
00679       else
00680          CreateChi2FCN( );
00681 #endif
00682       return;
00683    }
00684    if (!strcmp(name, "Graph2DFitChisquare")) {
00685 #ifdef OLDFCN_INTERFACE 
00686       SetFCN(Graph2DFitChisquare);
00687 #else 
00688       // use for graph extended chi2 to include error in X and Y coordinates
00689       //     if (!GetFitOption().W1) {
00690       //       CreateChi2ExtendedFCN( );
00691       //      else
00692       CreateChi2FCN( );
00693 #endif
00694       return;
00695       }
00696    if (!strcmp(name, "MultiGraphFitChisquare")) {
00697       fErrorDef = 1.;
00698 #ifdef OLDFCN_INTERFACE 
00699       SetFCN(MultiGraphFitChisquare);
00700 #else 
00701       CreateChi2FCN();
00702 #endif
00703       return;
00704    }
00705    if (!strcmp(name, "H1FitLikelihood")) {
00706       // old way of passing
00707 #ifdef OLDFCN_INTERFACE 
00708       SetFCN(H1FitLikelihood);
00709 #else 
00710       CreateBinLikelihoodFCN();    
00711 #endif  
00712       return;
00713    }
00714    
00715    std::cout << "TFitterMinuit::fit method " << name << " is not  supported !" << std::endl; 
00716    
00717    assert(fMinuitFCN != 0);
00718    
00719    
00720    
00721    // 
00722    //   } else {
00723    //     SetFCN(H1FitChisquare);
00724    //   }
00725    // TFitterMinuit manages the data
00726    
00727    
00728 }
00729 
00730 Int_t TFitterMinuit::SetParameter(Int_t,const char *parname,Double_t value,Double_t verr,Double_t vlow, Double_t vhigh) {
00731    // set (add) a new fit parameter passing initial value,  step size (verr) and parametr limits
00732    // if vlow > vhigh the parameter is unbounded
00733    // if the stepsize (verr) == 0 the parameter is treated as fixed   
00734 
00735 #ifdef DEBUG
00736    std::cout<<"SetParameter";
00737    std::cout << parname<<" value = " << value << " verr= "<<verr<<std::endl;
00738 #endif
00739    if(vlow < vhigh) { 
00740       State().Add(parname, value, verr, vlow, vhigh);
00741    }
00742    else
00743       State().Add(parname, value, verr);
00744    
00745    // treat constant parameter as fixed 
00746    if (verr == 0)  State().Fix(parname);
00747    return 0;
00748 }
00749 
00750 
00751 void TFitterMinuit::SetFCN(void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
00752 {
00753    // override setFCN to use the Adapter to Minuit2 FCN interface
00754    //*-*-*-*-*-*-*To set the address of the minimization function*-*-*-*-*-*-*-*
00755    //*-*          ===============================================
00756    //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00757    fFCN = fcn;
00758    if (fMinuitFCN) delete fMinuitFCN;
00759    fMinuitFCN = new TFcnAdapter(fFCN);
00760 }
00761 
00762 // need for interactive environment
00763 
00764 
00765 // global functions needed by interpreter 
00766 
00767 
00768 //______________________________________________________________________________
00769 void Minuit2InteractiveFCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
00770 {
00771    //*-*-*-*-*-*-*Static function called when SetFCN is called in interactive mode
00772    //*-*          ===============================================
00773    
00774    TMethodCall *m  = gMinuit2->GetMethodCall();
00775    if (!m) return;
00776    
00777    Long_t args[5];
00778    args[0] = (Long_t)&npar;
00779    args[1] = (Long_t)gin;
00780    args[2] = (Long_t)&f;
00781    args[3] = (Long_t)u;
00782    args[4] = (Long_t)flag;
00783    m->SetParamPtrs(args);
00784    Double_t result;
00785    m->Execute(result);
00786 }
00787 
00788 
00789 //______________________________________________________________________________
00790 void TFitterMinuit::SetFCN(void *fcn)
00791 {
00792    //*-*-*-*-*-*-*To set the address of the minimization function*-*-*-*-*-*-*-*
00793    //*-*          ===============================================
00794    //     this function is called by CINT instead of the function above
00795    //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00796    
00797    if (!fcn) return;
00798    
00799    const char *funcname = gCint->Getp2f2funcname(fcn);
00800    if (funcname) {
00801       fMethodCall = new TMethodCall();
00802       fMethodCall->InitWithPrototype(funcname,"Int_t&,Double_t*,Double_t&,Double_t*,Int_t");
00803    }
00804    fFCN = Minuit2InteractiveFCN;
00805    gMinuit2 = this; //required by InteractiveFCNm
00806    
00807    if (fMinuitFCN) delete fMinuitFCN;
00808    fMinuitFCN = new TFcnAdapter(fFCN);
00809 }
00810 
00811 void TFitterMinuit::SetMinuitFCN(  FCNBase * f) { 
00812    // class takes the ownership of the passed pointer
00813    // so needs to delete previous one 
00814    if (fMinuitFCN) delete fMinuitFCN;
00815    fMinuitFCN = f; 
00816 }
00817 
00818 void TFitterMinuit::CreateChi2FCN() { 
00819    // create a chi2 FCN object
00820    SetMinuitFCN(new TChi2FCN( *this ) );
00821 }
00822 
00823 
00824 void TFitterMinuit::CreateChi2ExtendedFCN() { 
00825    // create an extended chi2 FCN object 
00826    // used in the case of errors both on the coordinates and the value (case of a graph fit)
00827    SetMinuitFCN(new TChi2ExtendedFCN( *this ) );
00828 }
00829 
00830 void TFitterMinuit::CreateBinLikelihoodFCN() { 
00831    // create a binned likelihood FCN
00832    SetMinuitFCN(new TBinLikelihoodFCN( *this ) );
00833 }

Generated on Tue Jul 5 14:37:11 2011 for ROOT_528-00b_version by  doxygen 1.5.1