• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisiond5b846f87409da25db9520322b2640389622bb03 (tree)
Time2014-01-11 03:44:51
Authorktns <ktns@1136...>
Commiterktns

Log Message

Refactor BFGS::SearchMinimum using BFGSState. #32881

git-svn-id: https://svn.sourceforge.jp/svnroot/molds/branches/refactor_opt@1638 1136aad2-a195-0410-b898-f5ea1d11b9d8

Change Summary

Incremental Difference

--- a/src/optimization/BFGS.cpp
+++ b/src/optimization/BFGS.cpp
@@ -52,11 +52,35 @@ using namespace MolDS_base;
5252 using namespace MolDS_base_atoms;
5353
5454 namespace MolDS_optimization{
55+
56+BFGS::BFGSState::BFGSState(Molecule& molecule):
57+ matrixHessian(NULL),
58+ matrixOldForce(NULL),
59+ matrixStep(NULL),
60+ matrixOldCoordinates(NULL),
61+ matrixDisplacement(NULL),
62+ numAtoms(molecule.GetAtomVect().size())
63+{
64+ const int dimension = numAtoms * CartesianType_end;
65+ MallocerFreer::GetInstance()->Malloc(&this->matrixHessian, dimension, dimension);
66+ MallocerFreer::GetInstance()->Malloc(&this->matrixOldForce, this->numAtoms, CartesianType_end);
67+ MallocerFreer::GetInstance()->Malloc(&this->matrixStep, this->numAtoms, CartesianType_end);
68+ MallocerFreer::GetInstance()->Malloc(&this->matrixOldCoordinates, this->numAtoms, CartesianType_end);
69+ MallocerFreer::GetInstance()->Malloc(&this->matrixDisplacement, this->numAtoms, CartesianType_end);
70+}
71+BFGS::BFGSState::~BFGSState(){
72+ const int dimension = numAtoms * CartesianType_end;
73+ MallocerFreer::GetInstance()->Free(&this->matrixHessian, dimension, dimension);
74+ MallocerFreer::GetInstance()->Free(&this->matrixOldForce, this->numAtoms, CartesianType_end);
75+ MallocerFreer::GetInstance()->Free(&this->matrixStep, this->numAtoms, CartesianType_end);
76+ MallocerFreer::GetInstance()->Free(&this->matrixOldCoordinates, this->numAtoms, CartesianType_end);
77+ MallocerFreer::GetInstance()->Free(&this->matrixDisplacement, this->numAtoms, CartesianType_end);
78+}
79+
5580 BFGS::BFGS(){
5681 this->SetMessages();
5782 //this->OutputLog("BFGS created\n");
5883 }
59-
6084 BFGS::~BFGS(){
6185 //this->OutputLog("BFGS deleted\n");
6286 }
@@ -110,129 +134,98 @@ void BFGS::SearchMinimum(boost::shared_ptr<ElectronicStructure> electronicStruct
110134 int totalSteps = Parameters::GetInstance()->GetTotalStepsOptimization();
111135 double maxGradientThreshold = Parameters::GetInstance()->GetMaxGradientOptimization();
112136 double rmsGradientThreshold = Parameters::GetInstance()->GetRmsGradientOptimization();
113- double lineSearchCurrentEnergy = 0.0;
114- double lineSearchInitialEnergy = 0.0;
115- double const* const* matrixForce = NULL;
116- double const* vectorForce = NULL;
117137 const int dimension = molecule.GetAtomVect().size()*CartesianType_end;
118- double** matrixHessian = NULL;
119- double* vectorOldForce = NULL;
120- double* vectorStep = NULL;
121- double** matrixStep = NULL;
122- double** matrixOldCoordinates = NULL;
123- double* vectorOldCoordinates = NULL;
124- double** matrixDisplacement = NULL;
125138 double trustRadius = Parameters::GetInstance()->GetInitialTrustRadiusOptimization();
126139 const double maxNormStep = Parameters::GetInstance()->GetMaxNormStepOptimization();
140+ BFGSState state(molecule);
127141
128- try{
129- // initialize Hessian with unit matrix
130- MallocerFreer::GetInstance()->Malloc(&matrixHessian, dimension, dimension);
131- const double one = 1;
132- MolDS_wrappers::Blas::GetInstance()->Dcopy(dimension, &one, 0, &matrixHessian[0][0], dimension+1);
133-
134- // initial calculation
135- bool requireGuess = true;
136- this->UpdateElectronicStructure(electronicStructure, molecule, requireGuess, this->CanOutputLogs());
137- lineSearchCurrentEnergy = electronicStructure->GetElectronicEnergy(elecState);
138-
139- requireGuess = false;
140- matrixForce = electronicStructure->GetForce(elecState);
141- vectorForce = &matrixForce[0][0];
142-
143- for(int s=0; s<totalSteps; s++){
144- this->OutputLog(boost::format("%s%d\n\n") % this->messageStartBFGSStep % (s+1));
145-
146- // Store old Force data
147- MallocerFreer::GetInstance()->Malloc(&vectorOldForce, dimension);
148- MolDS_wrappers::Blas::GetInstance()->Dcopy(dimension,
149- static_cast<double const*>(vectorForce),
150- vectorOldForce);
151-
152- this->StoreMolecularGeometry(matrixOldCoordinates, molecule);
153-
154- // Level shift Hessian redundant modes
155- this->ShiftHessianRedundantMode(matrixHessian, molecule);
156-
157- // Limit the trustRadius to maxNormStep
158- trustRadius=min(trustRadius,maxNormStep);
159-
160- //Calculate RFO step
161- MallocerFreer::GetInstance()->Malloc(&matrixStep, molecule.GetAtomVect().size(), CartesianType_end);
162- vectorStep = &matrixStep[0][0];
163- this->CalcRFOStep(vectorStep, matrixHessian, vectorForce, trustRadius, dimension);
164-
165- double approximateChange = this->ApproximateEnergyChange(dimension, matrixHessian, vectorForce, vectorStep);
166-
167- // Take a RFO step
168- bool doLineSearch = false;
169- bool tempCanOutputLogs = false;
170- lineSearchInitialEnergy = lineSearchCurrentEnergy;
171- if(doLineSearch){
172- this->LineSearch(electronicStructure, molecule, lineSearchCurrentEnergy, matrixStep, elecState, dt);
173- }
174- else{
175- this->UpdateMolecularCoordinates(molecule, matrixStep);
142+ // initialize Hessian with unit matrix
143+ const double one = 1;
144+ MolDS_wrappers::Blas::GetInstance()->Dcopy(dimension, &one, 0, &state.GetMatrixHessian()[0][0], dimension+1);
176145
177- // Broadcast to all processes
178- int root = MolDS_mpi::MpiProcess::GetInstance()->GetHeadRank();
179- molecule.BroadcastConfigurationToAllProcesses(root);
146+ // initial calculation
147+ bool requireGuess = true;
148+ this->UpdateElectronicStructure(electronicStructure, molecule, requireGuess, this->CanOutputLogs());
149+ state.SetCurrentEnergy(electronicStructure->GetElectronicEnergy(elecState));
180150
181- this->UpdateElectronicStructure(electronicStructure, molecule, requireGuess, tempCanOutputLogs);
182- lineSearchCurrentEnergy = electronicStructure->GetElectronicEnergy(elecState);
183- }
184- this->OutputMoleculeElectronicStructure(electronicStructure, molecule, this->CanOutputLogs());
185-
186- this->UpdateTrustRadius(trustRadius, approximateChange, lineSearchInitialEnergy, lineSearchCurrentEnergy);
187-
188- // check convergence
189- if(this->SatisfiesConvergenceCriterion(matrixForce,
190- molecule,
191- lineSearchInitialEnergy,
192- lineSearchCurrentEnergy,
193- maxGradientThreshold,
194- rmsGradientThreshold)){
195- *obtainesOptimizedStructure = true;
196- break;
197- }
151+ requireGuess = false;
152+ state.SetMatrixForce(electronicStructure->GetForce(elecState));
198153
199- //Calculate displacement (K_k at Eq. (15) in [SJTO_1983])
200- this->CalcDisplacement(matrixDisplacement, matrixOldCoordinates, molecule);
154+ for(int s=0; s<totalSteps; s++){
155+ this->OutputLog(boost::format("%s%d\n\n") % this->messageStartBFGSStep % (s+1));
201156
202- //Rollback geometry and energy if energy increases
203- bool isHillClimbing = lineSearchCurrentEnergy > lineSearchInitialEnergy;
204- if(isHillClimbing){
205- this->OutputLog(this->messageHillClimbing);
206- this->RollbackMolecularGeometry(molecule, matrixOldCoordinates);
207- lineSearchCurrentEnergy = lineSearchInitialEnergy;
208- }
157+ // Store old Force data
158+ MolDS_wrappers::Blas::GetInstance()->Dcopy(dimension,
159+ static_cast<double const*>(state.GetVectorForce()),
160+ state.GetVectorOldForce());
209161
210- matrixForce = electronicStructure->GetForce(elecState);
211- vectorForce = &matrixForce[0][0];
162+ this->StoreMolecularGeometry(state.GetMatrixOldCoordinatesRef(), molecule);
212163
213- // Update Hessian
214- this->UpdateHessian(matrixHessian, dimension, vectorForce, vectorOldForce, &matrixDisplacement[0][0]);
164+ // Level shift Hessian redundant modes
165+ this->ShiftHessianRedundantMode(state.GetMatrixHessian(), molecule);
215166
216- //Rollback gradient if energy increases
217- if(isHillClimbing){
218- vectorForce = vectorOldForce;
219- }
167+ // Limit the trustRadius to maxNormStep
168+ trustRadius=min(trustRadius,maxNormStep);
169+
170+ //Calculate RFO step
171+ this->CalcRFOStep(state.GetVectorStep(), state.GetMatrixHessian(), state.GetVectorForce(), trustRadius, dimension);
172+
173+ double approximateChange = this->ApproximateEnergyChange(dimension, state.GetMatrixHessian(), state.GetVectorForce(), state.GetVectorStep());
174+
175+ // Take a RFO step
176+ bool doLineSearch = false;
177+ bool tempCanOutputLogs = false;
178+ state.SetInitialEnergy(state.GetCurrentEnergy());
179+ if(doLineSearch){
180+ this->LineSearch(electronicStructure, molecule, state.GetCurrentEnergyRef(), state.GetMatrixStep(), elecState, dt);
181+ }
182+ else{
183+ this->UpdateMolecularCoordinates(molecule, state.GetMatrixStep());
184+
185+ // Broadcast to all processes
186+ int root = MolDS_mpi::MpiProcess::GetInstance()->GetHeadRank();
187+ molecule.BroadcastConfigurationToAllProcesses(root);
188+
189+ this->UpdateElectronicStructure(electronicStructure, molecule, requireGuess, tempCanOutputLogs);
190+ state.SetCurrentEnergy(electronicStructure->GetElectronicEnergy(elecState));
191+ }
192+ this->OutputMoleculeElectronicStructure(electronicStructure, molecule, this->CanOutputLogs());
193+
194+ this->UpdateTrustRadius(trustRadius, approximateChange, state.GetInitialEnergy(), state.GetCurrentEnergy());
195+
196+ // check convergence
197+ if(this->SatisfiesConvergenceCriterion(state.GetMatrixForce(),
198+ molecule,
199+ state.GetInitialEnergy(),
200+ state.GetCurrentEnergy(),
201+ maxGradientThreshold,
202+ rmsGradientThreshold)){
203+ *obtainesOptimizedStructure = true;
204+ break;
205+ }
206+
207+ //Calculate displacement (K_k at Eq. (15) in [SJTO_1983])
208+ this->CalcDisplacement(state.GetMatrixDisplacement(), state.GetMatrixOldCoordinates(), molecule);
209+
210+ //Rollback geometry and energy if energy increases
211+ bool isHillClimbing = state.GetCurrentEnergy() > state.GetInitialEnergy();
212+ if(isHillClimbing){
213+ this->OutputLog(this->messageHillClimbing);
214+ this->RollbackMolecularGeometry(molecule, state.GetMatrixOldCoordinates());
215+ state.SetCurrentEnergy(state.GetInitialEnergy());
216+ }
217+
218+ state.SetMatrixForce(electronicStructure->GetForce(elecState));
219+
220+ // Update Hessian
221+ this->UpdateHessian(state.GetMatrixHessian(), dimension, state.GetVectorForce(), state.GetVectorOldForce(), &state.GetMatrixDisplacement()[0][0]);
222+
223+ //Rollback gradient if energy increases
224+ if(isHillClimbing){
225+ state.SetMatrixForce(state.GetMatrixOldForce());
220226 }
221- *lineSearchedEnergy = lineSearchCurrentEnergy;
222- }
223- catch(MolDSException ex){
224- MallocerFreer::GetInstance()->Free(&matrixHessian, dimension, dimension);
225- MallocerFreer::GetInstance()->Free(&vectorOldForce, dimension);
226- MallocerFreer::GetInstance()->Free(&matrixStep, molecule.GetAtomVect().size(), CartesianType_end);
227- MallocerFreer::GetInstance()->Free(&matrixDisplacement, molecule.GetAtomVect().size(), CartesianType_end);
228- MallocerFreer::GetInstance()->Free(&matrixOldCoordinates, molecule.GetAtomVect().size(), CartesianType_end);
229- throw ex;
230227 }
231- MallocerFreer::GetInstance()->Free(&matrixHessian, dimension, dimension);
232- MallocerFreer::GetInstance()->Free(&vectorOldForce, dimension);
233- MallocerFreer::GetInstance()->Free(&matrixStep, molecule.GetAtomVect().size(), CartesianType_end);
234- MallocerFreer::GetInstance()->Free(&matrixDisplacement, molecule.GetAtomVect().size(), CartesianType_end);
235- MallocerFreer::GetInstance()->Free(&matrixOldCoordinates, molecule.GetAtomVect().size(), CartesianType_end);
228+ *lineSearchedEnergy = state.GetCurrentEnergy();
236229 }
237230
238231 void BFGS::CalcRFOStep(double* vectorStep,
@@ -566,11 +559,10 @@ void BFGS::RollbackMolecularGeometry(MolDS_base::Molecule& molecule,
566559 molecule.SetCanOutputLogs(tempCanOutputLogs);
567560 }
568561
569-void BFGS::CalcDisplacement(double * *& matrixDisplacement,
570- double const* const* matrixOldCoordinates,
562+void BFGS::CalcDisplacement(double * * matrixDisplacement,
563+ double const* const* matrixOldCoordinates,
571564 const MolDS_base::Molecule& molecule)const{
572565 //Calculate displacement (K_k at Eq. (15) in [SJTO_1983])
573- MallocerFreer::GetInstance()->Malloc(&matrixDisplacement, molecule.GetAtomVect().size(), CartesianType_end);
574566 for(int i=0;i<molecule.GetAtomVect().size();i++){
575567 const Atom* atom = molecule.GetAtomVect()[i];
576568 const double* xyz = atom->GetXyz();
--- a/src/optimization/BFGS.h
+++ b/src/optimization/BFGS.h
@@ -22,6 +22,33 @@
2222 namespace MolDS_optimization{
2323
2424 class BFGS : public MolDS_optimization::Optimizer{
25+private:
26+ class BFGSState: public OptimizerState{
27+ protected:
28+ double** matrixHessian;
29+ double** matrixOldForce;
30+ double** matrixStep;
31+ double** matrixOldCoordinates;
32+ double* vectorOldCoordinates;
33+ double** matrixDisplacement;
34+ size_t numAtoms;
35+ private:
36+ template<class vector>
37+ vector Matrix2Vector(vector const* matrix){return matrix == NULL ? NULL : &matrix[0][0];}
38+ public:
39+ BFGSState(MolDS_base::Molecule& molecule);
40+ virtual ~BFGSState();
41+ double const* GetVectorForce (){return this->Matrix2Vector(this->matrixForce);}
42+ double* GetVectorOldForce (){return this->Matrix2Vector(this->matrixOldForce);}
43+ double* GetVectorStep (){return this->Matrix2Vector(this->matrixStep);}
44+ double const* GetVectorOldCoordinates(){return this->Matrix2Vector(this->matrixOldCoordinates);}
45+ double** GetMatrixHessian() {return this->matrixHessian;}
46+ double** GetMatrixOldForce() {return this->matrixOldForce;}
47+ double** GetMatrixStep() {return this->matrixStep;}
48+ double** GetMatrixOldCoordinates() {return this->matrixOldCoordinates;}
49+ double**& GetMatrixOldCoordinatesRef(){return this->matrixOldCoordinates;}
50+ double** GetMatrixDisplacement() {return this->matrixDisplacement;}
51+ };
2552 public:
2653 BFGS();
2754 ~BFGS();
@@ -56,8 +83,8 @@ protected:
5683 double const* vectorForce,
5784 const double maxNormStep,
5885 const int dimension) const;
59- void CalcDisplacement(double * *& matrixDisplacement,
60- double const* const* matrixOldCoordinates,
86+ void CalcDisplacement(double * * matrixDisplacement,
87+ double const* const* matrixOldCoordinates,
6188 const MolDS_base::Molecule& molecule)const;
6289 void UpdateHessian(double** matrixHessian,
6390 const int dimension,
--- a/src/optimization/Optimizer.h
+++ b/src/optimization/Optimizer.h
@@ -24,7 +24,7 @@ namespace MolDS_optimization{
2424 class Optimizer : public MolDS_base::PrintController{
2525 protected:
2626 class OptimizerState{
27- private:
27+ protected:
2828 double currentEnergy;
2929 double initialEnergy;
3030 double const* const* matrixForce;