49 TMVA::SimulatedAnnealing::SimulatedAnnealing( IFitterTarget& target, const
std::vector<Interval*>& ranges )
50 : fKernelTemperature (kIncreasingAdaptive),
51 fFitterTarget ( target ),
55 fInitialTemperature ( 1000 ),
56 fMinTemperature ( 0 ),
58 fTemperatureScale ( 0.06 ),
59 fAdaptiveSpeed ( 1.0 ),
60 fTemperatureAdaptiveStep( 0.0 ),
61 fUseDefaultScale (
kFALSE ),
62 fUseDefaultTemperature ( kFALSE ),
63 fLogger( new MsgLogger("SimulatedAnnealing") ),
66 fKernelTemperature = kIncreasingAdaptive;
81 Bool_t useDefaultTemperature)
88 if (kernelTemperatureS ==
"IncreasingAdaptive") {
90 Log() <<
kINFO <<
"Using increasing adaptive algorithm" <<
Endl;
92 else if (kernelTemperatureS ==
"DecreasingAdaptive") {
94 Log() <<
kINFO <<
"Using decreasing adaptive algorithm" <<
Endl;
96 else if (kernelTemperatureS ==
"Sqrt") {
100 else if (kernelTemperatureS ==
"Homo") {
104 else if (kernelTemperatureS ==
"Log") {
108 else if (kernelTemperatureS ==
"Sin") {
132 for (
UInt_t rIter = 0; rIter < parameters.size(); rIter++) {
133 parameters[rIter] = fRandom->Uniform(0.0,1.0)*(fRanges[rIter]->GetMax() - fRanges[rIter]->GetMin()) + fRanges[rIter]->GetMin();
142 for (
UInt_t rIter = 0; rIter < from.size(); rIter++) to[rIter] = from[rIter];
151 ReWriteParameters( parameters, oldParameters );
153 for (
UInt_t rIter=0;rIter<parameters.size();rIter++) {
156 uni = fRandom->Uniform(0.0,1.0);
157 sign = (uni - 0.5 >= 0.0) ? (1.0) : (-1.0);
159 parameters[rIter] = oldParameters[rIter] + (fRanges[rIter]->GetMax()-fRanges[rIter]->GetMin())*0.1*distribution;
161 while (parameters[rIter] < fRanges[rIter]->GetMin() || parameters[rIter] > fRanges[rIter]->GetMax() );
169 std::vector<Double_t> newParameters( fRanges.size() );
171 for (
UInt_t rIter=0; rIter<parameters.size(); rIter++) {
174 uni = fRandom->Uniform(0.0,1.0);
175 sign = (uni - 0.5 >= 0.0) ? (1.0) : (-1.0);
177 newParameters[rIter] = parameters[rIter] + (fRanges[rIter]->GetMax()-fRanges[rIter]->GetMin())*0.1*distribution;
179 while (newParameters[rIter] < fRanges[rIter]->GetMin() || newParameters[rIter] > fRanges[rIter]->GetMax() );
182 return newParameters;
190 if (fKernelTemperature == kSqrt) {
191 currentTemperature = fInitialTemperature/(
Double_t)
TMath::Sqrt(Iter+2) * fTemperatureScale;
193 else if (fKernelTemperature == kLog) {
194 currentTemperature = fInitialTemperature/(
Double_t)
TMath::Log(Iter+2) * fTemperatureScale;
196 else if (fKernelTemperature == kHomo) {
197 currentTemperature = fInitialTemperature/(
Double_t)(Iter+2) * fTemperatureScale;
199 else if (fKernelTemperature == kSin) {
200 currentTemperature = (
TMath::Sin( (
Double_t)Iter / fTemperatureScale ) + 1.0 )/ (
Double_t)(Iter+1.0) * fInitialTemperature + fEps;
202 else if (fKernelTemperature == kGeo) {
203 currentTemperature = currentTemperature*fTemperatureScale;
205 else if (fKernelTemperature == kIncreasingAdaptive) {
206 currentTemperature = fMinTemperature + fTemperatureScale*
TMath::Log(1.0+fProgress*fAdaptiveSpeed);
208 else if (fKernelTemperature == kDecreasingAdaptive) {
209 currentTemperature = currentTemperature*fTemperatureScale;
219 if (currentTemperature < fEps)
return kFALSE;
221 Double_t prob = fRandom->Uniform(0.0, 1.0);
230 if (fKernelTemperature == kSqrt) fTemperatureScale = 1.0;
231 else if (fKernelTemperature == kLog) fTemperatureScale = 1.0;
232 else if (fKernelTemperature == kHomo) fTemperatureScale = 1.0;
233 else if (fKernelTemperature == kSin) fTemperatureScale = 20.0;
234 else if (fKernelTemperature == kGeo) fTemperatureScale = 0.99997;
235 else if (fKernelTemperature == kDecreasingAdaptive) {
236 fTemperatureScale = 1.0;
239 fTemperatureScale -= 0.000001;
242 else if (fKernelTemperature == kIncreasingAdaptive) fTemperatureScale = 0.15*( 1.0 / (
Double_t)(fRanges.size() ) );
253 Double_t t, dT, cold, delta, deltaY,
y, yNew, yBest, yOld;
254 std::vector<Double_t>
x( fRanges.size() ), xNew( fRanges.size() ), xBest( fRanges.size() ), xOld( fRanges.size() );
257 dT = fTemperatureAdaptiveStep;
258 for (
UInt_t rIter = 0; rIter <
x.size(); rIter++)
259 x[rIter] = ( fRanges[rIter]->GetMax() + fRanges[rIter]->GetMin() ) / 2.0;
261 for (
Int_t i=0; i<fMaxCalls/50; i++) {
262 if ((i>0) && (deltaY>0.0)) {
267 x = xOld = GenerateNeighbour(
x,t);
268 y = yOld = fFitterTarget.EstimatorFunction( xOld );
270 for (
Int_t k=0; (k<30) && (equilibrium<=12); k++ ) {
271 xNew = GenerateNeighbour(
x,t);
273 yNew = fFitterTarget.EstimatorFunction( xNew );
283 if (y != 0.0) delta /=
y;
284 else if (yNew != 0.0) delta /=
y;
287 if (delta < 0.1) equilibrium++;
288 else equilibrium = 0;
294 yNew = fFitterTarget.EstimatorFunction( xNew );
295 deltaY = yNew - yOld;
296 if ( (deltaY < 0.0 )&&( yNew < yBest)) {
301 if ((stopper) && (deltaY >= (100.0 * cold)))
break;
312 std::vector<Double_t> bestParameters(fRanges.size());
313 std::vector<Double_t> oldParameters (fRanges.size());
315 Double_t currentTemperature, bestFit, currentFit;
320 if (fUseDefaultTemperature) {
321 if (fKernelTemperature == kIncreasingAdaptive) {
322 fMinTemperature = currentTemperature = 1e-06;
323 FillWithRandomValues( parameters );
325 else fInitialTemperature = currentTemperature = GenerateMaxTemperature( parameters );
328 if (fKernelTemperature == kIncreasingAdaptive)
329 currentTemperature = fMinTemperature;
331 currentTemperature = fInitialTemperature;
332 FillWithRandomValues( parameters );
335 if (fUseDefaultScale) SetDefaultScale();
338 <<
"Temperatur scale = " << fTemperatureScale
339 <<
", current temperature = " << currentTemperature <<
Endl;
341 bestParameters = parameters;
342 bestFit = currentFit = fFitterTarget.EstimatorFunction( bestParameters );
344 optimizeCalls = fMaxCalls/100;
345 generalCalls = fMaxCalls - optimizeCalls;
348 Timer timer( fMaxCalls, fLogger->GetSource().c_str() );
350 for (
Int_t sample = 0; sample < generalCalls; sample++) {
351 GenerateNeighbour( parameters, oldParameters, currentTemperature );
352 Double_t localFit = fFitterTarget.EstimatorFunction( parameters );
354 if (localFit < currentFit ||
TMath::Abs(currentFit-localFit) < fEps) {
365 currentFit = localFit;
367 if (currentFit < bestFit) {
368 ReWriteParameters( parameters, bestParameters );
369 bestFit = currentFit;
373 if (!ShouldGoIn(localFit, currentFit, currentTemperature))
374 ReWriteParameters( oldParameters, parameters );
376 currentFit = localFit;
382 GenerateNewTemperature( currentTemperature, sample );
384 if ((fMaxCalls<100) || sample%
Int_t(fMaxCalls/100.0) == 0)
timer.DrawProgressBar( sample );
393 Double_t startingTemperature = fMinTemperature*(fRanges.size())*2.0;
394 currentTemperature = startingTemperature;
397 for (
Int_t sample=0;sample<optimizeCalls;sample++) {
398 GenerateNeighbour( parameters, oldParameters, currentTemperature );
399 Double_t localFit = fFitterTarget.EstimatorFunction( parameters );
401 if (localFit < currentFit) {
402 currentFit = localFit;
405 if (currentFit < bestFit) {
406 ReWriteParameters( parameters, bestParameters );
407 bestFit = currentFit;
410 else ReWriteParameters( oldParameters, parameters );
412 currentTemperature-=(startingTemperature - fEps)/optimizeCalls;
415 ReWriteParameters( bestParameters, parameters );
Double_t GenerateMaxTemperature(std::vector< Double_t > ¶meters)
maximum temperature
void FillWithRandomValues(std::vector< Double_t > ¶meters)
random starting parameters
void GenerateNewTemperature(Double_t ¤tTemperature, Int_t Iter)
generate new temperature
Random number generator class based on M.
MsgLogger & Endl(MsgLogger &ml)
void swap(ROOT::THist< DIMENSIONS, PRECISION > &a, ROOT::THist< DIMENSIONS, PRECISION > &b) noexcept
Swap two histograms.
int equals(Double_t n1, Double_t n2, double ERRORLIMIT=1.E-10)
ClassImp(TMVA::SimulatedAnnealing) TMVA
constructor
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
void GenerateNeighbour(std::vector< Double_t > ¶meters, std::vector< Double_t > &oldParameters, Double_t currentTemperature)
generate adjacent parameters
Double_t fTemperatureAdaptiveStep
Bool_t fUseDefaultTemperature
virtual ~SimulatedAnnealing()
destructor
void SetOptions(Int_t maxCalls, Double_t initialTemperature, Double_t minTemperature, Double_t eps, TString kernelTemperatureS, Double_t temperatureScale, Double_t adaptiveSpeed, Double_t temperatureAdaptiveStep, Bool_t useDefaultScale, Bool_t useDefaultTemperature)
option setter
void SetDefaultScale()
setting of default scale
Bool_t ShouldGoIn(Double_t currentFit, Double_t localFit, Double_t currentTemperature)
result checker
enum TMVA::SimulatedAnnealing::EKernelTemperature fKernelTemperature
Abstract ClassifierFactory template that handles arbitrary types.
Double_t Minimize(std::vector< Double_t > ¶meters)
minimisation algorithm
Double_t fInitialTemperature
Double_t Sqrt(Double_t x)
Double_t fTemperatureScale
void ReWriteParameters(std::vector< Double_t > &from, std::vector< Double_t > &to)
copy parameters