18 class MultiGenFunctionFitness : 
public TMVA::IFitterTarget {
 
   22    const ROOT::Math::IMultiGenFunction& fFunc;
 
   23    std::vector<int> fFixedParFlag;
 
   24    mutable std::vector<double> fValues;
 
   27    MultiGenFunctionFitness(
const ROOT::Math::IMultiGenFunction& 
function) : fNCalls(0),
 
   29    { fNFree = fFunc.NDim(); }
 
   31    unsigned int NCalls()
 const { 
return fNCalls; }
 
   32    unsigned int NDims()
 const { 
return fNFree; }
 
   34    unsigned int NTotal()
 const { 
return fFunc.NDim(); }
 
   36    void FixParameter(
unsigned int ipar, 
double value, 
bool fix = 
true) {
 
   38       if (fValues.size() != fFunc.NDim() ) {
 
   39          fValues.resize(fFunc.NDim() );
 
   40          fFixedParFlag.resize(fFunc.NDim());
 
   43       if (ipar >= fValues.size() ) 
return;
 
   46       fFixedParFlag[ipar] = fix;
 
   47       fValues[ipar] = value;
 
   49       for (
unsigned int i = 0; i < fFixedParFlag.size(); ++i)
 
   50          if (!fFixedParFlag[i] ) fNFree++;
 
   55    const std::vector<double> & Transform( 
const std::vector<double> & factors)
 const {
 
   56       unsigned int n = fValues.size();
 
   57       if (n == 0 || fNFree == n )
 
   61       for (
unsigned int i = 0, j = 0; i < n ; ++i) {
 
   62          if (!fFixedParFlag[i] ) {
 
   64             fValues[i] = factors[j];
 
   71    Double_t Evaluate(
const std::vector<double> & factors )
 const {
 
   72       const std::vector<double> & x = Transform( factors);
 
   76    Double_t EstimatorFunction(std::vector<double> & factors ){
 
   78       return Evaluate( factors);
 
   82 GeneticMinimizerParameters::GeneticMinimizerParameters()
 
   85    int defmaxiter = ROOT::Math::MinimizerOptions::DefaultMaxIterations();
 
   86    fNsteps   =  (defmaxiter > 0) ?  defmaxiter : 100;
 
   92    fConvCrit =10.0 * ROOT::Math::MinimizerOptions::DefaultTolerance(); 
 
   93    if (fConvCrit <=0 ) fConvCrit = 0.001;
 
   99 GeneticMinimizer::GeneticMinimizer(
int ):
 
  102    fParameters(GeneticMinimizerParameters() )
 
  106    ROOT::Math::IOptions * geneticOpt = ROOT::Math::MinimizerOptions::FindDefault(
"Genetic");
 
  108       ROOT::Math::MinimizerOptions opt; 
 
  109       opt.SetExtraOptions(*geneticOpt);
 
  110       this->SetOptions(opt);
 
  114    SetTolerance(0.1 * fParameters.fConvCrit);
 
  115    SetMaxIterations( fParameters.fNsteps);
 
  118 GeneticMinimizer::~GeneticMinimizer()
 
  127 void GeneticMinimizer::Clear()
 
  138 void GeneticMinimizer::SetFunction(
const ROOT::Math::IMultiGenFunction & func)
 
  142    fFitness = 
new MultiGenFunctionFitness(func);
 
  143    fResult = std::vector<double>(func.NDim() );
 
  144    assert(fResult.size() == NDim() );
 
  147 bool GeneticMinimizer::SetLimitedVariable(
unsigned int , 
const std::string & , 
double , 
double , 
double lower , 
double upper )
 
  149    fRanges.push_back( 
new TMVA::Interval(lower,upper) );
 
  154 bool GeneticMinimizer::SetVariable(
unsigned int, 
const std::string& name, 
double value, 
double step)
 
  157    double lower = value - (50 * step);
 
  158    double upper = value + (50 * step);
 
  159    Info(
"GeneticMinimizer::SetVariable", 
"Variables should be limited - set automatic range to 50 times step size for %s : [%f, %f]",
 
  160         name.c_str(),lower,upper);
 
  161    fRanges.push_back( 
new TMVA::Interval(lower, upper ) );
 
  166 bool GeneticMinimizer::SetFixedVariable(
unsigned int par, 
const std::string& name, 
double value) {
 
  169       Error(
"GeneticMinimizer::SetFixedVariable", 
"Function has not been set - cannot set fixed variables %s",name.c_str());
 
  173    static_cast<MultiGenFunctionFitness*
>(fFitness)->FixParameter(par, value);
 
  178 void GeneticMinimizer::SetParameters(
const GeneticMinimizerParameters & params )
 
  180    fParameters  = params;
 
  182    SetTolerance( 0.1 * fParameters.fConvCrit);
 
  183    SetMaxIterations( fParameters.fNsteps );
 
  186 ROOT::Math::MinimizerOptions GeneticMinimizer::Options()
 const {
 
  187    ROOT::Math::MinimizerOptions opt;
 
  188    GetGeneticOptions(opt);
 
  192 void  GeneticMinimizer::GetGeneticOptions(ROOT::Math::MinimizerOptions & opt)
 const {
 
  194    opt.SetTolerance(fParameters.fConvCrit/10); 
 
  195    opt.SetPrintLevel(PrintLevel() );
 
  196    opt.SetMaxIterations(fParameters.fNsteps);
 
  198    opt.SetMinimizerType(
"Genetic");
 
  199    opt.SetMaxFunctionCalls(0);
 
  203    opt.SetMinimizerAlgorithm(
"");
 
  205    ROOT::Math::GenAlgoOptions geneticOpt;
 
  206    geneticOpt.SetValue(
"PopSize",fParameters.fPopSize);
 
  207    geneticOpt.SetValue(
"Steps",fParameters.fNsteps);
 
  208    geneticOpt.SetValue(
"Cycles",fParameters.fCycles);
 
  209    geneticOpt.SetValue(
"SC_steps",fParameters.fSC_steps);
 
  210    geneticOpt.SetValue(
"SC_rate",fParameters.fSC_rate);
 
  211    geneticOpt.SetValue(
"SC_factor",fParameters.fSC_factor);
 
  212    geneticOpt.SetValue(
"ConvCrit",fParameters.fConvCrit);
 
  213    geneticOpt.SetValue(
"RandomSeed",fParameters.fSeed);
 
  215    opt.SetExtraOptions(geneticOpt);
 
  218 void GeneticMinimizer::SetOptions(
const ROOT::Math::MinimizerOptions & opt)
 
  220    SetTolerance(opt.Tolerance() );
 
  221    SetPrintLevel(opt.PrintLevel() );
 
  223    SetMaxIterations(opt.MaxIterations() );
 
  225    fParameters.fConvCrit = 10.*opt.Tolerance(); 
 
  228    const ROOT::Math::IOptions * geneticOpt = opt.ExtraOptions();
 
  230       Warning(
"GeneticMinimizer::SetOptions", 
"No specific genetic minimizer options have been set");
 
  235    geneticOpt->GetValue(
"PopSize",fParameters.fPopSize);
 
  236    geneticOpt->GetValue(
"Steps",fParameters.fNsteps);
 
  237    geneticOpt->GetValue(
"Cycles",fParameters.fCycles);
 
  238    geneticOpt->GetValue(
"SC_steps",fParameters.fSC_steps);
 
  239    geneticOpt->GetValue(
"SC_rate",fParameters.fSC_rate);
 
  240    geneticOpt->GetValue(
"SC_factor",fParameters.fSC_factor);
 
  241    geneticOpt->GetValue(
"ConvCrit",fParameters.fConvCrit);
 
  242    geneticOpt->GetValue(
"RandomSeed",fParameters.fSeed);
 
  245    int maxiter = opt.MaxIterations();
 
  246    if (maxiter > 0 && fParameters.fNsteps > 0 && maxiter !=  fParameters.fNsteps  )    {
 
  247       Warning(
"GeneticMinimizer::SetOptions", 
"max iterations value given different than  than Steps - set equal to Steps %d",fParameters.fNsteps);
 
  249    if (fParameters.fNsteps > 0) SetMaxIterations(fParameters.fNsteps);
 
  253 bool GeneticMinimizer::Minimize()
 
  257       Error(
"GeneticMinimizer::Minimize",
"Fitness function has not been set");
 
  262    if (MaxIterations() > 0) fParameters.fNsteps = MaxIterations();
 
  263    if (Tolerance() > 0) fParameters.fConvCrit = 10* Tolerance();
 
  265    TMVA::GeneticAlgorithm mg( *fFitness, fParameters.fPopSize, fRanges, fParameters.fSeed );
 
  267    if (PrintLevel() > 0) {
 
  268       std::cout << 
"GeneticMinimizer::Minimize  - Start iterating - max iterations = " <<  MaxIterations()
 
  269                 << 
" conv criteria (tolerance) =  "   << fParameters.fConvCrit << std::endl;
 
  273    unsigned int niter = 0;
 
  277       mg.CalculateFitness();
 
  282       mg.GetGeneticPopulation().TrimPopulation();
 
  284       mg.SpreadControl( fParameters.fSC_steps, fParameters.fSC_rate, fParameters.fSC_factor );
 
  286       if (PrintLevel() > 2) {
 
  287          std::cout << 
"New Iteration " << niter << 
" with  parameter values :" << std::endl;
 
  288          TMVA::GeneticGenes* genes = mg.GetGeneticPopulation().GetGenes( 0 );
 
  290             std::vector<Double_t> gvec;
 
  291             gvec = genes->GetFactors();
 
  292             for (
unsigned int i = 0; i < gvec.size(); ++i) {
 
  293                std::cout << gvec[i] << 
"    ";
 
  295             std::cout << std::endl;
 
  296             std::cout << 
"\tFitness function value = " <<  
static_cast<MultiGenFunctionFitness*
>(fFitness)->Evaluate(gvec) << std::endl;
 
  300       if ( niter > MaxIterations() && MaxIterations() > 0) {
 
  301          if (PrintLevel() > 0) {
 
  302             Info(
"GeneticMinimizer::Minimize",
"Max number of iterations %d reached - stop iterating",MaxIterations());
 
  308    } 
while (!mg.HasConverged( fParameters.fNsteps, fParameters.fConvCrit ));  
 
  310    TMVA::GeneticGenes* genes = mg.GetGeneticPopulation().GetGenes( 0 );
 
  311    std::vector<Double_t> gvec;
 
  312    gvec = genes->GetFactors();
 
  316    const std::vector<double> & transVec = 
static_cast<MultiGenFunctionFitness*
>(fFitness)->Transform(gvec);
 
  317    std::copy(transVec.begin(), transVec.end(), fResult.begin() );
 
  318    fMinValue = 
static_cast<MultiGenFunctionFitness*
>(fFitness)->Evaluate(gvec);
 
  321    if (PrintLevel() > 0) {
 
  322       if (PrintLevel() > 2) std::cout << std::endl;
 
  323           std::cout << 
"Finished Iteration (niter = " << niter << 
"  with fitness function value = " << MinValue() << std::endl;
 
  324       for (
unsigned int i = 0; i < fResult.size(); ++i) {
 
  325          std::cout << 
" Parameter-" << i << 
"\t=\t" << fResult[i] << std::endl;
 
  332 double GeneticMinimizer::MinValue()
 const 
  334    return (fFitness) ? fMinValue : 0;
 
  337 const double *  GeneticMinimizer::X()
 const {
 
  338    return (fFitness) ? &fResult[0] : 0;
 
  341 unsigned int GeneticMinimizer::NCalls()
 const 
  344       return static_cast<MultiGenFunctionFitness*
>(fFitness)->NCalls();
 
  349 unsigned int GeneticMinimizer::NDim()
 const 
  352       return static_cast<MultiGenFunctionFitness*
>(fFitness)->NTotal();
 
  356 unsigned int GeneticMinimizer::NFree()
 const 
  359       return static_cast<MultiGenFunctionFitness*
>(fFitness)->NDims();
 
  365 const double *  GeneticMinimizer::MinGradient()
 const { 
return 0; }
 
  366 bool GeneticMinimizer::ProvidesError()
 const { 
return false; }
 
  367 const double * GeneticMinimizer::Errors()
 const { 
return 0; }
 
  368 double GeneticMinimizer::Edm()
 const { 
return 0; }
 
  369 double GeneticMinimizer::CovMatrix(
unsigned int, 
unsigned int)
 const { 
return 0; }