#include "Riostream.h"
#include "TMVA/SimulatedAnnealingBase.h"
ClassImp(TMVA::SimulatedAnnealingBase)
;
TMVA::SimulatedAnnealingBase::SimulatedAnnealingBase( std::vector<LowHigh_t*>& ranges )
: fRandom ( new TRandom() )
, fRanges ( ranges )
, fMaxCalls ( 500000 )
, fTemperatureGradient ( 0.3 )
, fUseAdaptiveTemperature( kFALSE )
, fInitialTemperature ( 1000 )
, fMinTemperature ( 0 )
, fEps ( 1e-04 )
, fNFunLoops ( 25 )
, fNEps ( 4 )
{
}
TMVA::SimulatedAnnealingBase::~SimulatedAnnealingBase()
{
}
Double_t TMVA::SimulatedAnnealingBase::Minimize( std::vector<Double_t>& parameters )
{
Int_t npar = parameters.size();
Double_t deltaT = fTemperatureGradient;
Double_t stepWidth = 3*npar;
if (npar < 20) stepWidth = 50;
Int_t i;
std::vector <Double_t> diffFCN;
for (i = 0; i < fNEps; ++i) diffFCN.push_back(1e20);
std::vector <Double_t> bestParameters( parameters );
std::vector <Double_t> xPars( parameters );
std::vector <Double_t> yPars( parameters );
std::vector <Double_t> adaptiveErrors;
std::vector <Int_t> nAccepted;
for (Int_t k = 0; k < npar; k++ ) {
adaptiveErrors.push_back( (fRanges[k]->second - fRanges[k]->first)/10.0 );
nAccepted.push_back(0);
}
Double_t retFCN = - MinimizeFunction( xPars );
Int_t nCalls = 1;
Double_t maxFCN = retFCN;
diffFCN[1] = retFCN;
Double_t temperature = fInitialTemperature;
Int_t nIteration = 0;
std::pair<Int_t,Int_t> optPoint;
std::pair<Int_t,Int_t> optPoint_previous;
Bool_t continueWhile = kTRUE;
while (continueWhile) {
nIteration++;
if (fUseAdaptiveTemperature) {
if (nIteration>0 && ( TMath::Abs( ( (float)nIteration/2. ) - nIteration/2 ) < 0.01 ) ) {
if (optPoint.first > 0 && optPoint.second == 0 &&
optPoint_previous.first > 0 && optPoint_previous.second == 0) {
if (stepWidth > 20) {
deltaT = sqrt( deltaT );
stepWidth = 0.5*stepWidth;
}
}
}
}
for (Int_t m = 0; m < stepWidth; m++) {
optPoint_previous.first = optPoint.first;
optPoint_previous.second = optPoint.second;
optPoint.first = 0;
optPoint.second = 0;
for (Int_t j = 0; j < fNFunLoops; j++) {
for (Int_t h = 0; h < npar; h++) {
yPars[h] = xPars[h] + gRandom->Uniform(-1.0,1.0)*adaptiveErrors[h];
while (yPars[h] < fRanges[h]->first || yPars[h] > fRanges[h]->second) {
yPars[h] = gRandom->Uniform(-2.0,2.0)*adaptiveErrors[h] + parameters[h];
}
if (h >= 1) yPars[h-1] = xPars[h-1];
Double_t retFCNi = - MinimizeFunction( yPars );
++nCalls;
if (nCalls >= fMaxCalls) {
for (i = 0; i < npar; i++) parameters[i] = bestParameters[i];
return -maxFCN;
}
if (retFCNi > retFCN) {
for (i = 0; i < npar; ++i) xPars[i] = yPars[i];
retFCN = retFCNi;
++nAccepted[h];
if (retFCNi > maxFCN) {
for (i = 0; i < npar; ++i) bestParameters[i] = yPars[i];
if (m <= stepWidth/2) optPoint.first++;
else optPoint.second++;
maxFCN = retFCNi;
}
}
else {
if (gRandom->Uniform(1.0) < this->GetPerturbationProbability( retFCNi, retFCN,
temperature )) {
for (i = 1; i < npar; ++i) xPars[i] = yPars[i];
retFCN = retFCNi;
++nAccepted[h];
}
}
}
}
for (i = 0; i < npar; ++i) {
Double_t ratio = Double_t(nAccepted[i])/Double_t(fNFunLoops);
if (ratio > 0.6) adaptiveErrors[i] *= (2.0 * (ratio - 0.6) / 0.4 + 1.0);
else if (ratio < 0.4) adaptiveErrors[i] /= (2.0 * (0.4 - ratio) / 0.4 + 1.0);
if (adaptiveErrors[i] > fRanges[i]->second - fRanges[i]->first)
adaptiveErrors[i] = fRanges[i]->second - fRanges[i]->first;
}
for (i = 0; i < npar; ++i) nAccepted[i] = 0;
}
diffFCN[1] = retFCN;
if (TMath::Abs(maxFCN - diffFCN[1]) < fEps)
for (i = 0; i < fNEps; ++i) if (TMath::Abs(retFCN - diffFCN[i]) > fEps) continueWhile = kTRUE;
if (TMath::Abs(maxFCN) < 1e-06 ) continueWhile = kFALSE;
if (temperature < fMinTemperature) continueWhile = kFALSE;
if (continueWhile) {
temperature = deltaT * temperature;
for (i = fNEps-1; i >= 1; --i) diffFCN[i] = diffFCN[i - 1];
for (i = 0; i < npar; ++i) xPars[i] = bestParameters[i];
retFCN = maxFCN;
printf( "new temp: %g --> maxFCN: %f10.10\n" , temperature, maxFCN );
}
}
for (i = 0; i < npar; i++ ) parameters[i] = bestParameters[i];
return - maxFCN;
}
Double_t TMVA::SimulatedAnnealingBase::GetPerturbationProbability( Double_t E, Double_t Eref,
Double_t temperature )
{
return (temperature > 0) ? TMath::Exp( (E - Eref)/temperature ) : 0;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.