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; }