00001 // @(#)root/minuit2:$Id: TFitterFumili.cxx 36076 2010-10-05 09:13:12Z moneta $ 00002 // Author: L. Moneta 10/2005 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2005 ROOT Foundation, CERN/PH-SFT * 00007 * * 00008 **********************************************************************/ 00009 00010 #include "TROOT.h" 00011 #include "TFitterFumili.h" 00012 #include "TF1.h" 00013 #include "TH1.h" 00014 #include "TGraph.h" 00015 00016 #include "TFumiliFCN.h" 00017 #include "Minuit2/FumiliMinimizer.h" 00018 #include "Minuit2/FunctionMinimum.h" 00019 #include "Minuit2/MnStrategy.h" 00020 #include "Minuit2/MnPrint.h" 00021 00022 //______________________________________________________________________________ 00023 /** 00024 Implementation of the TVirtualFitter interface using the FUMILI algorithm present in Minuit2. 00025 The FUMILI algorithm is a specialized minimization algorithm in the case of a least square or likelihood 00026 functions. With this technique the Hessian matrix of the objective function is approximated using only first 00027 derivatives. 00028 BEGIN_HTML 00029 For more information on this method see page 31 of the <a href="http://seal.cern.ch/documents/minuit/mntutorial.pdf">Tutorial on Function Minimization</a>. 00030 <p> 00031 The new Fumili (Fumili2) can be set as the default fitter to be used in method like TH1::Fit, by doing 00032 <pre> 00033 TVirtualFitter::SetDefaultFitter("Fumili2"); 00034 </pre> 00035 To be used directly, Fumili2 requires that the user implements the ROOT::Minuit2::FumiliFCNBase interface and passes its pointer via the SetMinuitFCN method. 00036 END_HTML 00037 */ 00038 00039 00040 00041 using namespace ROOT::Minuit2; 00042 00043 //#define DEBUG 1 00044 00045 ClassImp(TFitterFumili); 00046 00047 TFitterFumili* gFumili2 = 0; 00048 00049 TFitterFumili::TFitterFumili() { 00050 // Constructor. Set Name and global pointer. 00051 SetName("Fumili2"); 00052 gFumili2 = this; 00053 gROOT->GetListOfSpecials()->Add(gFumili2); 00054 } 00055 00056 00057 00058 TFitterFumili::TFitterFumili(Int_t /* maxpar */) { 00059 // Constructor as default. Needed this for TVirtualFitter interface 00060 SetName("Fumili2"); 00061 gFumili2 = this; 00062 gROOT->GetListOfSpecials()->Add(gFumili2); 00063 } 00064 00065 00066 TFitterFumili::~TFitterFumili() { 00067 // destructor - deletes the minimizer 00068 00069 // delete pointer from TROOT 00070 gROOT->GetListOfSpecials()->Remove(this); 00071 if (gFumili2 == this) gFumili2 = 0; 00072 00073 } 00074 00075 00076 void TFitterFumili::CreateMinimizer(EMinimizerType ) { 00077 // Create the minimizer engine and register the plugin in ROOT 00078 // what ever we specify only Fumili is created 00079 if (PrintLevel() >=1 ) 00080 std::cout<<"TFitterFumili: Minimize using new Fumili algorithm "<<std::endl; 00081 00082 const ModularFunctionMinimizer * minimizer = GetMinimizer(); 00083 if (minimizer) delete minimizer; 00084 SetMinimizer( new FumiliMinimizer() ); 00085 00086 SetStrategy(1); 00087 // Fumili cannot deal with tolerance too smalls (10-3 corrsponds to 10-7 in FumiliBuilder) 00088 SetMinimumTolerance(0.001); 00089 00090 #ifdef DEBUG 00091 SetPrintLevel(3); 00092 #endif 00093 } 00094 00095 00096 Double_t TFitterFumili::Chisquare(Int_t npar, Double_t *params) const { 00097 // Do chisquare calculations in case of likelihood fits. 00098 const TFumiliBinLikelihoodFCN * fcn = dynamic_cast<const TFumiliBinLikelihoodFCN *> ( GetMinuitFCN() ); 00099 std::vector<double> p(npar); 00100 for (int i = 0; i < npar; ++i) 00101 p[i] = params[i]; 00102 return fcn->Chi2(p); 00103 } 00104 00105 00106 void TFitterFumili::CreateChi2FCN() { 00107 // Create Chi2FCN Fumili function. 00108 SetMinuitFCN(new TFumiliChi2FCN( *this,GetStrategy()) ); 00109 } 00110 00111 void TFitterFumili::CreateChi2ExtendedFCN() { 00112 //ExtendedFCN: for Fumili use normal method. 00113 SetMinuitFCN(new TFumiliChi2FCN(*this, GetStrategy())); 00114 } 00115 00116 void TFitterFumili::CreateBinLikelihoodFCN() { 00117 // Create bin likelihood FCN for Fumili. 00118 SetMinuitFCN( new TFumiliBinLikelihoodFCN( *this, GetStrategy()) ); 00119 }