00001
00002
00004
00005 #include "VariableStepsizeAnnealMinimizer.h"
00006
00008
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
00028
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
00081 m_iNMCSteps = m_iNMCSteps*1.15;
00082
00083
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
00099 m_iNMCSteps = 100;
00100
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
00107
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
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
00141 double normE = m_dECurrent/m_dTemperature;
00142 double Ai = m_dDeltaX*((m_dC*normE + 1.0)/(normE + 1.0));
00143
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 }