FOX/ObjCryst++  1.10.X (development)
Simplex.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /* Simplex.cpp
20 * source file for Conjugate Gradient Algorithm object
21 *
22 */
23 #include "ObjCryst/RefinableObj/Simplex.h"
24 #include "ObjCryst/Quirks/VFNStreamFormat.h"
25 
26 namespace ObjCryst
27 {
28 SimplexObj::SimplexObj(const string name):
29 OptimizationObj(name)
30 {
31 }
32 void SimplexObj::Optimize(long &nbSteps,const bool silent,const REAL finalcost,
33  const REAL maxTime)
34 {
35  VFN_DEBUG_ENTRY("SimplexObj::Optimize()",10)
36  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).BeginOptimization(true);
37  this->PrepareRefParList();
38  const unsigned long n=mRefParList.GetNbParNotFixed();
39  // Create the n+1 set of parameters (n+1 vertices for the initial simplex)
40  // To obtain the n new vertices we just move from the starting point
41  // by the amount of the declared global optimization step.
42  CrystVector_long vIndex(n+1);
43  vIndex(0)=mRefParList.CreateParamSet();
44  CrystVector_REAL vLLK(n+1);
45  vLLK(0)=this->GetLogLikelihood();
46  for(unsigned long i=0;i<n;i++)
47  {
48  vIndex(0)=mRefParList.CreateParamSet();
51  vIndex(i+1)=mRefParList.CreateParamSet();
52  vLLK(i+1)=this->GetLogLikelihood();
53  mRefParList.RestoreParamSet(vIndex(0));
54  }
55  unsigned long best=0,worst=0,nextworst=0;
56  for(;nbSteps>=0;--nbSteps)
57  {
58  // determine best, worst and next worst points
59  if(vLLK(0)>vLLK(1)){worst=0;nextworst=1;}
60  else{worst=1;nextworst=0;}
61  for(unsigned long i=1;i<=n;i++)
62  {
63  if(vLLK(i)<=vLLK(best)) best =i;
64  if(vLLK(i)>vLLK(worst))
65  {
66  nextworst=worst;
67  worst=i;
68  }
69  else if((vLLK(i)>vLLK(nextworst)) && (i!=worst)) nextworst=i;
70  }
71  {
72  CrystVector_REAL center(n);
73  center = 0.0;
74  for(unsigned long i=0;i<=n;i++)
75  {
76  if(i==worst) continue;
77  center += mRefParList.GetParamSet(vIndex(i));
78  }
79  center /= (REAL)n;
80  CrystVector_REAL worstdiff;
81  worstdiff=mRefParList.GetParamSet(vIndex(worst));
82  worstdiff-=center;
83  for(unsigned long i=0;i<n;i++) worstdiff(i)/=mRefParList.GetParNotFixed(i).GetGlobalOptimStep();
84 
85  if(!silent && (nbSteps%100==0)) cout<<"Simplex:cycle="<<nbSteps<<", cost="<<vLLK(best)
86  <<",best="<<best<<",worst="<<worst<<",nextworst="<<nextworst
87  <<", Worst diff="<<abs(worstdiff.min())+abs(worstdiff.max())<<endl;
88  if((abs(worstdiff.min())+abs(worstdiff.max()))<0.01) break;
89  }
90  #if 0
91  cout<<FormatHorizVector<REAL>(vLLK)<<endl;
92  cout<<FormatVertVector<REAL>(mRefParList.GetParamSet(vIndex(best)),
93  mRefParList.GetParamSet(vIndex(worst)),
94  mRefParList.GetParamSet(vIndex(nextworst)),
95  mRefParList.GetParamSet(vIndex(6)),
96  mRefParList.GetParamSet(vIndex(8)),
97  mRefParList.GetParamSet(vIndex(10)))<<endl;
98  #endif
99  mRefParList.RestoreParamSet(vIndex(best));
100  REAL llktry=this->GenerateNewSimplexConfiguration(vLLK,vIndex,worst,-1.0);
101  if(llktry<=vLLK(best))
102  llktry=this->GenerateNewSimplexConfiguration(vLLK,vIndex,worst,2.0);
103  else if(llktry>=vLLK(nextworst))
104  {
105  const REAL llksave=vLLK(worst);
106  llktry=this->GenerateNewSimplexConfiguration(vLLK,vIndex,worst,0.5);
107  if(llktry>=llksave)
108  {
109  CrystVector_REAL *p0=&(mRefParList.GetParamSet(vIndex(best)));
110  for(unsigned long i=0;i<=n;i++)
111  {
112  if(i==best) continue;
113  CrystVector_REAL *pi=&(mRefParList.GetParamSet(vIndex(i)));
114  for(unsigned long j=0;j<n;j++)
115  {(*pi)(j) = 0.5*((*p0)(j) + (*pi)(j));}
116  mRefParList.RestoreParamSet(vIndex(i));
117  vLLK(i)=this->GetLogLikelihood();
118  }
119  }
120  }
121  }
122  mRefParList.RestoreParamSet(vIndex(best));
124  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).EndOptimization();
125  VFN_DEBUG_EXIT("SimplexObj::Optimize()",10)
126 }
127 void SimplexObj::MultiRunOptimize(long &nbCycle,long &nbSteps,const bool silent,
128  const REAL finalcost,const REAL maxTime)
129 {
130  const long nbStep0=nbSteps;
131  while(nbCycle--!=0)
132  {
133  if(!silent) cout <<"SimplexObj::MultiRunOptimize: Starting Run#"<<abs(float(nbCycle))<<endl;
134  nbSteps=nbStep0;
135  this->Optimize(nbSteps,silent,finalcost,maxTime);
136  if(!silent) cout <<"SimplexObj::MultiRunOptimize: Finished Run#"<<abs(float(nbCycle))<<endl;
137  }
138 }
139 void SimplexObj::XMLOutput(ostream &os,int indent)const
140 {
141 }
142 void SimplexObj::XMLInput(istream &is,const XMLCrystTag &tag)
143 {
144 }
146  CrystVector_long &vIndex,
147  unsigned long worst,
148  REAL f)
149 {
150  // Compute center of vertices
151  const unsigned long n=mRefParList.GetNbParNotFixed();
152  const unsigned long iworst=vIndex(worst);
153  CrystVector_REAL center(n);
154  center = 0.0;
155  for(unsigned long i=0;i<=n;i++)
156  {
157  if(i==worst) continue;
158  center += mRefParList.GetParamSet(vIndex(i));
159  }
160  center /= (REAL)n;
161  for(unsigned long i=0;i<n;i++)
162  {
164  .MutateTo(center(i)+f*(mRefParList.GetParamSet(iworst)(i)-center(i)));
165  }
166  const REAL llk=this->GetLogLikelihood();
167  //cout<<"New,f="<<f<<",worst="<<worst<<":"<<llk<<endl;
168  if(llk<vLLK(worst))
169  {
170  vLLK(worst)=llk;
171  mRefParList.SaveParamSet(iworst);
172  }
173  return llk;
174 }
175 #ifdef __WX__CRYST__
176 WXCrystObjBasic* SimplexObj::WXCreate(wxWindow*)
177 {
178  return NULL;
179 }
180 WXOptimizationObj* SimplexObj::WXGet()
181 {
182  return NULL;
183 }
184 void SimplexObj::WXDelete(){}
185 void SimplexObj::WXNotifyDelete(){}
186 #endif
187 }//namespace
virtual void MultiRunOptimize(long &nbCycle, long &nbSteps, const bool silent=false, const REAL finalcost=0, const REAL maxTime=-1)
Launch optimization for multiple runs of N steps.
Definition: Simplex.cpp:127
void SaveParamSet(const unsigned long id) const
Save the current set of refined values over a previously-created set of saved values.
virtual void Optimize(long &nbSteps, const bool silent=false, const REAL finalcost=0, const REAL maxTime=-1)
Launch optimization (a single run) for N steps.
Definition: Simplex.cpp:32
const CrystVector_REAL & GetParamSet(const unsigned long setId) const
Access one save refpar set.
RefinablePar & GetParNotFixed(const long i)
Access all parameters in the order they were inputted, skipping fixed parameters. ...
long GetNbParNotFixed() const
Total number of non-fixed parameters. Is initialized by PrepareForRefinement()
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:127
const void EraseAllParamSet()
Erase all saved refpar sets.
void RestoreParamSet(const unsigned long id)
Restore a saved set of values.
RefinableObj mRefParList
The refinable par list used during refinement.
virtual void XMLOutput(ostream &os, int indent=0) const
Output a description of the object in XML format to a stream.
Definition: Simplex.cpp:139
ObjRegistry< RefinableObj > mRefinedObjList
The refined objects.
void MutateTo(const REAL newValue)
Change the current value to the given one.
Base object for Optimization methods.
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
REAL GetGlobalOptimStep() const
Maximum step to use during Global Optimization algorithms.
SimplexObj(const string name="Unnamed Simplex Object")
Constructor.
Definition: Simplex.cpp:28
class to input or output a well-formatted xml beginning or ending tag.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input in XML format from a stream, restoring the set of refined objects and the associated cost funct...
Definition: Simplex.cpp:142
unsigned long CreateParamSet(const string name="") const
Save the current set of refined values in a new set.
REAL GenerateNewSimplexConfiguration(CrystVector_REAL &vLLK, CrystVector_long &vIndex, unsigned long worst, REAL f)
Try a new configuration by expanding the worst vertex from the center by a factor f...
Definition: Simplex.cpp:145
virtual REAL GetLogLikelihood() const
The optimized (minimized, actually) function.