ROOT logo
// @(#)root/tmva $Id: MinuitFitter.cxx 29195 2009-06-24 10:39:49Z brun $ 
// Author: Andraes Hoecker

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : MinuitFitter                                                          *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation                                                            *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker  <Andreas.Hocker@cern.ch> - CERN, Switzerland             *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         * 
 *      MPI-K Heidelberg, Germany                                                 * 
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

//_______________________________________________________________________
//                                                                      
// Fitter using MINUIT
//_______________________________________________________________________

#include "TFitter.h"
#include "TMVA/MinuitFitter.h"
#include "TMVA/MinuitWrapper.h"
#include "TMVA/Interval.h"
#include "TMVA/Timer.h"

ClassImp(TMVA::MinuitFitter)

//_______________________________________________________________________
TMVA::MinuitFitter::MinuitFitter( IFitterTarget& target, 
                                  const TString& name, 
                                  std::vector<TMVA::Interval*>& ranges, 
                                  const TString& theOption ) 
   : TMVA::FitterBase( target, name, ranges, theOption ),
     TMVA::IFitterTarget( )
{
   // constructor

   // default parameters settings for Simulated Annealing algorithm
   DeclareOptions();
   ParseOptions();
   
   Init();  // initialise the TFitter
}            

//_______________________________________________________________________
TMVA::MinuitFitter::~MinuitFitter( )
{
   // destructor
   delete fMinWrap;
}

//_______________________________________________________________________
void TMVA::MinuitFitter::DeclareOptions() 
{
   // declare SA options

   DeclareOptionRef(fErrorLevel    =  1,     "ErrorLevel",    "TMinuit: error level: 0.5=logL fit, 1=chi-squared fit" );
   DeclareOptionRef(fPrintLevel    = -1,     "PrintLevel",    "TMinuit: output level: -1=least, 0, +1=all garbage" );
   DeclareOptionRef(fFitStrategy   = 2,      "FitStrategy",   "TMinuit: fit strategy: 2=best" );
   DeclareOptionRef(fPrintWarnings = kFALSE, "PrintWarnings", "TMinuit: suppress warnings" );
   DeclareOptionRef(fUseImprove    = kTRUE,  "UseImprove",    "TMinuit: use IMPROVE" );
   DeclareOptionRef(fUseMinos      = kTRUE,  "UseMinos",      "TMinuit: use MINOS" );  
   DeclareOptionRef(fBatch         = kFALSE, "SetBatch",      "TMinuit: use batch mode" );  
   DeclareOptionRef(fMaxCalls      = 1000,   "MaxCalls",      "TMinuit: approximate maximum number of function calls" );
   DeclareOptionRef(fTolerance     = 0.1,    "Tolerance",     "TMinuit: tolerance to the function value at the minimum" );
}

//_______________________________________________________________________
void TMVA::MinuitFitter::Init()
{
   // minuit-specific settings
   Double_t args[10];

   // Execute fitting
   if (!fBatch) Log() << kINFO << "<MinuitFitter> Init " << Endl;

   // timing of MC   
   Timer timer;

   // initialize first -> prepare the fitter

   // instantiate minuit
   // maximum number of fit parameters is equal to 
   // (2xnpar as workaround for TMinuit allocation bug (taken from RooMinuit))
   fMinWrap = new MinuitWrapper( fFitterTarget, 2*GetNpars() );

   // output level      
   args[0] = fPrintLevel;
   fMinWrap->ExecuteCommand( "SET PRINTOUT", args, 1 );

   if (fBatch) fMinWrap->ExecuteCommand( "SET BAT", args, 0 );

   // set fitter object, and clear
   fMinWrap->Clear();
   
   // error level: 1 (2*log(L) fit
   args[0] = fErrorLevel;
   fMinWrap->ExecuteCommand( "SET ERR", args, 1 );

   // print warnings ?   
   if (!fPrintWarnings) fMinWrap->ExecuteCommand( "SET NOWARNINGS", args, 0 );
      
   // define fit strategy
   args[0] = fFitStrategy;
   fMinWrap->ExecuteCommand( "SET STRATEGY", args, 1 );
}

//_______________________________________________________________________
Double_t TMVA::MinuitFitter::Run( std::vector<Double_t>& pars )
{
   // performs the fit

   // minuit-specific settings
   Double_t args[10];

   // Execute fitting
   if ( !fBatch ) Log() << kINFO << "<MinuitFitter> Fitting, please be patient ... " << Endl;

   // sanity check
   if ((Int_t)pars.size() != GetNpars())
      Log() << kFATAL << "<Run> Mismatch in number of parameters: (a)"
              << GetNpars() << " != " << pars.size() << Endl;

   // timing of MC   
   Timer* timer = 0;
   if (!fBatch) timer = new Timer();

   // define fit parameters
   for (Int_t ipar=0; ipar<fNpars; ipar++) {
      fMinWrap->SetParameter( ipar, Form( "Par%i",ipar ), 
                              pars[ipar], fRanges[ipar]->GetWidth()/100.0, 
                              fRanges[ipar]->GetMin(), fRanges[ipar]->GetMax() );      
      if (fRanges[ipar]->GetWidth() == 0.0) fMinWrap->FixParameter( ipar );
   }

   // --------- execute the fit
   
   // continue with usual case
   args[0] = fMaxCalls;
   args[1] = fTolerance;

   // MIGRAD
   fMinWrap->ExecuteCommand( "MIGrad", args, 2 );

   // IMPROVE
   if (fUseImprove) fMinWrap->ExecuteCommand( "IMProve", args, 0 );

   // MINOS
   if (fUseMinos) {
      args[0] = 500;
      fMinWrap->ExecuteCommand( "MINOs", args, 1 );
   }

   // retrieve fit result (statistics)
   Double_t chi2;
   Double_t edm;
   Double_t errdef; 
   Int_t    nvpar;
   Int_t    nparx;
   fMinWrap->GetStats( chi2, edm, errdef, nvpar, nparx );

   // sanity check
   if (GetNpars() != nparx) {
      Log() << kFATAL << "<Run> Mismatch in number of parameters: "
              << GetNpars() << " != " << nparx << Endl;
   }

   // retrieve parameters
   for (Int_t ipar=0; ipar<GetNpars(); ipar++) {
      Double_t errp, errm, errsym, globcor, currVal, currErr;
      fMinWrap->GetParameter( ipar, currVal, currErr );
      pars[ipar] = currVal;
      fMinWrap->GetErrors( ipar, errp, errm, errsym, globcor );
   }
            
   // clean up

   // get elapsed time   
   if (!fBatch) { 
      Log() << kINFO << "Elapsed time: " << timer->GetElapsedTime() 
           << "                            " << Endl;  
      delete timer;
   }

   fMinWrap->Clear();
   
   return chi2;
}

//_______________________________________________________________________
Double_t TMVA::MinuitFitter::EstimatorFunction( std::vector<Double_t>& pars )
{ 
   // performs the fit by calliung Run(pars)
   return Run( pars ); 
}


 MinuitFitter.cxx:1
 MinuitFitter.cxx:2
 MinuitFitter.cxx:3
 MinuitFitter.cxx:4
 MinuitFitter.cxx:5
 MinuitFitter.cxx:6
 MinuitFitter.cxx:7
 MinuitFitter.cxx:8
 MinuitFitter.cxx:9
 MinuitFitter.cxx:10
 MinuitFitter.cxx:11
 MinuitFitter.cxx:12
 MinuitFitter.cxx:13
 MinuitFitter.cxx:14
 MinuitFitter.cxx:15
 MinuitFitter.cxx:16
 MinuitFitter.cxx:17
 MinuitFitter.cxx:18
 MinuitFitter.cxx:19
 MinuitFitter.cxx:20
 MinuitFitter.cxx:21
 MinuitFitter.cxx:22
 MinuitFitter.cxx:23
 MinuitFitter.cxx:24
 MinuitFitter.cxx:25
 MinuitFitter.cxx:26
 MinuitFitter.cxx:27
 MinuitFitter.cxx:28
 MinuitFitter.cxx:29
 MinuitFitter.cxx:30
 MinuitFitter.cxx:31
 MinuitFitter.cxx:32
 MinuitFitter.cxx:33
 MinuitFitter.cxx:34
 MinuitFitter.cxx:35
 MinuitFitter.cxx:36
 MinuitFitter.cxx:37
 MinuitFitter.cxx:38
 MinuitFitter.cxx:39
 MinuitFitter.cxx:40
 MinuitFitter.cxx:41
 MinuitFitter.cxx:42
 MinuitFitter.cxx:43
 MinuitFitter.cxx:44
 MinuitFitter.cxx:45
 MinuitFitter.cxx:46
 MinuitFitter.cxx:47
 MinuitFitter.cxx:48
 MinuitFitter.cxx:49
 MinuitFitter.cxx:50
 MinuitFitter.cxx:51
 MinuitFitter.cxx:52
 MinuitFitter.cxx:53
 MinuitFitter.cxx:54
 MinuitFitter.cxx:55
 MinuitFitter.cxx:56
 MinuitFitter.cxx:57
 MinuitFitter.cxx:58
 MinuitFitter.cxx:59
 MinuitFitter.cxx:60
 MinuitFitter.cxx:61
 MinuitFitter.cxx:62
 MinuitFitter.cxx:63
 MinuitFitter.cxx:64
 MinuitFitter.cxx:65
 MinuitFitter.cxx:66
 MinuitFitter.cxx:67
 MinuitFitter.cxx:68
 MinuitFitter.cxx:69
 MinuitFitter.cxx:70
 MinuitFitter.cxx:71
 MinuitFitter.cxx:72
 MinuitFitter.cxx:73
 MinuitFitter.cxx:74
 MinuitFitter.cxx:75
 MinuitFitter.cxx:76
 MinuitFitter.cxx:77
 MinuitFitter.cxx:78
 MinuitFitter.cxx:79
 MinuitFitter.cxx:80
 MinuitFitter.cxx:81
 MinuitFitter.cxx:82
 MinuitFitter.cxx:83
 MinuitFitter.cxx:84
 MinuitFitter.cxx:85
 MinuitFitter.cxx:86
 MinuitFitter.cxx:87
 MinuitFitter.cxx:88
 MinuitFitter.cxx:89
 MinuitFitter.cxx:90
 MinuitFitter.cxx:91
 MinuitFitter.cxx:92
 MinuitFitter.cxx:93
 MinuitFitter.cxx:94
 MinuitFitter.cxx:95
 MinuitFitter.cxx:96
 MinuitFitter.cxx:97
 MinuitFitter.cxx:98
 MinuitFitter.cxx:99
 MinuitFitter.cxx:100
 MinuitFitter.cxx:101
 MinuitFitter.cxx:102
 MinuitFitter.cxx:103
 MinuitFitter.cxx:104
 MinuitFitter.cxx:105
 MinuitFitter.cxx:106
 MinuitFitter.cxx:107
 MinuitFitter.cxx:108
 MinuitFitter.cxx:109
 MinuitFitter.cxx:110
 MinuitFitter.cxx:111
 MinuitFitter.cxx:112
 MinuitFitter.cxx:113
 MinuitFitter.cxx:114
 MinuitFitter.cxx:115
 MinuitFitter.cxx:116
 MinuitFitter.cxx:117
 MinuitFitter.cxx:118
 MinuitFitter.cxx:119
 MinuitFitter.cxx:120
 MinuitFitter.cxx:121
 MinuitFitter.cxx:122
 MinuitFitter.cxx:123
 MinuitFitter.cxx:124
 MinuitFitter.cxx:125
 MinuitFitter.cxx:126
 MinuitFitter.cxx:127
 MinuitFitter.cxx:128
 MinuitFitter.cxx:129
 MinuitFitter.cxx:130
 MinuitFitter.cxx:131
 MinuitFitter.cxx:132
 MinuitFitter.cxx:133
 MinuitFitter.cxx:134
 MinuitFitter.cxx:135
 MinuitFitter.cxx:136
 MinuitFitter.cxx:137
 MinuitFitter.cxx:138
 MinuitFitter.cxx:139
 MinuitFitter.cxx:140
 MinuitFitter.cxx:141
 MinuitFitter.cxx:142
 MinuitFitter.cxx:143
 MinuitFitter.cxx:144
 MinuitFitter.cxx:145
 MinuitFitter.cxx:146
 MinuitFitter.cxx:147
 MinuitFitter.cxx:148
 MinuitFitter.cxx:149
 MinuitFitter.cxx:150
 MinuitFitter.cxx:151
 MinuitFitter.cxx:152
 MinuitFitter.cxx:153
 MinuitFitter.cxx:154
 MinuitFitter.cxx:155
 MinuitFitter.cxx:156
 MinuitFitter.cxx:157
 MinuitFitter.cxx:158
 MinuitFitter.cxx:159
 MinuitFitter.cxx:160
 MinuitFitter.cxx:161
 MinuitFitter.cxx:162
 MinuitFitter.cxx:163
 MinuitFitter.cxx:164
 MinuitFitter.cxx:165
 MinuitFitter.cxx:166
 MinuitFitter.cxx:167
 MinuitFitter.cxx:168
 MinuitFitter.cxx:169
 MinuitFitter.cxx:170
 MinuitFitter.cxx:171
 MinuitFitter.cxx:172
 MinuitFitter.cxx:173
 MinuitFitter.cxx:174
 MinuitFitter.cxx:175
 MinuitFitter.cxx:176
 MinuitFitter.cxx:177
 MinuitFitter.cxx:178
 MinuitFitter.cxx:179
 MinuitFitter.cxx:180
 MinuitFitter.cxx:181
 MinuitFitter.cxx:182
 MinuitFitter.cxx:183
 MinuitFitter.cxx:184
 MinuitFitter.cxx:185
 MinuitFitter.cxx:186
 MinuitFitter.cxx:187
 MinuitFitter.cxx:188
 MinuitFitter.cxx:189
 MinuitFitter.cxx:190
 MinuitFitter.cxx:191
 MinuitFitter.cxx:192
 MinuitFitter.cxx:193
 MinuitFitter.cxx:194
 MinuitFitter.cxx:195
 MinuitFitter.cxx:196
 MinuitFitter.cxx:197
 MinuitFitter.cxx:198
 MinuitFitter.cxx:199
 MinuitFitter.cxx:200
 MinuitFitter.cxx:201
 MinuitFitter.cxx:202
 MinuitFitter.cxx:203
 MinuitFitter.cxx:204
 MinuitFitter.cxx:205
 MinuitFitter.cxx:206
 MinuitFitter.cxx:207