Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
MinuitFitter.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Andraes Hoecker
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : MinuitFitter *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation *
12  * *
13  * Authors (alphabetical): *
14  * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
15  * *
16  * Copyright (c) 2005: *
17  * CERN, Switzerland *
18  * MPI-K Heidelberg, Germany *
19  * *
20  * Redistribution and use in source and binary forms, with or without *
21  * modification, are permitted according to the terms listed in LICENSE *
22  * (http://tmva.sourceforge.net/LICENSE) *
23  **********************************************************************************/
24 
25 /*! \class TMVA::MinuitFitter
26 \ingroup TMVA
27 /Fitter using MINUIT
28 */
29 #include "TMVA/MinuitFitter.h"
30 
31 #include "TMVA/Configurable.h"
32 #include "TMVA/FitterBase.h"
33 #include "TMVA/IFitterTarget.h"
34 #include "TMVA/Interval.h"
35 #include "TMVA/MinuitWrapper.h"
36 #include "TMVA/MsgLogger.h"
37 #include "TMVA/Timer.h"
38 #include "TMVA/Types.h"
39 
40 #include "TFitter.h"
41 
42 ClassImp(TMVA::MinuitFitter);
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 /// constructor
46 
47 TMVA::MinuitFitter::MinuitFitter( IFitterTarget& target,
48  const TString& name,
49  std::vector<TMVA::Interval*>& ranges,
50  const TString& theOption )
51 : TMVA::FitterBase( target, name, ranges, theOption ),
52  TMVA::IFitterTarget( )
53 {
54  // default parameters settings for Simulated Annealing algorithm
55  DeclareOptions();
56  ParseOptions();
57 
58  Init(); // initialise the TFitter
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// destructor
63 
64 TMVA::MinuitFitter::~MinuitFitter( )
65 {
66  delete fMinWrap;
67 }
68 
69 ////////////////////////////////////////////////////////////////////////////////
70 /// declare SA options
71 
72 void TMVA::MinuitFitter::DeclareOptions()
73 {
74  DeclareOptionRef(fErrorLevel = 1, "ErrorLevel", "TMinuit: error level: 0.5=logL fit, 1=chi-squared fit" );
75  DeclareOptionRef(fPrintLevel = -1, "PrintLevel", "TMinuit: output level: -1=least, 0, +1=all garbage" );
76  DeclareOptionRef(fFitStrategy = 2, "FitStrategy", "TMinuit: fit strategy: 2=best" );
77  DeclareOptionRef(fPrintWarnings = kFALSE, "PrintWarnings", "TMinuit: suppress warnings" );
78  DeclareOptionRef(fUseImprove = kTRUE, "UseImprove", "TMinuit: use IMPROVE" );
79  DeclareOptionRef(fUseMinos = kTRUE, "UseMinos", "TMinuit: use MINOS" );
80  DeclareOptionRef(fBatch = kFALSE, "SetBatch", "TMinuit: use batch mode" );
81  DeclareOptionRef(fMaxCalls = 1000, "MaxCalls", "TMinuit: approximate maximum number of function calls" );
82  DeclareOptionRef(fTolerance = 0.1, "Tolerance", "TMinuit: tolerance to the function value at the minimum" );
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// minuit-specific settings
87 
88 void TMVA::MinuitFitter::Init()
89 {
90  Double_t args[10];
91 
92  // Execute fitting
93  if (!fBatch) Log() << kINFO << "<MinuitFitter> Init " << Endl;
94 
95  // timing of MC
96  Timer timer;
97 
98  // initialize first -> prepare the fitter
99 
100  // instantiate minuit
101  // maximum number of fit parameters is equal to
102  // (2xnpar as workaround for TMinuit allocation bug (taken from RooMinuit))
103  fMinWrap = new MinuitWrapper( fFitterTarget, 2*GetNpars() );
104 
105  // output level
106  args[0] = fPrintLevel;
107  fMinWrap->ExecuteCommand( "SET PRINTOUT", args, 1 );
108 
109  if (fBatch) fMinWrap->ExecuteCommand( "SET BAT", args, 0 );
110 
111  // set fitter object, and clear
112  fMinWrap->Clear();
113 
114  // error level: 1 (2*log(L) fit
115  args[0] = fErrorLevel;
116  fMinWrap->ExecuteCommand( "SET ERR", args, 1 );
117 
118  // print warnings ?
119  if (!fPrintWarnings) fMinWrap->ExecuteCommand( "SET NOWARNINGS", args, 0 );
120 
121  // define fit strategy
122  args[0] = fFitStrategy;
123  fMinWrap->ExecuteCommand( "SET STRATEGY", args, 1 );
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// performs the fit
128 
129 Double_t TMVA::MinuitFitter::Run( std::vector<Double_t>& pars )
130 {
131  // minuit-specific settings
132  Double_t args[10];
133 
134  // Execute fitting
135  if ( !fBatch ) Log() << kINFO << "<MinuitFitter> Fitting, please be patient ... " << Endl;
136 
137  // sanity check
138  if ((Int_t)pars.size() != GetNpars())
139  Log() << kFATAL << "<Run> Mismatch in number of parameters: (a)"
140  << GetNpars() << " != " << pars.size() << Endl;
141 
142  // timing of MC
143  Timer* timer = 0;
144  if (!fBatch) timer = new Timer();
145 
146  // define fit parameters
147  for (Int_t ipar=0; ipar<fNpars; ipar++) {
148  fMinWrap->SetParameter( ipar, Form( "Par%i",ipar ),
149  pars[ipar], fRanges[ipar]->GetWidth()/100.0,
150  fRanges[ipar]->GetMin(), fRanges[ipar]->GetMax() );
151  if (fRanges[ipar]->GetWidth() == 0.0) fMinWrap->FixParameter( ipar );
152  }
153 
154  // --------- execute the fit
155 
156  // continue with usual case
157  args[0] = fMaxCalls;
158  args[1] = fTolerance;
159 
160  // MIGRAD
161  fMinWrap->ExecuteCommand( "MIGrad", args, 2 );
162 
163  // IMPROVE
164  if (fUseImprove) fMinWrap->ExecuteCommand( "IMProve", args, 0 );
165 
166  // MINOS
167  if (fUseMinos) {
168  args[0] = 500;
169  fMinWrap->ExecuteCommand( "MINOs", args, 1 );
170  }
171 
172  // retrieve fit result (statistics)
173  Double_t chi2;
174  Double_t edm;
175  Double_t errdef;
176  Int_t nvpar;
177  Int_t nparx;
178  fMinWrap->GetStats( chi2, edm, errdef, nvpar, nparx );
179 
180  // sanity check
181  if (GetNpars() != nparx) {
182  Log() << kFATAL << "<Run> Mismatch in number of parameters: "
183  << GetNpars() << " != " << nparx << Endl;
184  }
185 
186  // retrieve parameters
187  for (Int_t ipar=0; ipar<GetNpars(); ipar++) {
188  Double_t errp, errm, errsym, globcor, currVal, currErr;
189  fMinWrap->GetParameter( ipar, currVal, currErr );
190  pars[ipar] = currVal;
191  fMinWrap->GetErrors( ipar, errp, errm, errsym, globcor );
192  }
193 
194  // clean up
195 
196  // get elapsed time
197  if (!fBatch) {
198  Log() << kINFO << "Elapsed time: " << timer->GetElapsedTime()
199  << " " << Endl;
200  delete timer;
201  }
202 
203  fMinWrap->Clear();
204 
205  return chi2;
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// performs the fit by calling Run(pars)
210 
211 Double_t TMVA::MinuitFitter::EstimatorFunction( std::vector<Double_t>& pars )
212 {
213  return Run( pars );
214 }
215 
216