// @(#)root/tmva $Id$ 
// Author: Andreas Hoecker, Peter Speckmayer, Joerg Stelzer, Helge Voss

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : TMVA::MCFitter                                                        *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation                                                            *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Peter Speckmayer <speckmay@mail.cern.ch> - CERN, Switzerland              *
 *      Joerg Stelzer    <Joerg.Stelzer@cern.ch>  - CERN, Switzerland             *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *                                                                                *
 * 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)                                          *
 **********************************************************************************/

//_______________________________________________________________________
/*
  MCFitter
  
  Fitter using Monte Carlo sampling of parameters 
*/
//_______________________________________________________________________


#include "TMVA/MCFitter.h"
#include "TMVA/GeneticRange.h"
#include "TMVA/Interval.h"
#include "TMVA/Timer.h"
#include "TRandom3.h"

ClassImp(TMVA::MCFitter)

//_______________________________________________________________________
TMVA::MCFitter::MCFitter( IFitterTarget& target, 
                          const TString& name, 
                          const std::vector<Interval*>& ranges, 
                          const TString& theOption ) 
   : TMVA::FitterBase( target, name, ranges, theOption ),
     fSamples( 0 ),
     fSigma  ( 1 ),
     fSeed   ( 0 )
{
   // constructor
   DeclareOptions();
   ParseOptions();
}            

//_______________________________________________________________________
void TMVA::MCFitter::DeclareOptions() 
{
   // Declare MCFitter options
   DeclareOptionRef( fSamples = 100000, "SampleSize", "Number of Monte Carlo events in toy sample" );  
   DeclareOptionRef( fSigma   = -1.0,   "Sigma", 
                    "If > 0: new points are generated according to Gauss around best value and with \"Sigma\" in units of interval length" );  
   DeclareOptionRef( fSeed    = 100,    "Seed",       "Seed for the random generator (0 takes random seeds)" );  
}

//_______________________________________________________________________
void TMVA::MCFitter::SetParameters( Int_t samples )
{
   // set MC fitter configuration parameters
   fSamples = samples;
}

//_______________________________________________________________________
Double_t TMVA::MCFitter::Run( std::vector<Double_t>& pars )
{
   // Execute fitting
   Log() << kINFO << "<MCFitter> Sampling, please be patient ..." << Endl;
   
   // sanity check
   if ((Int_t)pars.size() != GetNpars())
      Log() << kFATAL << "<Run> Mismatch in number of parameters: "
              << GetNpars() << " != " << pars.size() << Endl;

   // timing of MC
   Timer timer( fSamples, GetName() ); 
   
   std::vector<Double_t> parameters;
   std::vector<Double_t> bestParameters;

   TRandom3*rnd = new TRandom3( fSeed );
   rnd->Uniform(0.,1.);
      
   std::vector<TMVA::GeneticRange*> rndRanges;

   // initial parameters (given by argument) are ignored
   std::vector< TMVA::Interval* >::const_iterator rIt; 
   Double_t val;
   for (rIt = fRanges.begin(); rIt<fRanges.end(); rIt++) {
      rndRanges.push_back( new TMVA::GeneticRange( rnd, (*rIt) ) );
      val = rndRanges.back()->Random();
      parameters.push_back( val );
      bestParameters.push_back( val );
   }

   std::vector<Double_t>::iterator parIt;
   std::vector<Double_t>::iterator parBestIt;
      
   Double_t estimator = 0;
   Double_t bestFit   = 0;

   // loop over all MC samples
   for (Int_t sample = 0; sample < fSamples; sample++) {

      // dice the parameters
      parIt = parameters.begin();
      if (fSigma > 0.0) {
         parBestIt = bestParameters.begin();
         for (std::vector<TMVA::GeneticRange*>::iterator rndIt = rndRanges.begin(); rndIt<rndRanges.end(); rndIt++) {
            (*parIt) = (*rndIt)->Random( kTRUE, (*parBestIt), fSigma );
            parIt++;
            parBestIt++;
         }
      }
      else {
         for (std::vector<TMVA::GeneticRange*>::iterator rndIt = rndRanges.begin(); rndIt<rndRanges.end(); rndIt++) {
            (*parIt) = (*rndIt)->Random();
            parIt++;
         }
      }

      // test the estimator value for the parameters
      estimator = EstimatorFunction( parameters );

      // if the estimator ist better (=smaller), take the new parameters as the best ones
      if (estimator < bestFit || sample==0) {
         bestFit = estimator;
         bestParameters.swap( parameters );
      }

      // whats the time please?
      if ((fSamples<100) || sample%Int_t(fSamples/100.0) == 0) timer.DrawProgressBar( sample );
   }
   pars.swap( bestParameters ); // return best parameters found

   // get elapsed time
   Log() << kINFO << "Elapsed time: " << timer.GetElapsedTime() 
           << "                           " << Endl;  
   
   return bestFit;
}
 MCFitter.cxx:1
 MCFitter.cxx:2
 MCFitter.cxx:3
 MCFitter.cxx:4
 MCFitter.cxx:5
 MCFitter.cxx:6
 MCFitter.cxx:7
 MCFitter.cxx:8
 MCFitter.cxx:9
 MCFitter.cxx:10
 MCFitter.cxx:11
 MCFitter.cxx:12
 MCFitter.cxx:13
 MCFitter.cxx:14
 MCFitter.cxx:15
 MCFitter.cxx:16
 MCFitter.cxx:17
 MCFitter.cxx:18
 MCFitter.cxx:19
 MCFitter.cxx:20
 MCFitter.cxx:21
 MCFitter.cxx:22
 MCFitter.cxx:23
 MCFitter.cxx:24
 MCFitter.cxx:25
 MCFitter.cxx:26
 MCFitter.cxx:27
 MCFitter.cxx:28
 MCFitter.cxx:29
 MCFitter.cxx:30
 MCFitter.cxx:31
 MCFitter.cxx:32
 MCFitter.cxx:33
 MCFitter.cxx:34
 MCFitter.cxx:35
 MCFitter.cxx:36
 MCFitter.cxx:37
 MCFitter.cxx:38
 MCFitter.cxx:39
 MCFitter.cxx:40
 MCFitter.cxx:41
 MCFitter.cxx:42
 MCFitter.cxx:43
 MCFitter.cxx:44
 MCFitter.cxx:45
 MCFitter.cxx:46
 MCFitter.cxx:47
 MCFitter.cxx:48
 MCFitter.cxx:49
 MCFitter.cxx:50
 MCFitter.cxx:51
 MCFitter.cxx:52
 MCFitter.cxx:53
 MCFitter.cxx:54
 MCFitter.cxx:55
 MCFitter.cxx:56
 MCFitter.cxx:57
 MCFitter.cxx:58
 MCFitter.cxx:59
 MCFitter.cxx:60
 MCFitter.cxx:61
 MCFitter.cxx:62
 MCFitter.cxx:63
 MCFitter.cxx:64
 MCFitter.cxx:65
 MCFitter.cxx:66
 MCFitter.cxx:67
 MCFitter.cxx:68
 MCFitter.cxx:69
 MCFitter.cxx:70
 MCFitter.cxx:71
 MCFitter.cxx:72
 MCFitter.cxx:73
 MCFitter.cxx:74
 MCFitter.cxx:75
 MCFitter.cxx:76
 MCFitter.cxx:77
 MCFitter.cxx:78
 MCFitter.cxx:79
 MCFitter.cxx:80
 MCFitter.cxx:81
 MCFitter.cxx:82
 MCFitter.cxx:83
 MCFitter.cxx:84
 MCFitter.cxx:85
 MCFitter.cxx:86
 MCFitter.cxx:87
 MCFitter.cxx:88
 MCFitter.cxx:89
 MCFitter.cxx:90
 MCFitter.cxx:91
 MCFitter.cxx:92
 MCFitter.cxx:93
 MCFitter.cxx:94
 MCFitter.cxx:95
 MCFitter.cxx:96
 MCFitter.cxx:97
 MCFitter.cxx:98
 MCFitter.cxx:99
 MCFitter.cxx:100
 MCFitter.cxx:101
 MCFitter.cxx:102
 MCFitter.cxx:103
 MCFitter.cxx:104
 MCFitter.cxx:105
 MCFitter.cxx:106
 MCFitter.cxx:107
 MCFitter.cxx:108
 MCFitter.cxx:109
 MCFitter.cxx:110
 MCFitter.cxx:111
 MCFitter.cxx:112
 MCFitter.cxx:113
 MCFitter.cxx:114
 MCFitter.cxx:115
 MCFitter.cxx:116
 MCFitter.cxx:117
 MCFitter.cxx:118
 MCFitter.cxx:119
 MCFitter.cxx:120
 MCFitter.cxx:121
 MCFitter.cxx:122
 MCFitter.cxx:123
 MCFitter.cxx:124
 MCFitter.cxx:125
 MCFitter.cxx:126
 MCFitter.cxx:127
 MCFitter.cxx:128
 MCFitter.cxx:129
 MCFitter.cxx:130
 MCFitter.cxx:131
 MCFitter.cxx:132
 MCFitter.cxx:133
 MCFitter.cxx:134
 MCFitter.cxx:135
 MCFitter.cxx:136
 MCFitter.cxx:137
 MCFitter.cxx:138
 MCFitter.cxx:139
 MCFitter.cxx:140
 MCFitter.cxx:141
 MCFitter.cxx:142
 MCFitter.cxx:143
 MCFitter.cxx:144
 MCFitter.cxx:145
 MCFitter.cxx:146
 MCFitter.cxx:147
 MCFitter.cxx:148
 MCFitter.cxx:149
 MCFitter.cxx:150
 MCFitter.cxx:151
 MCFitter.cxx:152
 MCFitter.cxx:153
 MCFitter.cxx:154