Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

VariableStepsizeAnnealMinimizer.cpp

Go to the documentation of this file.
00001 // VariableStepsizeAnnealMinimizer.cpp: implementation of the CVariableStepsizeAnnealMinimizer class.
00002 //
00004 
00005 #include "VariableStepsizeAnnealMinimizer.h"
00006 
00008 // Construction/Destruction
00010 
00011 CVariableStepsizeAnnealMinimizer::CVariableStepsizeAnnealMinimizer(int RNGSeed, CParameterFilter *pFilter, double T0, double lambda, double deltaX, double c)
00012 :CSimulatedAnnealingStrategy(RNGSeed,pFilter)
00013 {
00014         m_dTemperature = T0;
00015         m_dLambda = lambda;
00016         m_dDeltaX = deltaX;
00017         m_dC = c;
00018 }
00019 
00020 CVariableStepsizeAnnealMinimizer::~CVariableStepsizeAnnealMinimizer()
00021 {
00022 
00023 }
00024 
00025 bool CVariableStepsizeAnnealMinimizer::AcceptMove(double Eold, double Enew)
00026 {
00027         // probability has less simple form b/c of detailed balance correction
00028         // forced by shifting stepsize
00029         double normE = Enew/m_dTemperature;
00030         double Af = m_dDeltaX*((m_dC*normE + 1.0)/(normE + 1.0));
00031         normE = Eold/m_dTemperature;
00032         double Ai = m_dDeltaX*((m_dC*normE + 1.0)/(normE + 1.0));
00033         
00034         double logprob = -(Enew - Eold)/m_dTemperature;
00035         logprob += nParameters*log(Ai/Af);
00036         logprob -= 0.5*m_dSqrLogParDiff*(1.0/(Af*Af) - 1.0/(Ai*Ai));
00037 
00038         if(exp(logprob) > 1.0)
00039         {
00040                 return true;
00041         }
00042         else if(m_pRNG->uniform() < exp(logprob))
00043         {
00044                 return true;    
00045         }
00046 
00047         return false;
00048 }
00049 
00050 bool CVariableStepsizeAnnealMinimizer::Terminate()
00051 {
00052         double Ebar = this->GetEBar();
00053         double ratio = (Ebar - m_dEBest)/Ebar;
00054 
00055         if(ratio < 1.0e-03)
00056         {
00057                 return true;
00058         }
00059         
00060         return false;
00061 }
00062 
00063 bool CVariableStepsizeAnnealMinimizer::Equilibrated()
00064 {
00065         if(m_iTrialCount > m_iNMCSteps)
00066         {
00067                 return true;
00068         }
00069 
00070         return false;
00071 }
00072 
00073 void CVariableStepsizeAnnealMinimizer::Cool()
00074 {
00075         
00076         double sigma = this->GetE2Bar() - (this->GetEBar())*(this->GetEBar());
00077         double expFac = -(m_dLambda*m_dTemperature)/sigma;
00078         m_dTemperature = m_dTemperature*exp(expFac);
00079         
00080         // increase the number of MC steps as we cool
00081         m_iNMCSteps = m_iNMCSteps*1.15;
00082 
00083         // write the best (temporary) parameters to a file and stdout
00084         fstream *pfbest = new fstream("satemp.par",ios::out);
00085         *pfbest << "##################################################################" << endl;
00086         *pfbest << "# BEST PARAMETERS (PARTIAL)" << endl;
00087         *pfbest << "##################################################################" << endl;
00088         for(int i = 0; i < nParameters; i++)
00089         {
00090                 *pfbest << m_pdCurrentParameters[i] << endl;
00091         }
00092         delete pfbest;
00093 
00094 }
00095 
00096 void CVariableStepsizeAnnealMinimizer::InitializeTemperature(Minimizable *minimizable)
00097 {
00098         // set number of equilibration steps
00099         m_iNMCSteps = 100;
00100         // save starting parameters
00101         double *savepar = new double[nParameters];
00102         m_pMO->ElementCopy(m_pdCurrentParameters,savepar,nParameters);
00103         double Eold = minimizable->ObjectiveFunction(m_pdCurrentParameters);
00104         double tempT = m_dTemperature;
00105 
00106         // run 50 steps and check the acceptance ratio, then increase
00107         // T if A < 0.8
00108         while(m_dAcceptanceRatio < 0.8)
00109         {
00110                 m_dAcceptanceRatio = 0.0;
00111                 m_dTemperature = tempT;
00112                 for(int i = 0; i < 50; i++)
00113                 {
00114                         this->GenerateMove();
00115                         double Enew = minimizable->ObjectiveFunction(m_pdTrialParameters);
00116 
00117                         if(this->AcceptMove(Eold,Enew))
00118                         {                       
00119                                 Eold = Enew;
00120                                 m_dAcceptanceRatio += 1.0;
00121                                 m_pMO->ElementCopy(m_pdTrialParameters,m_pdCurrentParameters,nParameters);
00122                         }
00123                 }
00124                 m_dAcceptanceRatio = m_dAcceptanceRatio/50;
00125                 tempT = tempT*1.5;
00126         }
00127         // restore original parameters
00128         m_pMO->ElementCopy(savepar,m_pdCurrentParameters,nParameters);
00129         
00130         cout << "T0 = " << m_dTemperature << endl;
00131         
00132         delete [] savepar;
00133         
00134         return;
00135 }
00136 
00137 void CVariableStepsizeAnnealMinimizer::GenerateMove()
00138 {
00139         m_dSqrLogParDiff = 0.0;
00140         // compute the stepsize
00141         double normE = m_dECurrent/m_dTemperature;
00142         double Ai = m_dDeltaX*((m_dC*normE + 1.0)/(normE + 1.0));
00143         // now take a step w/ std dev. Ai
00144         m_pFilter->ForwardTransformation(m_pdCurrentParameters,nParameters);
00145         for(int i = 0; i < nParameters; i++)
00146         {
00147                 double delta = m_pRNG->gaussian(Ai);
00148                 m_pdTrialParameters[i] = m_pdCurrentParameters[i] + delta;
00149                 m_dSqrLogParDiff += delta*delta;
00150         }
00151         m_pFilter->BackwardTransformation(m_pdTrialParameters,nParameters);
00152         m_pFilter->BackwardTransformation(m_pdCurrentParameters,nParameters);
00153 }

Generated on Mon Nov 3 09:38:20 2003 by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002