GAMinTutorial.cxx

Go to the documentation of this file.
00001 #include "TH1.h"
00002 #include "TF1.h"
00003 #include "Fit/BinData.h"
00004 #include "Fit/Chi2FCN.h"
00005 
00006 #include "Math/WrappedMultiTF1.h"
00007 #include "Math/Minimizer.h"
00008 #include "Math/GeneticMinimizer.h"
00009 #include "Math/Factory.h"
00010 #include "HFitInterface.h"
00011 
00012 #include "TMath.h"
00013 
00014 #include "TApplication.h"
00015 #include "TLegend.h"
00016 #include "TCanvas.h"
00017 #include "TStyle.h"
00018 
00019 //#define DEBUG
00020 
00021 // Quadratic background function
00022 Double_t background(Double_t *x, Double_t *par) {
00023    return par[0] + par[1]*x[0];
00024 }
00025 
00026 // Gaussian Peak function
00027 Double_t gaussianPeak(Double_t *x, Double_t *par) {
00028   return par[0]*TMath::Gaus(x[0],par[1], par[2]);
00029 }
00030 
00031 // Sum of background and peak function
00032 Double_t fitFunction(Double_t *x, Double_t *par) {
00033   return background(x,par) + gaussianPeak(x,&par[2]) + gaussianPeak(x,&par[5]);
00034 }
00035 
00036 // We'll look for the minimum at 2 and 7
00037 double par0[8] = { 1, 0.05, 10 , 2, 0.5 , 10 , 7 , 1. }; 
00038 const int ndata = 10000; 
00039 const double gAbsTolerance = 0.1; 
00040 const int gVerbose = 0; 
00041 
00042 using std::cout;
00043 using std::endl;
00044 
00045 int GAMinimize(ROOT::Math::IMultiGenFunction& chi2Func, double& xm1, double& xm2)
00046 {
00047    // minimize the function
00048    ROOT::Math::GeneticMinimizer* min = new ROOT::Math::GeneticMinimizer();
00049    if (min == 0) { 
00050       cout << "Error creating minimizer " << endl;
00051       return -1;
00052    }
00053 
00054    // Set the parameters for the minimization.
00055    min->SetMaxFunctionCalls(1000000);
00056    min->SetMaxIterations(100000);
00057    min->SetTolerance(gAbsTolerance);
00058    min->SetPrintLevel(gVerbose);
00059    min->SetFunction(chi2Func); 
00060    min->SetParameters(100, 300);
00061 
00062 
00063    // initial values of the function
00064    double x0[8]; 
00065    std::copy(par0, par0 + 8, x0); 
00066    x0[3] = xm1; 
00067    x0[6] = xm2;
00068 
00069    for (unsigned int i = 0; i < chi2Func.NDim(); ++i) { 
00070 #ifdef DEBUG
00071       cout << "set variable " << i << " to value " << x0[i] << endl;
00072 #endif
00073       if ( i == 3 || i == 6 )
00074           min->SetLimitedVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], 0.1,2,8);
00075        else
00076          min->SetLimitedVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], 0.1,x0[i]-2,x0[i]+2);
00077    }
00078 
00079 
00080    // minimize
00081    if ( !min->Minimize() ) return 1;
00082    min->MinValue(); 
00083 
00084    // show the results
00085    cout << "Min values by GeneticMinimizer: " << min->X()[3] << "  " << min->X()[6] << endl;
00086    xm1 = min->X()[3];
00087    xm2 = min->X()[6];
00088 
00089    return 0;
00090 }
00091 
00092 
00093 const double* Min2Minimize(ROOT::Math::IMultiGenFunction& chi2Func, double xm1, double xm2) { 
00094 
00095    // minimize the function
00096    ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad");
00097    if (min == 0) { 
00098       cout << "Error creating minimizer " << endl;
00099       exit(-1);
00100    }
00101 
00102    // Set the minimizer options
00103    min->SetMaxFunctionCalls(1000000);
00104    min->SetMaxIterations(100000);
00105    min->SetTolerance(gAbsTolerance);
00106    min->SetPrintLevel(gVerbose);
00107    min->SetFunction(chi2Func); 
00108 
00109    // initial values of the function
00110    double x0[8]; 
00111    std::copy(par0, par0 + 8, x0); 
00112    x0[3] = xm1; 
00113    x0[6] = xm2;
00114 
00115    for (unsigned int i = 0; i < chi2Func.NDim(); ++i) { 
00116 #ifdef DEBUG
00117       cout << "set variable " << i << " to value " << x0[i] << endl;
00118 #endif
00119       min->SetVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], 0.1);
00120    }
00121 
00122    // minimize
00123    if ( !min->Minimize() ) exit(1);
00124    double minval = min->MinValue(); 
00125 
00126    // show the results
00127    cout << "--------------------------------------" << endl;
00128    cout << "Minuit2Minimizer(" << xm1 << "," << xm2 << ")" << endl;
00129    cout << "chi2  min value " << minval << endl; 
00130    cout << " x minimum values " << min->X()[3] << "  " << min->X()[6] << endl;
00131    for (unsigned int i = 0; i < chi2Func.NDim(); ++i)
00132       cout << min->X()[i] << " ";
00133    cout << endl;
00134 
00135    return min->X();
00136 }
00137 
00138 int GAMinTutorial()
00139 {
00140    double x1=0, x2=0;
00141 
00142 
00143    // create a TF1 from fit function and generate histogram 
00144    TF1 * fitFunc = new TF1("fitFunc",fitFunction,0,10,8);
00145    fitFunc->SetParameters(par0); 
00146 
00147    // Create a histogram filled with random data from TF1
00148    TH1D * h1 = new TH1D("h1","",100, 0, 10); 
00149    for (int i = 0; i < ndata; ++i) { 
00150       h1->Fill(fitFunc->GetRandom() ); 
00151    } 
00152    
00153    h1->Draw(); 
00154    gPad->SetFillColor(kYellow-10);
00155    h1->SetFillColor(kYellow-5);
00156    gStyle->SetOptStat(0);
00157 
00158    // perform the fit 
00159    ROOT::Fit::BinData d; 
00160    ROOT::Fit::FillData(d,h1); 
00161    ROOT::Math::WrappedMultiTF1 f(*fitFunc);
00162 
00163    // Create the function for fitting.
00164    ROOT::Fit::Chi2FCN<ROOT::Math::IMultiGenFunction> chi2Func(d,f); 
00165 
00166    // Minimizer a first time with Minuit2
00167    const double* xmin1 = Min2Minimize(chi2Func, 0, 0);
00168    fitFunc->SetParameters(&xmin1[0]);
00169    fitFunc->SetLineColor(kBlue+3);
00170    TF1 * fitFunc0 = new TF1; 
00171    fitFunc->Copy(*fitFunc0);
00172    fitFunc0->Draw("same");
00173 
00174    // Look for an approximation with a Genetic Algorithm
00175    GAMinimize(chi2Func, x1,x2);
00176 
00177    // Minimize a second time with Minuit2 
00178    const double* xmin2 = Min2Minimize(chi2Func, x1, x2);
00179    fitFunc->SetParameters(&xmin2[0]);
00180    fitFunc->SetLineColor(kRed+3);
00181    fitFunc->DrawCopy("same");
00182 
00183    TLegend* legend = new TLegend(0.61,0.72,0.86,0.86);
00184    legend->AddEntry(h1, "Histogram Data","F");
00185    legend->AddEntry(fitFunc0, "Minuit only minimization");
00186    legend->AddEntry(fitFunc, "Minuit+Genetic minimization");
00187    legend->Draw();
00188 
00189    return 0; 
00190    // Min2Minimize will exit with a different value if there is any
00191    // error.
00192 }
00193 
00194 int main(int argc, char **argv)
00195 {
00196    TApplication* theApp = new TApplication("App",&argc,argv);
00197 
00198    int status = GAMinTutorial();
00199 
00200    theApp->Run();
00201 
00202    delete theApp;
00203    theApp = 0;
00204 
00205    return status;
00206 }

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