FOX/ObjCryst++  2022
GlobalOptimObj.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 /*
20 * source file for Global Optimization Objects
21 *
22 */
23 #include <iomanip>
24 
25 #include "ObjCryst/RefinableObj/GlobalOptimObj.h"
26 #include "ObjCryst/ObjCryst/Crystal.h"
27 #include "ObjCryst/Quirks/VFNStreamFormat.h"
28 #include "ObjCryst/Quirks/VFNDebug.h"
29 #include "ObjCryst/Quirks/Chronometer.h"
30 #include "ObjCryst/ObjCryst/IO.h"
31 #include "ObjCryst/RefinableObj/LSQNumObj.h"
32 
33 #include "ObjCryst/ObjCryst/Molecule.h"
34 
35 #ifdef __WX__CRYST__
36  #include "ObjCryst/wxCryst/wxRefinableObj.h"
37  #undef GetClassName // Conflict from wxMSW headers ? (cygwin)
38 #endif
39 
40 //For some reason, with wxWindows this must be placed after wx headers (Borland c++)
41 #include <fstream>
42 #include <sstream>
43 #include <stdio.h>
44 #include <boost/format.hpp>
45 
46 namespace ObjCryst
47 {
48 void CompareWorlds(const CrystVector_long &idx,const CrystVector_long &swap, const RefinableObj &obj)
49 {
50  const long nb=swap.numElements();
51  const CrystVector_REAL *pv0=&(obj.GetParamSet(idx(swap(nb-1))));
52  for(long i=0;i<idx.numElements();++i)
53  {
54  REAL d=0.0;
55  const CrystVector_REAL *pv1=&(obj.GetParamSet(idx(swap(i))));
56  for(long j=0;j<pv0->numElements();++j) d += ((*pv0)(j)-(*pv1)(j))*((*pv0)(j)-(*pv1)(j));
57  cout<<"d("<<i<<")="<<sqrt(d)<<endl;
58  }
59  cout<<endl;
60 }
61 //#################################################################################
62 //
63 // OptimizationObj
64 //
65 //#################################################################################
66 ObjRegistry<OptimizationObj> gOptimizationObjRegistry("List of all Optimization objects");
67 
69 mName(""),mSaveFileName("GlobalOptim.save"),
70 mNbTrialPerRun(10000000),mNbTrial(0),mRun(0),mBestCost(-1),
71 mBestParSavedSetIndex(-1),
72 mContext(0),
73 mIsOptimizing(false),mStopAfterCycle(false),
74 mRefinedObjList("OptimizationObj: "+mName+" RefinableObj registry"),
75 mRecursiveRefinedObjList("OptimizationObj: "+mName+" recursive RefinableObj registry"),
76 mLastOptimTime(0)
77 {
78  VFN_DEBUG_ENTRY("OptimizationObj::OptimizationObj()",5)
79  // This must be done in a real class to avoid calling a pure virtual method
80  // if a graphical representation is automatically called upon registration.
81  // gOptimizationObjRegistry.Register(*this);
82 
83  static bool need_initRandomSeed=true;
84  if(need_initRandomSeed==true)
85  {
86  srand(time(NULL));
87  need_initRandomSeed=false;
88  }
89  // We only copy parameters, so do not delete them !
91  VFN_DEBUG_EXIT("OptimizationObj::OptimizationObj()",5)
92 }
93 
95 mName(name),mSaveFileName("GlobalOptim.save"),
96 mNbTrialPerRun(10000000),mNbTrial(0),mRun(0),mBestCost(-1),
97 mBestParSavedSetIndex(-1),
98 mContext(0),
99 mIsOptimizing(false),mStopAfterCycle(false),
100 mRefinedObjList("OptimizationObj: "+mName+" RefinableObj registry"),
101 mRecursiveRefinedObjList("OptimizationObj: "+mName+" recursive RefinableObj registry"),
102 mLastOptimTime(0)
103 {
104  VFN_DEBUG_ENTRY("OptimizationObj::OptimizationObj()",5)
105  // This must be done in a real class to avoid calling a pure virtual method
106  // if a graphical representation is automatically called upon registration.
107  // gOptimizationObjRegistry.Register(*this);
108 
109  static bool need_initRandomSeed=true;
110  if(need_initRandomSeed==true)
111  {
112  srand(time(NULL));
113  need_initRandomSeed=false;
114  }
115  // We only copy parameters, so do not delete them !
117  VFN_DEBUG_EXIT("OptimizationObj::OptimizationObj()",5)
118 }
119 
121 mName(old.mName),mSaveFileName(old.mSaveFileName),
122 mNbTrialPerRun(old.mNbTrialPerRun),mNbTrial(old.mNbTrial),mRun(old.mRun),mBestCost(old.mBestCost),
123 mBestParSavedSetIndex(-1),
124 mContext(0),
125 mIsOptimizing(false),mStopAfterCycle(false),
126 mRefinedObjList("OptimizationObj: "+mName+" RefinableObj registry"),
127 mRecursiveRefinedObjList("OptimizationObj: "+mName+" recursive RefinableObj registry"),
128 mLastOptimTime(0)
129 {
130  VFN_DEBUG_ENTRY("OptimizationObj::OptimizationObj(&old)",5)
131  // This must be done in a real class to avoid calling a pure virtual method
132  // if a graphical representation is automatically called upon registration.
133  // gOptimizationObjRegistry.Register(*this);
134 
135  static bool need_initRandomSeed=true;
136  if(need_initRandomSeed==true)
137  {
138  srand(time(NULL));
139  need_initRandomSeed=false;
140  }
141  // We only copy parameters, so do not delete them !
143 
144  for(unsigned int i=0;i<old.mRefinedObjList.GetNb();i++)
145  this->AddRefinableObj(old.mRefinedObjList.GetObj(i));
146 
147  VFN_DEBUG_EXIT("OptimizationObj::OptimizationObj(&old)",5)
148 }
149 
151 {
152  VFN_DEBUG_ENTRY("OptimizationObj::~OptimizationObj()",5)
153  gOptimizationObjRegistry.DeRegister(*this);
154  VFN_DEBUG_EXIT("OptimizationObj::~OptimizationObj()",5)
155 }
156 
158 {
159  VFN_DEBUG_ENTRY("OptimizationObj::RandomizeStartingConfig()",5)
160  this->PrepareRefParList();
161  for(int j=0;j<mRefParList.GetNbParNotFixed();j++)
162  {
163  if(true==mRefParList.GetParNotFixed(j).IsLimited())
164  {
165  const REAL min=mRefParList.GetParNotFixed(j).GetMin();
166  const REAL max=mRefParList.GetParNotFixed(j).GetMax();
167  mRefParList.GetParNotFixed(j).MutateTo(min+(max-min)*(rand()/(REAL)RAND_MAX) );
168  }
169  else if(true==mRefParList.GetParNotFixed(j).IsPeriodic())
171  Mutate(mRefParList.GetParNotFixed(j).GetPeriod()*rand()/(REAL)RAND_MAX);
172  }
173  //else cout << mRefParList.GetParNotFixed(j).Name() <<" Not limited :-(" <<endl;
174  VFN_DEBUG_EXIT("OptimizationObj::RandomizeStartingConfig()",5)
175 }
176 
178 {
179  VFN_DEBUG_ENTRY("OptimizationObj::FixAllPar()",5)
180  this->BuildRecursiveRefObjList();
181  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
182  mRecursiveRefinedObjList.GetObj(i).FixAllPar();
183  VFN_DEBUG_EXIT("OptimizationObj::FixAllPar():End",5)
184 }
185 void OptimizationObj::SetParIsFixed(const string& parName,const bool fix)
186 {
187  this->BuildRecursiveRefObjList();
188  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
189  mRecursiveRefinedObjList.GetObj(i).SetParIsFixed(parName,fix);
190 }
191 void OptimizationObj::SetParIsFixed(const RefParType *type,const bool fix)
192 {
193  this->BuildRecursiveRefObjList();
194  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
195  mRecursiveRefinedObjList.GetObj(i).SetParIsFixed(type,fix);
196 }
197 
199 {
200  this->BuildRecursiveRefObjList();
201  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
202  mRecursiveRefinedObjList.GetObj(i).UnFixAllPar();
203 }
204 
205 void OptimizationObj::SetParIsUsed(const string& parName,const bool use)
206 {
207  this->BuildRecursiveRefObjList();
208  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
209  mRecursiveRefinedObjList.GetObj(i).SetParIsUsed(parName,use);
210 }
211 void OptimizationObj::SetParIsUsed(const RefParType *type,const bool use)
212 {
213  this->BuildRecursiveRefObjList();
214  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
215  mRecursiveRefinedObjList.GetObj(i).SetParIsUsed(type,use);
216 }
217 void OptimizationObj::SetLimitsRelative(const string &parName,
218  const REAL min, const REAL max)
219 {
220  this->BuildRecursiveRefObjList();
221  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
222  mRecursiveRefinedObjList.GetObj(i).SetLimitsRelative(parName,min,max);
223 }
225  const REAL min, const REAL max)
226 {
227  this->BuildRecursiveRefObjList();
228  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
229  mRecursiveRefinedObjList.GetObj(i).SetLimitsRelative(type,min,max);
230 }
231 void OptimizationObj::SetLimitsAbsolute(const string &parName,
232  const REAL min, const REAL max)
233 {
234  this->BuildRecursiveRefObjList();
235  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
236  mRecursiveRefinedObjList.GetObj(i).SetLimitsAbsolute(parName,min,max);
237 }
239  const REAL min, const REAL max)
240 {
241  this->BuildRecursiveRefObjList();
242  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
243  mRecursiveRefinedObjList.GetObj(i).SetLimitsAbsolute(type,min,max);
244 }
245 
247 {
248  TAU_PROFILE("OptimizationObj::GetLogLikelihood()","void ()",TAU_DEFAULT);
249  REAL cost =0.;
250  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
251  {
252  const REAL tmp=mRecursiveRefinedObjList.GetObj(i).GetLogLikelihood();
253  if(tmp!=0.)
254  {
256  [&(mRecursiveRefinedObjList.GetObj(i))]);
257  st->mTotalLogLikelihood += tmp;
259  (tmp-st->mLastLogLikelihood)*(tmp-st->mLastLogLikelihood);
260  st->mLastLogLikelihood=tmp;
261  }
262  cost += mvObjWeight[&(mRecursiveRefinedObjList.GetObj(i))].mWeight * tmp;
263  }
264  return cost;
265 }
267 {
268  VFN_DEBUG_MESSAGE("OptimizationObj::StopAfterCycle()",5)
269  if(mIsOptimizing)
270  {
271  #ifdef __WX__CRYST__
272  wxMutexLocker lock(mMutexStopAfterCycle);
273  #endif
274  mStopAfterCycle=true;
275  }
276 }
277 
279 {
280  //:TODO: ask all objects to print their own report ?
281 }
282 
284 {
285  VFN_DEBUG_MESSAGE("OptimizationObj::AddRefinableObj():"<<obj.GetName(),5)
286  //in case some object has been modified, to avoid rebuilding the entire list
287  this->BuildRecursiveRefObjList();
288 
289  mRefinedObjList.Register(obj);
291  #ifdef __WX__CRYST__
292  if(0!=this->WXGet()) this->WXGet()->AddRefinedObject(obj);
293  #endif
294 }
295 
297 {
298  if(rebuild) this->PrepareRefParList();
299  return mRefParList;
300 }
301 
302 const string& OptimizationObj::GetName()const { return mName;}
303 void OptimizationObj::SetName(const string& name) {mName=name;}
304 
305 const string OptimizationObj::GetClassName()const { return "OptimizationObj";}
306 
307 void OptimizationObj::Print()const {this->XMLOutput(cout);}
308 
310 {
311  //:TODO: check list of refinableObj has not changed, and the list of
312  // RefPar has not changed in all sub-objects.
314 }
315 
317 
319 {
320  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
321  mRecursiveRefinedObjList.GetObj(i).TagNewBestConfig();
322  mMainTracker.AppendValues(mNbTrial);
323 }
324 
326 {
327  return mLastOptimTime;
328 }
329 
331 
333 
334 RefObjOpt& OptimizationObj::GetXMLAutoSaveOption() {return mXMLAutoSave;}
335 const RefObjOpt& OptimizationObj::GetXMLAutoSaveOption()const {return mXMLAutoSave;}
336 
337 const REAL& OptimizationObj::GetBestCost()const{return mBestCost;}
339 
340 void OptimizationObj::BeginOptimization(const bool allowApproximations, const bool enableRestraints)
341 {
342  mvContextObjStats.clear();
343  for(int i=0;i<mRefinedObjList.GetNb();i++)
344  {
345  mRefinedObjList.GetObj(i).BeginOptimization(allowApproximations,enableRestraints);
346  }
347 }
348 
350 {
351  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).EndOptimization();
352 }
353 
355 
356 const long& OptimizationObj::NbTrialPerRun() const {return mNbTrialPerRun;}
357 
358 long OptimizationObj::GetTrial() const {return mNbTrial;}
359 
360 long OptimizationObj::GetRun() const {return mRun;}
361 
362 unsigned int OptimizationObj::GetNbOption()const
363 {
364  return mOptionRegistry.GetNb();
365 }
366 
368 {
369  return mOptionRegistry;
370 }
371 
372 RefObjOpt& OptimizationObj::GetOption(const unsigned int i)
373 {
374  VFN_DEBUG_MESSAGE("RefinableObj::GetOption()"<<i,3)
375  //:TODO: Check
376  return mOptionRegistry.GetObj(i);
377 }
378 
380 {
381  VFN_DEBUG_MESSAGE("OptimizationObj::GetOption()"<<name,3)
382  const long i=mOptionRegistry.Find(name);
383  if(i<0)
384  {
385  this->Print();
386  throw ObjCrystException("OptimizationObj::GetOption(): cannot find option: "+name+" in object:"+this->GetName());
387  }
388  return mOptionRegistry.GetObj(i);
389 }
390 
391 const RefObjOpt& OptimizationObj::GetOption(const unsigned int i)const
392 {
393  VFN_DEBUG_MESSAGE("RefinableObj::GetOption()"<<i,3)
394  //:TODO: Check
395  return mOptionRegistry.GetObj(i);
396 }
397 
398 const RefObjOpt& OptimizationObj::GetOption(const string & name)const
399 {
400  VFN_DEBUG_MESSAGE("OptimizationObj::GetOption()"<<name,3)
401  const long i=mOptionRegistry.Find(name);
402  if(i<0)
403  {
404  this->Print();
405  throw ObjCrystException("OptimizationObj::GetOption(): cannot find option: "+name+" in object:"+this->GetName());
406  }
407  return mOptionRegistry.GetObj(i);
408 }
409 
411 {
412  return mRefinedObjList;
413 }
414 
415 unsigned int OptimizationObj::GetNbParamSet() const
416 {
417  return mvSavedParamSet.size();
418 }
419 
420 long OptimizationObj::GetParamSetIndex(const unsigned int i) const
421 {
422  if(i>=mvSavedParamSet.size())
423  throw ObjCrystException("OptimizationObj::GetSavedParamSetIndex(i): i > nb saved param set");
424 
425  return mvSavedParamSet[i].first;
426 }
427 
428 long OptimizationObj::GetParamSetCost(const unsigned int i) const
429 {
430  if(i>=mvSavedParamSet.size())
431  throw ObjCrystException("OptimizationObj::GetSavedParamSetCost(i): i > nb saved param set");
432  return mvSavedParamSet[i].second;
433 }
434 
435 void OptimizationObj::RestoreParamSet(const unsigned int i, const bool update_display)
436 {
438  if(update_display) this->UpdateDisplay();
439 }
440 
442 {
443  VFN_DEBUG_ENTRY("OptimizationObj::PrepareRefParList()",6)
444 
445  this->BuildRecursiveRefObjList();
446  // As any parameter been added in the recursive list of objects ?
447  // or has any object been added/removed ?
448  RefinableObjClock clock;
450  if( (clock>mRefParList.GetRefParListClock())
451  ||(mRecursiveRefinedObjList.GetRegistryClock()>mRefParList.GetRefParListClock()) )
452  {
453  VFN_DEBUG_MESSAGE("OptimizationObj::PrepareRefParList():Rebuild list",6)
456  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
458  mvSavedParamSet.clear();
459  mBestParSavedSetIndex=mRefParList.CreateParamSet("Best Configuration");
460  mvSavedParamSet.push_back(make_pair(mBestParSavedSetIndex,mBestCost));
461 
463 
464  REAL (OptimizationObj::*fl)() const;
467  (this->GetName()+"::Overall LogLikelihood",*this,fl));
468 
469  for(long i=0;i<mRecursiveRefinedObjList.GetNb();i++)
470  {
471  REAL (RefinableObj::*fp)() const;
474  (mRecursiveRefinedObjList.GetObj(i).GetName()+"::LogLikelihood",mRecursiveRefinedObjList.GetObj(i),fp));
475 
476  if(mRecursiveRefinedObjList.GetObj(i).GetClassName()=="Crystal")
477  {
478  REAL (Crystal::*fc)() const;
479  const Crystal *pCryst=dynamic_cast<const Crystal *>(&(mRecursiveRefinedObjList.GetObj(i)));
481  mMainTracker.AddTracker(new TrackerObject<Crystal>
482  (pCryst->GetName()+"::BumpMergeCost",*pCryst,fc));
484  mMainTracker.AddTracker(new TrackerObject<Crystal>
485  (pCryst->GetName()+"::BondValenceCost",*pCryst,fc));
486 
487  fc=&Crystal::GetInterMolDistCost;
488  mMainTracker.AddTracker(new TrackerObject<Crystal>
489  (pCryst->GetName()+"::InterMolDistCost",*pCryst,fc));
490  }
491  }
492  }
493  // Prepare for refinement, ie get the list of not fixed parameters,
494  // and prepare the objects...
496  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
497  mRecursiveRefinedObjList.GetObj(i).PrepareForRefinement();
498  VFN_DEBUG_EXIT("OptimizationObj::PrepareRefParList()",6)
499 }
500 
502 {
503  VFN_DEBUG_MESSAGE("OptimizationObj::InitOptions()",5)
504  static string xmlAutoSaveName;
505  static string xmlAutoSaveChoices[6];
506 
507  static bool needInitNames=true;
508  if(true==needInitNames)
509  {
510  xmlAutoSaveName="Save Best Config Regularly";
511  xmlAutoSaveChoices[0]="No";
512  xmlAutoSaveChoices[1]="Every day";
513  xmlAutoSaveChoices[2]="Every hour";
514  xmlAutoSaveChoices[3]="Every 10mn";
515  xmlAutoSaveChoices[4]="Every new best config (a lot ! Not Recommended !)";
516  xmlAutoSaveChoices[5]="Every Run (Recommended)";
517 
518  needInitNames=false;//Only once for the class
519  }
520  mXMLAutoSave.Init(6,&xmlAutoSaveName,xmlAutoSaveChoices);
521  this->AddOption(&mXMLAutoSave);
522  VFN_DEBUG_MESSAGE("OptimizationObj::InitOptions():End",5)
523 }
524 
526 {
527  Chronometer chrono;
528  for(int i=0;i<mRefinedObjList.GetNb();i++)
529  mRefinedObjList.GetObj(i).UpdateDisplay();
531 }
532 
534 {
535  // First check if anything has changed (ie if a sub-object has been
536  // added or removed in the recursive refinable object list)
537  RefinableObjClock clock;
539  if(clock>mRecursiveRefinedObjList.GetRegistryClock())
540  {
541  VFN_DEBUG_ENTRY("OptimizationObj::BuildRecursiveRefObjList()",5)
542  mRecursiveRefinedObjList.DeRegisterAll();
543  for(int i=0;i<mRefinedObjList.GetNb();i++)
545  VFN_DEBUG_EXIT("OptimizationObj::BuildRecursiveRefObjList()",5)
546  }
547 }
548 
550 {
551  VFN_DEBUG_ENTRY("OptimizationObj::AddOption()",5)
552  mOptionRegistry.Register(*opt);
553  VFN_DEBUG_EXIT("OptimizationObj::AddOption()",5)
554 }
555 
556 //#################################################################################
557 //
558 // MonteCarloObj
559 //
560 //#################################################################################
562 OptimizationObj(""),
563 mCurrentCost(-1),
564 mTemperatureMax(1e6),mTemperatureMin(.001),mTemperatureGamma(1.0),
565 mMutationAmplitudeMax(8.),mMutationAmplitudeMin(.125),mMutationAmplitudeGamma(1.0),
566 mNbTrialRetry(0),mMinCostRetry(0)
567 #ifdef __WX__CRYST__
568 ,mpWXCrystObj(0)
569 #endif
570 {
571  VFN_DEBUG_ENTRY("MonteCarloObj::MonteCarloObj()",5)
572  this->InitOptions();
573  mGlobalOptimType.SetChoice(GLOBAL_OPTIM_PARALLEL_TEMPERING);
574  mAnnealingScheduleTemp.SetChoice(ANNEALING_SMART);
575  mAnnealingScheduleMutation.SetChoice(ANNEALING_EXPONENTIAL);
576  mXMLAutoSave.SetChoice(5);//Save after each Run
577  mAutoLSQ.SetChoice(0);
578  gOptimizationObjRegistry.Register(*this);
579  VFN_DEBUG_EXIT("MonteCarloObj::MonteCarloObj()",5)
580 }
581 
582 MonteCarloObj::MonteCarloObj(const string name):
583 OptimizationObj(name),
584 mCurrentCost(-1),
585 mTemperatureMax(1e6),mTemperatureMin(.001),mTemperatureGamma(1.0),
586 mMutationAmplitudeMax(8.),mMutationAmplitudeMin(.125),mMutationAmplitudeGamma(1.0),
587 mNbTrialRetry(0),mMinCostRetry(0)
588 #ifdef __WX__CRYST__
589 ,mpWXCrystObj(0)
590 #endif
591 {
592  VFN_DEBUG_ENTRY("MonteCarloObj::MonteCarloObj()",5)
593  this->InitOptions();
594  mGlobalOptimType.SetChoice(GLOBAL_OPTIM_PARALLEL_TEMPERING);
595  mAnnealingScheduleTemp.SetChoice(ANNEALING_SMART);
596  mAnnealingScheduleMutation.SetChoice(ANNEALING_EXPONENTIAL);
597  mXMLAutoSave.SetChoice(5);//Save after each Run
598  mAutoLSQ.SetChoice(0);
599  gOptimizationObjRegistry.Register(*this);
600  VFN_DEBUG_EXIT("MonteCarloObj::MonteCarloObj()",5)
601 }
602 
604 OptimizationObj(old),
605 mCurrentCost(old.mCurrentCost),
606 mTemperatureMax(old.mTemperatureMax),mTemperatureMin(old.mTemperatureMin),
607 mTemperatureGamma(old.mTemperatureGamma),
608 mMutationAmplitudeMax(old.mMutationAmplitudeMax),mMutationAmplitudeMin(old.mMutationAmplitudeMin),
609 mMutationAmplitudeGamma(old.mMutationAmplitudeGamma),
610 mNbTrialRetry(old.mNbTrialRetry),mMinCostRetry(old.mMinCostRetry)
611 #ifdef __WX__CRYST__
612 ,mpWXCrystObj(0)
613 #endif
614 {
615  VFN_DEBUG_ENTRY("MonteCarloObj::MonteCarloObj(&old)",5)
616  this->InitOptions();
617  for(unsigned int i=0;i<this->GetNbOption();i++)
618  this->GetOption(i).SetChoice(old.GetOption(i).GetChoice());
619 
620  gOptimizationObjRegistry.Register(*this);
621  VFN_DEBUG_EXIT("MonteCarloObj::MonteCarloObj(&old)",5)
622 }
623 
624 MonteCarloObj::MonteCarloObj(const bool internalUseOnly):
625 OptimizationObj(""),
626 mCurrentCost(-1),
627 mTemperatureMax(.03),mTemperatureMin(.003),mTemperatureGamma(1.0),
628 mMutationAmplitudeMax(16.),mMutationAmplitudeMin(.125),mMutationAmplitudeGamma(1.0),
629 mNbTrialRetry(0),mMinCostRetry(0)
630 #ifdef __WX__CRYST__
631 ,mpWXCrystObj(0)
632 #endif
633 {
634  VFN_DEBUG_ENTRY("MonteCarloObj::MonteCarloObj(bool)",5)
635  this->InitOptions();
636  mGlobalOptimType.SetChoice(GLOBAL_OPTIM_PARALLEL_TEMPERING);
637  mAnnealingScheduleTemp.SetChoice(ANNEALING_SMART);
638  mAnnealingScheduleMutation.SetChoice(ANNEALING_EXPONENTIAL);
639  mXMLAutoSave.SetChoice(5);//Save after each Run
640  mAutoLSQ.SetChoice(0);
641  if(false==internalUseOnly) gOptimizationObjRegistry.Register(*this);
642  VFN_DEBUG_EXIT("MonteCarloObj::MonteCarloObj(bool)",5)
643 }
644 
646 {
647  VFN_DEBUG_ENTRY("MonteCarloObj::~MonteCarloObj()",5)
648  gOptimizationObjRegistry.DeRegister(*this);
649  VFN_DEBUG_EXIT ("MonteCarloObj::~MonteCarloObj()",5)
650 }
652  const REAL tMax, const REAL tMin,
653  const AnnealingSchedule scheduleMutation,
654  const REAL mutMax, const REAL mutMin,
655  const long nbTrialRetry,const REAL minCostRetry)
656 {
657  VFN_DEBUG_MESSAGE("MonteCarloObj::SetAlgorithmSimulAnnealing()",5)
658  mGlobalOptimType.SetChoice(GLOBAL_OPTIM_SIMULATED_ANNEALING);
659  mTemperatureMax=tMax;
660  mTemperatureMin=tMin;
661  mAnnealingScheduleTemp.SetChoice(scheduleTemp);
662 
663 
664  mMutationAmplitudeMax=mutMax;
665  mMutationAmplitudeMin=mutMin;
666  mAnnealingScheduleMutation.SetChoice(scheduleMutation);
667  mNbTrialRetry=nbTrialRetry;
668  mMinCostRetry=minCostRetry;
669  VFN_DEBUG_MESSAGE("MonteCarloObj::SetAlgorithmSimulAnnealing():End",3)
670 }
671 
673  const REAL tMax, const REAL tMin,
674  const AnnealingSchedule scheduleMutation,
675  const REAL mutMax, const REAL mutMin)
676 {
677  VFN_DEBUG_MESSAGE("MonteCarloObj::SetAlgorithmParallTempering()",5)
678  mGlobalOptimType.SetChoice(GLOBAL_OPTIM_PARALLEL_TEMPERING);
679  mTemperatureMax=tMax;
680  mTemperatureMin=tMin;
681  mAnnealingScheduleTemp.SetChoice(scheduleTemp);
682 
683  mMutationAmplitudeMax=mutMax;
684  mMutationAmplitudeMin=mutMin;
685  mAnnealingScheduleMutation.SetChoice(scheduleMutation);
686  //mNbTrialRetry=nbTrialRetry;
687  //mMinCostRetry=minCostRetry;
688  VFN_DEBUG_MESSAGE("MonteCarloObj::SetAlgorithmParallTempering():End",3)
689 }
690 void MonteCarloObj::Optimize(long &nbStep,const bool silent,const REAL finalcost,
691  const REAL maxTime)
692 {
693  //:TODO: Other algorithms !
694  TAU_PROFILE("MonteCarloObj::Optimize()","void (long)",TAU_DEFAULT);
695  VFN_DEBUG_ENTRY("MonteCarloObj::Optimize()",5)
696  this->BeginOptimization(true);
697  this->PrepareRefParList();
698 
699  this->InitLSQ(false);
700 
701  mIsOptimizing=true;
706  // prepare all objects
707  this->TagNewBestConfig();
710  mvObjWeight.clear();
712  Chronometer chrono;
713  chrono.start();
714  switch(mGlobalOptimType.GetChoice())
715  {
716  case GLOBAL_OPTIM_SIMULATED_ANNEALING:
717  {
718  this->RunSimulatedAnnealing(nbStep,silent,finalcost,maxTime);
719  break;
720  }//case GLOBAL_OPTIM_SIMULATED_ANNEALING
721  case GLOBAL_OPTIM_PARALLEL_TEMPERING:
722  {
723  this->RunParallelTempering(nbStep,silent,finalcost,maxTime);
724  break;
725  }//case GLOBAL_OPTIM_PARALLEL_TEMPERING
726  case GLOBAL_OPTIM_RANDOM_LSQ: //:TODO:
727  {
728  long cycles = 1;
729  this->RunRandomLSQMethod(cycles);
730  break;
731  }//case GLOBAL_OPTIM_GENETIC
732  }
733  mIsOptimizing=false;
734  #ifdef __WX__CRYST__
735  mMutexStopAfterCycle.Lock();
736  #endif
737  mStopAfterCycle=false;
738  #ifdef __WX__CRYST__
739  mMutexStopAfterCycle.Unlock();
740  #endif
741 
743  this->EndOptimization();
744  (*fpObjCrystInformUser)((boost::format("Finished Optimization, final cost=%12.2f (dt=%.1fs)") % this->GetLogLikelihood() % chrono.seconds()).str());
745 
746  if(mSaveTrackedData.GetChoice()==1)
747  {
748  ofstream outTracker;
749  outTracker.imbue(std::locale::classic());
750  const string outTrackerName=this->GetName()+"-Tracker.dat";
751  outTracker.open(outTrackerName.c_str());
752  mMainTracker.SaveAll(outTracker);
753  outTracker.close();
754  }
755 
756  for(vector<pair<long,REAL> >::iterator pos=mvSavedParamSet.begin();pos!=mvSavedParamSet.end();++pos)
757  if(pos->first==mBestParSavedSetIndex)
758  {
759  if( (pos->second>mBestCost)
760  ||(pos->second<0))
761  {
762  pos->second=mBestCost;
763  break;
764  }
765  }
766 
767  this->UpdateDisplay();
768 
769  VFN_DEBUG_EXIT("MonteCarloObj::Optimize()",5)
770 }
771 void MonteCarloObj::MultiRunOptimize(long &nbCycle,long &nbStep,const bool silent,
772  const REAL finalcost,const REAL maxTime)
773 {
774  //:TODO: Other algorithms !
775  TAU_PROFILE("MonteCarloObj::MultiRunOptimize()","void (long)",TAU_DEFAULT);
776  VFN_DEBUG_ENTRY("MonteCarloObj::MultiRunOptimize()",5)
777  //Keep a copy of the total number of steps, and decrement nbStep
778  const long nbStep0=nbStep;
779  this->BeginOptimization(true);
780  this->PrepareRefParList();
781 
782  this->InitLSQ(false);
783 
784  mIsOptimizing=true;
789  // prepare all objects
792  this->TagNewBestConfig();
793  mvObjWeight.clear();
794  long nbTrialCumul=0;
795  const long nbCycle0=nbCycle;
796  Chronometer chrono;
797  mRun = 0;
798  while(nbCycle!=0)
799  {
800  if(!silent) cout <<"MonteCarloObj::MultiRunOptimize: Starting Run#"<<abs(nbCycle)<<endl;
801  nbStep=nbStep0;
802  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).RandomizeConfiguration();
804  chrono.start();
805  switch(mGlobalOptimType.GetChoice())
806  {
807  case GLOBAL_OPTIM_SIMULATED_ANNEALING:
808  {
809  try{this->RunSimulatedAnnealing(nbStep,silent,finalcost,maxTime);}
810  catch(...){cout<<"Unhandled exception in MonteCarloObj::MultiRunOptimize() ?"<<endl;}
811  break;
812  }
813  case GLOBAL_OPTIM_PARALLEL_TEMPERING:
814  {
815  try{this->RunParallelTempering(nbStep,silent,finalcost,maxTime);}
816  catch(...){cout<<"Unhandled exception in MonteCarloObj::MultiRunOptimize() ?"<<endl;}
817  break;
818  }
819  case GLOBAL_OPTIM_RANDOM_LSQ:
820  {
821  try{this->RunRandomLSQMethod(nbCycle);}
822  catch(...){cout<<"Unhandled exception in MonteCarloObj::RunRandomLSQMethod() ?"<<endl;}
823  //nbCycle=1;
824  break;
825  }
826  }
827  nbTrialCumul+=(nbStep0-nbStep);
828  if(finalcost>1)
829  (*fpObjCrystInformUser)((boost::format("Finished Run #%d, final cost=%12.2f, nbTrial=%d (dt=%.1fs), so far <nbTrial>=%d")
830  % (nbCycle0-nbCycle) % this->GetLogLikelihood() % (nbStep0-nbStep) % chrono.seconds() % (nbTrialCumul/(nbCycle0-nbCycle+1))).str());
831  else
832  (*fpObjCrystInformUser)((boost::format("Finished Run #%d, final cost=%12.2f, nbTrial=%d (dt=%.1fs)")
833  % (nbCycle0-nbCycle) % this->GetLogLikelihood() % (nbStep0-nbStep) % chrono.seconds()).str());
834 
835 
836  nbStep=nbStep0;
837  if(false==mStopAfterCycle) this->UpdateDisplay();
838  stringstream s;
839  s<<"Run #"<<abs(nbCycle);
840  mvSavedParamSet.push_back(make_pair(mRefParList.CreateParamSet(s.str()),mCurrentCost));
841  if(!silent) cout <<"MonteCarloObj::MultiRunOptimize: Finished Run#"
842  <<abs(nbCycle)<<", Run Best Cost:"<<mCurrentCost
843  <<", Overall Best Cost:"<<mBestCost<<endl;
844  if(mXMLAutoSave.GetChoice()==5)
845  {
846  string saveFileName=this->GetName();
847  time_t date=time(0);
848  char strDate[40];
849  strftime(strDate,sizeof(strDate),"%Y-%m-%d_%H-%M-%S",localtime(&date));//%Y-%m-%dT%H:%M:%S%Z
850  char costAsChar[64];
851  // Use %g (bounded length) rather than %f -- %f expands the full
852  // integer part of the cost, and an unbounded log-likelihood
853  // (e.g. from an overlapping-atoms starting configuration) can
854  // produce a string long enough to overflow this fixed buffer,
855  // which glibc's fortified sprintf (_FORTIFY_SOURCE) turns into a
856  // hard abort() rather than a graceful error.
857  snprintf(costAsChar,sizeof(costAsChar),"-Run#%ld-Cost-%g",abs(nbCycle),this->GetLogLikelihood());
858  saveFileName=saveFileName+(string)strDate+(string)costAsChar+(string)".xml";
859  XMLCrystFileSaveGlobal(saveFileName);
860  }
861  if(mSaveTrackedData.GetChoice()==1)
862  {
863  ofstream outTracker;
864  outTracker.imbue(std::locale::classic());
865  char runNum[40];
866  snprintf(runNum,sizeof(runNum),"-Tracker-Run#%ld.dat",abs(nbCycle));
867  const string outTrackerName=this->GetName()+runNum;
868  outTracker.open(outTrackerName.c_str());
869  mMainTracker.SaveAll(outTracker);
870  outTracker.close();
871  }
872  nbCycle--;
873  #ifdef __WX__CRYST__
874  mMutexStopAfterCycle.Lock();
875  #endif
876  if(mStopAfterCycle)
877  {
878  #ifdef __WX__CRYST__
879  mMutexStopAfterCycle.Unlock();
880  #endif
881  break;
882  }
883  #ifdef __WX__CRYST__
884  mMutexStopAfterCycle.Unlock();
885  #endif
886  mRun++;
887  }
888  mIsOptimizing=false;
889 
891 
892  for(vector<pair<long,REAL> >::iterator pos=mvSavedParamSet.begin();pos!=mvSavedParamSet.end();++pos)
893  if(pos->first==mBestParSavedSetIndex)
894  {
895  if( (pos->second>mBestCost)
896  ||(pos->second<0))
897  {
898  pos->second=mBestCost;
899  break;
900  }
901  }
902 
903  this->EndOptimization();
904 
905  if(false==mStopAfterCycle) this->UpdateDisplay();
906 
907  #ifdef __WX__CRYST__
908  mMutexStopAfterCycle.Lock();
909  #endif
910  mStopAfterCycle=false;
911  #ifdef __WX__CRYST__
912  mMutexStopAfterCycle.Unlock();
913  #endif
914 
915  if(finalcost>1)
916  cout<<endl<<"Finished all runs, number of trials to reach cost="
917  <<finalcost<<" : <nbTrial>="<<nbTrialCumul/(nbCycle0-nbCycle)<<endl;
918  VFN_DEBUG_EXIT("MonteCarloObj::MultiRunOptimize()",5)
919 }
920 
921 void MonteCarloObj::RunSimulatedAnnealing(long &nbStep,const bool silent,
922  const REAL finalcost,const REAL maxTime)
923 {
924  //Keep a copy of the total number of steps, and decrement nbStep
925  const long nbSteps=nbStep;
926  unsigned int accept;// 1 if last trial was accepted? 2 if new best config ? else 0
927  mNbTrial=0;
928  // time (in seconds) when last autoSave was made (if enabled)
929  unsigned long secondsWhenAutoSave=0;
930 
931  if(!silent) cout << "Starting Simulated Annealing Optimization for"<<nbSteps<<" trials"<<endl;
932  if(!silent) this->DisplayReport();
933  REAL runBestCost;
935  runBestCost=mCurrentCost;
936  const long lastParSavedSetIndex=mRefParList.CreateParamSet("MonteCarloObj:Last parameters (SA)");
937  const long runBestIndex=mRefParList.CreateParamSet("Best parameters for current run (SA)");
938  //Report each ... cycles
939  const int nbTryReport=3000;
940  // Keep record of the number of accepted moves
941  long nbAcceptedMoves=0;//since last report
942  long nbAcceptedMovesTemp=0;//since last temperature/mutation rate change
943  // Number of tries since best configuration found
944  long nbTriesSinceBest=0;
945  // Change temperature (and mutation) every...
946  const int nbTryPerTemp=300;
947 
950 
951  // Do we need to update the display ?
952  bool needUpdateDisplay=false;
953  Chronometer chrono;
954  chrono.start();
955  for(mNbTrial=1;mNbTrial<=nbSteps;)
956  {
957  if((mNbTrial % nbTryPerTemp) == 1)
958  {
959  VFN_DEBUG_MESSAGE("-> Updating temperature and mutation amplitude.",3)
960  // Temperature & displacements amplitude
961  switch(mAnnealingScheduleTemp.GetChoice())
962  {
963  case ANNEALING_BOLTZMANN:
964  mTemperature=
965  mTemperatureMin*log((REAL)nbSteps)/log((REAL)(mNbTrial+1));break;
966  case ANNEALING_CAUCHY:
967  mTemperature=mTemperatureMin*nbSteps/mNbTrial;break;
968  //case ANNEALING_QUENCHING:
969  case ANNEALING_EXPONENTIAL:
972  mNbTrial/(REAL)nbSteps);break;
973  case ANNEALING_GAMMA:
975  *pow(mNbTrial/(REAL)nbSteps,mTemperatureGamma);break;
976  case ANNEALING_SMART:
977  {
978  if((nbAcceptedMovesTemp/(REAL)nbTryPerTemp)>0.30)
979  mTemperature/=1.5;
980  if((nbAcceptedMovesTemp/(REAL)nbTryPerTemp)<0.10)
981  mTemperature*=1.5;
984  nbAcceptedMovesTemp=0;
985  break;
986  }
987  default: mTemperature=mTemperatureMin;break;
988  }
989  switch(mAnnealingScheduleMutation.GetChoice())
990  {
991  case ANNEALING_BOLTZMANN:
993  mMutationAmplitudeMin*log((REAL)nbSteps)/log((REAL)(mNbTrial+1));
994  break;
995  case ANNEALING_CAUCHY:
997  //case ANNEALING_QUENCHING:
998  case ANNEALING_EXPONENTIAL:
1001  mNbTrial/(REAL)nbSteps);break;
1002  case ANNEALING_GAMMA:
1004  *pow(mNbTrial/(REAL)nbSteps,mMutationAmplitudeGamma);break;
1005  case ANNEALING_SMART:
1006  if((nbAcceptedMovesTemp/(REAL)nbTryPerTemp)>0.3) mMutationAmplitude*=2.;
1007  if((nbAcceptedMovesTemp/(REAL)nbTryPerTemp)<0.1) mMutationAmplitude/=2.;
1012  nbAcceptedMovesTemp=0;
1013  break;
1015  }
1016  }
1017 
1018  this->NewConfiguration();
1019  accept=0;
1020  REAL cost=this->GetLogLikelihood();
1021  if(cost<mCurrentCost)
1022  {
1023  accept=1;
1024  mCurrentCost=cost;
1025  mRefParList.SaveParamSet(lastParSavedSetIndex);
1026  if(mCurrentCost<runBestCost)
1027  {
1028  accept=2;
1029  runBestCost=mCurrentCost;
1030  this->TagNewBestConfig();
1031  needUpdateDisplay=true;
1032  mRefParList.SaveParamSet(runBestIndex);
1033  if(runBestCost<mBestCost)
1034  {
1037  if(!silent) cout << "Trial :" << mNbTrial
1038  << " Temp="<< mTemperature
1039  << " Mutation Ampl.: "<<mMutationAmplitude
1040  << " NEW OVERALL Best Cost="<<runBestCost<< endl;
1041  }
1042  else if(!silent) cout << "Trial :" << mNbTrial
1043  << " Temp="<< mTemperature
1044  << " Mutation Ampl.: "<<mMutationAmplitude
1045  << " NEW Run Best Cost="<<runBestCost<< endl;
1046  nbTriesSinceBest=0;
1047  }
1048  nbAcceptedMoves++;
1049  nbAcceptedMovesTemp++;
1050  }
1051  else
1052  {
1053  if( log((rand()+1)/(REAL)RAND_MAX) < (-(cost-mCurrentCost)/mTemperature) )
1054  {
1055  accept=1;
1056  mCurrentCost=cost;
1057  mRefParList.SaveParamSet(lastParSavedSetIndex);
1058  nbAcceptedMoves++;
1059  nbAcceptedMovesTemp++;
1060  }
1061  }
1062  if(accept==0) mRefParList.RestoreParamSet(lastParSavedSetIndex);
1063 
1064  if( (mNbTrial % nbTryReport) == 0)
1065  {
1066  if(!silent) cout <<"Trial :" << mNbTrial << " Temp="<< mTemperature;
1067  if(!silent) cout <<" Mutation Ampl.: " <<mMutationAmplitude<< " Best Cost=" << runBestCost
1068  <<" Current Cost=" << mCurrentCost
1069  <<" Accepting "<<(int)((REAL)nbAcceptedMoves/nbTryReport*100)
1070  <<"% moves" << endl;
1071  nbAcceptedMoves=0;
1072  #ifdef __WX__CRYST__
1073  if(0!=mpWXCrystObj) mpWXCrystObj->UpdateDisplayNbTrial();
1074  #endif
1075  }
1076  mNbTrial++;nbStep--;
1077 
1078  #ifdef __WX__CRYST__
1079  mMutexStopAfterCycle.Lock();
1080  #endif
1081  if((runBestCost<finalcost) || mStopAfterCycle ||( (maxTime>0)&&(chrono.seconds()>maxTime)))
1082  {
1083  #ifdef __WX__CRYST__
1084  mMutexStopAfterCycle.Unlock();
1085  #endif
1086  if(!silent) cout << endl <<endl << "Refinement Stopped."<<endl;
1087  break;
1088  }
1089  #ifdef __WX__CRYST__
1090  mMutexStopAfterCycle.Unlock();
1091  #endif
1092  nbTriesSinceBest++;
1093  if( ((mXMLAutoSave.GetChoice()==1)&&((chrono.seconds()-secondsWhenAutoSave)>86400))
1094  ||((mXMLAutoSave.GetChoice()==2)&&((chrono.seconds()-secondsWhenAutoSave)>3600))
1095  ||((mXMLAutoSave.GetChoice()==3)&&((chrono.seconds()-secondsWhenAutoSave)> 600))
1096  ||((mXMLAutoSave.GetChoice()==4)&&(accept==2)) )
1097  {
1098  secondsWhenAutoSave=(unsigned long)chrono.seconds();
1099  string saveFileName=this->GetName();
1100  time_t date=time(0);
1101  char strDate[40];
1102  strftime(strDate,sizeof(strDate),"%Y-%m-%d_%H-%M-%S",localtime(&date));//%Y-%m-%dT%H:%M:%S%Z
1103  char costAsChar[64];
1105  // See the comment at the equivalent site in MultiRunOptimize() above:
1106  // %g instead of %f + snprintf avoids a fortified-sprintf abort() on
1107  // an unbounded log-likelihood value.
1108  snprintf(costAsChar,sizeof(costAsChar),"-Cost-%g",this->GetLogLikelihood());
1109  saveFileName=saveFileName+(string)strDate+(string)costAsChar+(string)".xml";
1110  XMLCrystFileSaveGlobal(saveFileName);
1111  if(accept!=2) mRefParList.RestoreParamSet(lastParSavedSetIndex);
1112  }
1113  if((mNbTrial%300==0)&&needUpdateDisplay)
1114  {
1115  this->UpdateDisplay();
1116  needUpdateDisplay=false;
1117  mRefParList.RestoreParamSet(lastParSavedSetIndex);
1118  }
1119 
1120  }
1121  //cout<<"Beginning final LSQ refinement? ... ";
1122  if(mAutoLSQ.GetChoice()>0)
1123  {// LSQ
1124  if(!silent) cout<<"Beginning final LSQ refinement"<<endl;
1125  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(false);
1126  mRefParList.RestoreParamSet(runBestIndex);
1128  try {mLSQ.Refine(-50,true,true,false,0.001);}
1129  catch(const ObjCrystException &except){};
1130  if(!silent) cout<<"LSQ cost: "<<mCurrentCost<<" -> "<<this->GetLogLikelihood()<<endl;
1131 
1132  // Need to go back to optimization with approximations allowed (they are not during LSQ)
1133  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(true);
1134 
1135  REAL cost=this->GetLogLikelihood();
1136  if(cost<mCurrentCost)
1137  {
1138  mCurrentCost=cost;
1139  mRefParList.SaveParamSet(lastParSavedSetIndex);
1140  if(mCurrentCost<runBestCost)
1141  {
1142  runBestCost=mCurrentCost;
1143  mRefParList.SaveParamSet(runBestIndex);
1144  if(runBestCost<mBestCost)
1145  {
1148  if(!silent) cout << "LSQ : NEW OVERALL Best Cost="<<runBestCost<< endl;
1149  }
1150  else if(!silent) cout << " LSQ : NEW Run Best Cost="<<runBestCost<< endl;
1151  }
1152  }
1153  if(!silent) cout<<"Finished LSQ refinement"<<endl;
1154  }
1155 
1156 
1157  mLastOptimTime=chrono.seconds();
1158  //Restore Best values
1159  mRefParList.RestoreParamSet(runBestIndex);
1160  mRefParList.ClearParamSet(runBestIndex);
1161  mRefParList.ClearParamSet(lastParSavedSetIndex);
1163  if(!silent) this->DisplayReport();
1164  if(!silent) chrono.print();
1165 }
1166 /*
1167 void MonteCarloObj::RunNondestructiveLSQRefinement( int nbCycle,bool useLevenbergMarquardt,
1168  const bool silent, const bool callBeginEndOptimization,
1169  const float minChi2var )
1170 {
1171  float bsigma=-1, bdelta=-1;
1172  float asigma=-1, adelta=-1;
1173  //set the sigma values lower - it makes the molecular model more stable for LSQ
1174  for(int i=0;i<mRefinedObjList.GetNb();i++) {
1175  if(mRefinedObjList.GetObj(i).GetClassName()=="Crystal") {
1176  try {
1177  Crystal * pCryst = dynamic_cast<Crystal *>(&(mRefinedObjList.GetObj(i)));
1178  for(int s=0;s<pCryst->GetScattererRegistry().GetNb();s++) {
1179  Molecule *pMol=dynamic_cast<Molecule*>(&(pCryst->GetScatt(s)));
1180  if(pMol==NULL) continue; // not a Molecule
1181  for(vector<MolBond*>::iterator pos = pMol->GetBondList().begin(); pos != pMol->GetBondList().end();++pos) {
1182  bsigma = (*pos)->GetLengthSigma();
1183  bdelta = (*pos)->GetLengthDelta();
1184  (*pos)->SetLengthDelta(0.02);
1185  (*pos)->SetLengthSigma(0.001);
1186  }
1187  for(vector<MolBondAngle*>::iterator pos=pMol->GetBondAngleList().begin();pos != pMol->GetBondAngleList().end();++pos)
1188  {
1189  asigma = (*pos)->GetAngleSigma();
1190  adelta = (*pos)->GetAngleDelta();
1191  (*pos)->SetAngleDelta(0.2*DEG2RAD);
1192  (*pos)->SetAngleSigma(0.01*DEG2RAD);
1193  }
1194  }
1195  } catch (const std::bad_cast& e) {
1196 
1197  }
1198  }
1199  }
1200  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(false);
1201  try {
1202  mLSQ.Refine(nbCycle,useLevenbergMarquardt,silent,callBeginEndOptimization,minChi2var);
1203  }
1204  catch(const ObjCrystException &except) {
1205 
1206  };
1207  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(true);
1208 
1209  if(bsigma<0 || bdelta<0 || asigma<0 || adelta<0) return;
1210  //restore the delta and sigma values
1211  for(int i=0;i<mRefinedObjList.GetNb();i++) {
1212  if(mRefinedObjList.GetObj(i).GetClassName()=="Crystal") {
1213  try {
1214  Crystal * pCryst = dynamic_cast<Crystal *>(&(mRefinedObjList.GetObj(i)));
1215  for(int s=0;s<pCryst->GetScattererRegistry().GetNb();s++) {
1216  Molecule *pMol=dynamic_cast<Molecule*>(&(pCryst->GetScatt(s)));
1217  if(pMol==NULL) continue; // not a Molecule
1218  for(vector<MolBond*>::iterator pos = pMol->GetBondList().begin(); pos != pMol->GetBondList().end();++pos) {
1219  (*pos)->SetLengthDelta(bdelta);
1220  (*pos)->SetLengthSigma(bsigma);
1221  }
1222  for(vector<MolBondAngle*>::iterator pos=pMol->GetBondAngleList().begin();pos != pMol->GetBondAngleList().end();++pos)
1223  {
1224  (*pos)->SetAngleDelta(adelta);
1225  (*pos)->SetAngleSigma(asigma);
1226  }
1227  }
1228  } catch (const std::bad_cast& e) {
1229 
1230  }
1231  }
1232  }
1233 }
1234 */
1235 void MonteCarloObj::RunRandomLSQMethod(long &nbCycle)
1236 {
1237  //perform random move
1239  float bsigma=-1, bdelta=-1;
1240  float asigma=-1, adelta=-1;
1241 
1242  //set the delta and sigma values - low values are good for LSQ!
1243  for(int i=0;i<mRefinedObjList.GetNb();i++) {
1244  if(mRefinedObjList.GetObj(i).GetClassName()=="Crystal") {
1245  try {
1246  Crystal * pCryst = dynamic_cast<Crystal *>(&(mRefinedObjList.GetObj(i)));
1247  for(int s=0;s<pCryst->GetScattererRegistry().GetNb();s++)
1248  {
1249  Molecule *pMol=dynamic_cast<Molecule*>(&(pCryst->GetScatt(s)));
1250  if(pMol==NULL) continue; // not a Molecule
1251  for(vector<MolBond*>::iterator pos = pMol->GetBondList().begin(); pos != pMol->GetBondList().end();++pos) {
1252  bsigma = (*pos)->GetLengthSigma();
1253  bdelta = (*pos)->GetLengthDelta();
1254  (*pos)->SetLengthDelta(0.02);
1255  (*pos)->SetLengthSigma(0.001);
1256  }
1257  for(vector<MolBondAngle*>::iterator pos=pMol->GetBondAngleList().begin();pos != pMol->GetBondAngleList().end();++pos)
1258  {
1259  asigma = (*pos)->GetAngleSigma();
1260  adelta = (*pos)->GetAngleDelta();
1261  (*pos)->SetAngleDelta(0.2*DEG2RAD);
1262  (*pos)->SetAngleSigma(0.01*DEG2RAD);
1263  }
1264  }
1265  } catch (const std::bad_cast& e){
1266 
1267  }
1268  }
1269  }
1270 
1271  const long starting_point=mRefParList.CreateParamSet("MonteCarloObj:Last parameters (RANDOM-LSQ)");
1272  mRefParList.SaveParamSet(starting_point);
1273  mRun = 0;
1274  while(nbCycle!=0) {
1275  nbCycle--;
1276  mRefParList.RestoreParamSet(starting_point);
1277  //this->NewConfiguration();
1278  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).RandomizeConfiguration();
1279  this->UpdateDisplay();
1280 
1281  //perform LSQ
1282  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(false);
1283  //mCurrentCost=this->GetLogLikelihood();
1284  try {
1285  mLSQ.Refine(20,true,true,false,0.001);
1286  }
1287  catch(const ObjCrystException &except) {
1288  //cout<<"Something wrong?"<<endl;
1289  };
1290  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(true);
1291  //cout<<"LSQ cost: "<<mCurrentCost<<" -> "<<this->GetLogLikelihood()<<endl;
1292  REAL lsq_cost=this->GetLogLikelihood();
1293  mCurrentCost = lsq_cost;
1294  //mRefParList.SaveParamSet(lsqtParSavedSetIndex);
1296  {
1299  }
1300  this->UpdateDisplay();
1301 
1302  //save it to the file
1303  string saveFileName=this->GetName();
1304  time_t date=time(0);
1305  char strDate[40];
1306  strftime(strDate,sizeof(strDate),"%Y-%m-%d_%H-%M-%S",localtime(&date));//%Y-%m-%dT%H:%M:%S%Z
1307  char costAsChar[64];
1308  // See the comment at the equivalent site in MultiRunOptimize() above:
1309  // %g instead of %f + snprintf avoids a fortified-sprintf abort() on
1310  // an unbounded log-likelihood value.
1311  snprintf(costAsChar,sizeof(costAsChar),"#Run%ld-Cost-%g",nbCycle, mCurrentCost);
1312  saveFileName=saveFileName+(string)strDate+(string)costAsChar+(string)".xml";
1313  XMLCrystFileSaveGlobal(saveFileName);
1314 
1315  #ifdef __WX__CRYST__
1316  mMutexStopAfterCycle.Lock();
1317  #endif
1318  if(mStopAfterCycle)
1319  {
1320  #ifdef __WX__CRYST__
1321  mMutexStopAfterCycle.Unlock();
1322  #endif
1323  break;
1324  }
1325  #ifdef __WX__CRYST__
1326  mMutexStopAfterCycle.Unlock();
1327  #endif
1328  mRun++;
1329  }
1330 
1331  if(bsigma<0 || bdelta<0 || asigma<0 || adelta<0) return;
1332  //restore the delta and sigma values
1333  for(int i=0;i<mRefinedObjList.GetNb();i++) {
1334  if(mRefinedObjList.GetObj(i).GetClassName()=="Crystal") {
1335  try {
1336  Crystal * pCryst = dynamic_cast<Crystal *>(&(mRefinedObjList.GetObj(i)));
1337  for(int s=0;s<pCryst->GetScattererRegistry().GetNb();s++)
1338  {
1339  Molecule *pMol=dynamic_cast<Molecule*>(&(pCryst->GetScatt(s)));
1340  if(pMol==NULL) continue; // not a Molecule
1341  for(vector<MolBond*>::iterator pos = pMol->GetBondList().begin(); pos != pMol->GetBondList().end();++pos) {
1342  (*pos)->SetLengthDelta(bdelta);
1343  (*pos)->SetLengthSigma(bsigma);
1344  }
1345  for(vector<MolBondAngle*>::iterator pos=pMol->GetBondAngleList().begin();pos != pMol->GetBondAngleList().end();++pos)
1346  {
1347  (*pos)->SetAngleDelta(adelta);
1348  (*pos)->SetAngleSigma(asigma);
1349  }
1350  }
1351  } catch (const std::bad_cast& e){
1352 
1353  }
1354  }
1355  }
1356 }
1357 
1358 void MonteCarloObj::RunParallelTempering(long &nbStep,const bool silent,
1359  const REAL finalcost,const REAL maxTime)
1360 {
1361  TAU_PROFILE("MonteCarloObj::RunParallelTempering()","void ()",TAU_DEFAULT);
1362  TAU_PROFILE_TIMER(timer0a,"MonteCarloObj::RunParallelTempering() Begin 1","", TAU_FIELD);
1363  TAU_PROFILE_TIMER(timer0b,"MonteCarloObj::RunParallelTempering() Begin 2","", TAU_FIELD);
1364  TAU_PROFILE_TIMER(timer1,"MonteCarloObj::RunParallelTempering() New Config + LLK","", TAU_FIELD);
1365  TAU_PROFILE_TIMER(timerN,"MonteCarloObj::RunParallelTempering() Finish","", TAU_FIELD);
1366  TAU_PROFILE_START(timer0a);
1367  //Keep a copy of the total number of steps, and decrement nbStep
1368  const long nbSteps=nbStep;
1369  unsigned int accept;// 1 if last trial was accepted? 2 if new best config ? else 0
1370  mNbTrial=0;
1371  // time (in seconds) when last autoSave was made (if enabled)
1372  unsigned long secondsWhenAutoSave=0;
1373 
1374  // Periodicity of the automatic LSQ refinements (if the option is set)
1375  const unsigned int autoLSQPeriod=150000;
1376 
1377  if(!silent) cout << "Starting Parallel Tempering Optimization"<<endl;
1378  //Total number of parallel refinements,each is a 'World'. The most stable
1379  // world must be i=nbWorld-1, and the most changing World (high mutation,
1380  // high temperature) is i=0.
1381  const long nbWorld=30;
1382  CrystVector_long worldSwapIndex(nbWorld);
1383  for(int i=0;i<nbWorld;++i) worldSwapIndex(i)=i;
1384  // Number of successive trials for each World. At the end of these trials
1385  // a swap is tried with the upper World (eg i-1). This number effectvely sets
1386  // the rate of swapping.
1387  const int nbTryPerWorld=10;
1388  // Initialize the costs
1390  REAL runBestCost=mCurrentCost;
1391  CrystVector_REAL currentCost(nbWorld);
1392  currentCost=mCurrentCost;
1393  // Init the different temperatures
1394  CrystVector_REAL simAnnealTemp(nbWorld);
1395  for(int i=0;i<nbWorld;i++)
1396  {
1397  switch(mAnnealingScheduleTemp.GetChoice())
1398  {
1399  case ANNEALING_BOLTZMANN:
1400  simAnnealTemp(i)=
1401  mTemperatureMin*log((REAL)nbWorld)/log((REAL)(i+2));break;
1402  case ANNEALING_CAUCHY:
1403  simAnnealTemp(i)=mTemperatureMin*nbWorld/(i+1);break;
1404  //case ANNEALING_QUENCHING:
1405  case ANNEALING_EXPONENTIAL:
1406  simAnnealTemp(i)=mTemperatureMax
1408  i/(REAL)(nbWorld-1));break;
1409  case ANNEALING_GAMMA:
1411  *pow(i/(REAL)(nbWorld-1),mTemperatureGamma);break;
1412  case ANNEALING_SMART:
1413  simAnnealTemp(i)=mCurrentCost/(100.+(REAL)i/(REAL)nbWorld*900.);break;
1414  default:
1415  simAnnealTemp(i)=mCurrentCost/(100.+(REAL)i/(REAL)nbWorld*900.);break;
1416  }
1417  }
1418  //Init the different mutation rate parameters
1419  CrystVector_REAL mutationAmplitude(nbWorld);
1420  for(int i=0;i<nbWorld;i++)
1421  {
1422  switch(mAnnealingScheduleMutation.GetChoice())
1423  {
1424  case ANNEALING_BOLTZMANN:
1425  mutationAmplitude(i)=
1426  mMutationAmplitudeMin*log((REAL)(nbWorld-1))/log((REAL)(i+2));
1427  break;
1428  case ANNEALING_CAUCHY:
1429  mutationAmplitude(i)=mMutationAmplitudeMin*(REAL)(nbWorld-1)/(i+1);break;
1430  //case ANNEALING_QUENCHING:
1431  case ANNEALING_EXPONENTIAL:
1432  mutationAmplitude(i)=mMutationAmplitudeMax
1434  i/(REAL)(nbWorld-1));break;
1435  case ANNEALING_GAMMA:
1437  *pow(i/(REAL)(nbWorld-1),mMutationAmplitudeGamma);break;
1438  case ANNEALING_SMART:
1439  mutationAmplitude(i)=sqrt(mMutationAmplitudeMin*mMutationAmplitudeMax);break;
1440  default:
1441  mutationAmplitude(i)=sqrt(mMutationAmplitudeMin*mMutationAmplitudeMax);break;
1442  }
1443  }
1444  // Init the parameter sets for each World
1445  // All Worlds start from the same (current) configuration.
1446  CrystVector_long worldCurrentSetIndex(nbWorld);
1447  for(int i=nbWorld-1;i>=0;i--)
1448  {
1449  if((i!=(nbWorld-1))&&(i%2==0))
1450  for(int j=0;j<mRecursiveRefinedObjList.GetNb();j++)
1451  mRecursiveRefinedObjList.GetObj(j).RandomizeConfiguration();
1452  worldCurrentSetIndex(i)=mRefParList.CreateParamSet();
1453  mRefParList.RestoreParamSet(worldCurrentSetIndex(nbWorld-1));
1454  }
1455  TAU_PROFILE_STOP(timer0a);
1456  TAU_PROFILE_START(timer0b);
1457  //mNbTrial=nbSteps;;
1458  const long lastParSavedSetIndex=mRefParList.CreateParamSet("MonteCarloObj:Last parameters (PT)");
1459  const long runBestIndex=mRefParList.CreateParamSet("Best parameters for current run (PT)");
1460  CrystVector_REAL swapPar;
1461  //Keep track of how many trials are accepted for each World
1462  CrystVector_long worldNbAcceptedMoves(nbWorld);
1463  worldNbAcceptedMoves=0;
1464  //Do a report each... And check if mutation rate is OK (for annealing_smart)s
1465  const int nbTrialsReport=3000;
1466  // TEST : allow GENETIC mating of configurations
1467  //Get gene groups list :TODO: check for missing groups
1468  CrystVector_uint refParGeneGroupIndex(mRefParList.GetNbPar());
1469  unsigned int first=1;
1470  for(int i=0;i<mRecursiveRefinedObjList.GetNb();i++)
1471  mRecursiveRefinedObjList.GetObj(i).GetGeneGroup(mRefParList,refParGeneGroupIndex,first);
1472  #if 0
1473  if(!silent)
1474  for(int i=0;i<mRefParList.GetNbPar();i++)
1475  {
1476  cout << "Gene Group:"<<refParGeneGroupIndex(i)<<" :";
1477  mRefParList.GetPar(i).Print();
1478  }
1479  #endif
1480  // number of gene groups
1481  // to select which gene groups are exchanged in the mating
1482  //const unsigned int nbGeneGroup=refParGeneGroupIndex.max();
1483  //CrystVector_int crossoverGroupIndex(nbGeneGroup);
1484  //const long parSetOffspringA=mRefParList.CreateParamSet("Offspring A");
1485  //const long parSetOffspringB=mRefParList.CreateParamSet("Offspring B");
1486  // record the statistical distribution n=f(cost function) for each World
1487  //CrystMatrix_REAL trialsDensity(100,nbWorld+1);
1488  //trialsDensity=0;
1489  //for(int i=0;i<100;i++) trialsDensity(i,0)=i/(float)100;
1490  // Do we need to update the display ?
1491  bool needUpdateDisplay=false;
1492  //Do the refinement
1493  bool makeReport=false;
1494  Chronometer chrono;
1495  chrono.start();
1496  float lastUpdateDisplayTime=chrono.seconds();
1497  TAU_PROFILE_STOP(timer0b);
1498  for(;mNbTrial<nbSteps;)
1499  {
1500  for(int i=0;i<nbWorld;i++)
1501  {
1502  mContext=i;
1503  //mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1504  mMutationAmplitude=mutationAmplitude(i);
1505  mTemperature=simAnnealTemp(i);
1506  for(int j=0;j<nbTryPerWorld;j++)
1507  {
1508  //mRefParList.SaveParamSet(lastParSavedSetIndex);
1509  TAU_PROFILE_START(timer1);
1510  mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1511  this->NewConfiguration();
1512  accept=0;
1513  REAL cost=this->GetLogLikelihood();
1514  TAU_PROFILE_STOP(timer1);
1515  //trialsDensity((long)(cost*100.),i+1)+=1;
1516  if(cost<currentCost(i))
1517  {
1518  accept=1;
1519  currentCost(i)=cost;
1520  mRefParList.SaveParamSet(worldCurrentSetIndex(i));
1521  if(cost<runBestCost)
1522  {
1523  accept=2;
1524  runBestCost=currentCost(i);
1525  this->TagNewBestConfig();
1526  needUpdateDisplay=true;
1527 
1528  mRefParList.SaveParamSet(runBestIndex);
1529  if(runBestCost<mBestCost)
1530  {
1531  mBestCost=currentCost(i);
1533  if(!silent) cout << "->Trial :" << mNbTrial
1534  << " World="<< worldSwapIndex(i)
1535  << " Temp="<< mTemperature
1536  << " Mutation Ampl.: "<<mMutationAmplitude
1537  << " NEW OVERALL Best Cost="<<mBestCost<< endl;
1538  }
1539  else if(!silent) cout << "->Trial :" << mNbTrial
1540  << " World="<< worldSwapIndex(i)
1541  << " Temp="<< mTemperature
1542  << " Mutation Ampl.: "<<mMutationAmplitude
1543  << " NEW RUN Best Cost="<<runBestCost<< endl;
1544  if(!silent) this->DisplayReport();
1545  }
1546  worldNbAcceptedMoves(i)++;
1547  }
1548  else
1549  {
1550  if(log((rand()+1)/(REAL)RAND_MAX)<(-(cost-currentCost(i))/mTemperature) )
1551  {
1552  accept=1;
1553  currentCost(i)=cost;
1554  mRefParList.SaveParamSet(worldCurrentSetIndex(i));
1555  worldNbAcceptedMoves(i)++;
1556  }
1557  }
1558  //if(accept==1 && i==(nbWorld-1)){this->UpdateDisplay();}
1559  if( ((mXMLAutoSave.GetChoice()==1)&&((chrono.seconds()-secondsWhenAutoSave)>86400))
1560  ||((mXMLAutoSave.GetChoice()==2)&&((chrono.seconds()-secondsWhenAutoSave)>3600))
1561  ||((mXMLAutoSave.GetChoice()==3)&&((chrono.seconds()-secondsWhenAutoSave)> 600))
1562  ||((mXMLAutoSave.GetChoice()==4)&&(accept==2)) )
1563  {
1564  secondsWhenAutoSave=(unsigned long)chrono.seconds();
1565  string saveFileName=this->GetName();
1566  time_t date=time(0);
1567  char strDate[40];
1568  strftime(strDate,sizeof(strDate),"%Y-%m-%d_%H-%M-%S",localtime(&date));//%Y-%m-%dT%H:%M:%S%Z
1569  char costAsChar[64];
1571  // See the comment at the equivalent site in MultiRunOptimize() above:
1572  // %g instead of %f + snprintf avoids a fortified-sprintf abort() on
1573  // an unbounded log-likelihood value.
1574  snprintf(costAsChar,sizeof(costAsChar),"-Cost-%g",this->GetLogLikelihood());
1575  saveFileName=saveFileName+(string)strDate+(string)costAsChar+(string)".xml";
1576  XMLCrystFileSaveGlobal(saveFileName);
1577  //if(accept!=2) mRefParList.RestoreParamSet(lastParSavedSetIndex);
1578  }
1579  //if(accept==0) mRefParList.RestoreParamSet(lastParSavedSetIndex);
1580  mNbTrial++;nbStep--;
1581  if((mNbTrial%nbTrialsReport)==0) makeReport=true;
1582  }//nbTryPerWorld trials
1583  }//For each World
1584 
1585  if(mAutoLSQ.GetChoice()==2)
1586  if((mNbTrial%autoLSQPeriod)<(nbTryPerWorld*nbWorld))
1587  {// Try a quick LSQ ?
1588  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(false);
1589  for(int i=nbWorld-5;i<nbWorld;i++)
1590  {
1591  #ifdef __WX__CRYST__
1592  mMutexStopAfterCycle.Lock();
1593  if(mStopAfterCycle)
1594  {
1595  mMutexStopAfterCycle.Unlock();
1596  break;
1597  }
1598  mMutexStopAfterCycle.Unlock();
1599  #endif
1600 
1601  mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1602 
1603  #if 0
1604  // Report GoF values (Chi^2 / nbObs) values for all objects
1605  for(map<RefinableObj*,unsigned int>::iterator pos=mLSQ.GetRefinedObjMap().begin();pos!=mLSQ.GetRefinedObjMap().end();++pos)
1606  if(pos->first->GetNbLSQFunction()>0)
1607  {
1608  CrystVector_REAL tmp;
1609  tmp =pos->first->GetLSQCalc(pos->second);
1610  tmp-=pos->first->GetLSQObs (pos->second);
1611  tmp*=tmp;
1612  tmp*=pos->first->GetLSQWeight(pos->second);
1613  cout<<pos->first->GetClassName()<<":"<<pos->first->GetName()<<": GoF="<<tmp.sum()/tmp.numElements();
1614  }
1615  cout<<endl;
1616  #endif
1617 
1618  const REAL cost0=this->GetLogLikelihood();// cannot use currentCost(i), approximations changed...
1619  if(!silent) cout<<"LSQ: World="<<worldSwapIndex(i)<<": cost="<<cost0;
1620  try {mLSQ.Refine(-30,true,true,false,0.001);}
1621  catch(const ObjCrystException &except){};
1622  #if 0
1623  // Report GoF values (Chi^2 / nbObs) values for all objects
1624  for(map<RefinableObj*,unsigned int>::iterator pos=mLSQ.GetRefinedObjMap().begin();pos!=mLSQ.GetRefinedObjMap().end();++pos)
1625  if(pos->first->GetNbLSQFunction()>0)
1626  {
1627  CrystVector_REAL tmp;
1628  tmp =pos->first->GetLSQCalc(pos->second);
1629  tmp-=pos->first->GetLSQObs (pos->second);
1630  tmp*=tmp;
1631  tmp*=pos->first->GetLSQWeight(pos->second);
1632  cout<<pos->first->GetClassName()<<":"<<pos->first->GetName()<<": GoF="<<tmp.sum()/tmp.numElements();
1633  }
1634  cout<<endl;
1635  #endif
1636  const REAL cost=this->GetLogLikelihood();
1637  if(!silent) cout<<" -> "<<cost<<endl;
1638  if(cost<cost0) mRefParList.SaveParamSet(worldCurrentSetIndex(i));
1639  }
1640  // Need to go back to optimization with approximations allowed (they are not during LSQ)
1641  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(true);
1642  // And recompute LLK - since they will be lower
1643  for(int i=nbWorld-5;i<nbWorld;i++)
1644  {
1645  mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1646  const REAL cost=this->GetLogLikelihood();
1647  if(!silent) cout<<"LSQ2:"<<currentCost(i)<<"->"<<cost<<endl;
1648  if(cost<currentCost(i))
1649  {
1650  const REAL oldcost=currentCost(i);
1651  mRefParList.SaveParamSet(worldCurrentSetIndex(i));
1652  currentCost(i)=cost;
1653  if(cost<runBestCost)
1654  {
1655  runBestCost=currentCost(i);
1656  this->TagNewBestConfig();
1657  needUpdateDisplay=true;
1658 
1659  mRefParList.SaveParamSet(runBestIndex);
1660  if(runBestCost<mBestCost)
1661  {
1662  mBestCost=currentCost(i);
1664  if(!silent) cout << "->Trial :" << mNbTrial
1665  << " World="<< worldSwapIndex(i)
1666  << " LSQ2: NEW OVERALL Best Cost="<<mBestCost<< endl;
1667  }
1668  else if(!silent) cout << "->Trial :" << mNbTrial
1669  << " World="<< worldSwapIndex(i)
1670  << " LSQ2: NEW RUN Best Cost="<<runBestCost<< endl;
1671  if(!silent) this->DisplayReport();
1672  }
1673  // KLUDGE - after a successful LSQ, we will be close to a minimum,
1674  // which will make most successive global optimization trials to
1675  // be rejected, until the temperature is increased a lot - this
1676  // is a problem as the temperature increases so much that the
1677  // benefit of the LSQ is essentially negated.
1678  // So we need to use a higher recorded cost, so that successive trials
1679  // may be accepted
1680  #if 0
1681  mMutationAmplitude=mutationAmplitude(i);
1682  for(unsigned int ii=0;ii<4;ii++) this->NewConfiguration(gpRefParTypeObjCryst,false);
1683  currentCost(i)=(this->GetLogLikelihood()+cost)/2;
1684  if(!silent) cout<<"LSQ3: #"<<worldSwapIndex(i)<<":"<<cost<<"->"<<currentCost(i)<<endl;
1685  #else
1686  currentCost(i)=oldcost;
1687  #endif
1688  }
1689  }
1690  }
1691 
1692  //Try swapping worlds
1693  for(int i=1;i<nbWorld;i++)
1694  {
1695  #if 0
1696  mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1697  mMutationAmplitude=mutationAmplitude(i);
1698  cout<<i<<":"<<currentCost(i)<<":"<<this->GetLogLikelihood()<<endl;
1699  #endif
1700  #if 1
1701  if( log((rand()+1)/(REAL)RAND_MAX)
1702  < (-(currentCost(i-1)-currentCost(i))/simAnnealTemp(i)))
1703  #else
1704  // Compare World (i-1) and World (i) with the same amplitude,
1705  // hence the same max likelihood error
1706  mRefParList.RestoreParamSet(worldCurrentSetIndex(i-1));
1707  mMutationAmplitude=mutationAmplitude(i);
1708  if( log((rand()+1)/(REAL)RAND_MAX)
1709  < (-(this->GetLogLikelihood()-currentCost(i))/simAnnealTemp(i)))
1710  #endif
1711  {
1712  /*
1713  if(i>2)
1714  {
1715  cout <<"->Swapping Worlds :" << i <<"(cost="<<currentCost(i)<<")"
1716  <<" with "<< (i-1) <<"(cost="<< currentCost(i-1)<<")"<<endl;
1717  }
1718  */
1719  swapPar=mRefParList.GetParamSet(worldCurrentSetIndex(i));
1720  mRefParList.GetParamSet(worldCurrentSetIndex(i))=
1721  mRefParList.GetParamSet(worldCurrentSetIndex(i-1));
1722  mRefParList.GetParamSet(worldCurrentSetIndex(i-1))=swapPar;
1723  const REAL tmp=currentCost(i);
1724  currentCost(i)=currentCost(i-1);
1725  currentCost(i-1)=tmp;
1726  const long tmpIndex=worldSwapIndex(i);
1727  worldSwapIndex(i)=worldSwapIndex(i-1);
1728  worldSwapIndex(i-1)=tmpIndex;
1729  #if 0
1730  // Compute correct costs in the case we use maximum likelihood
1731  mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1732  mMutationAmplitude=mutationAmplitude(i);
1733  currentCost(i)=this->GetLogLikelihood();
1734 
1735  mRefParList.RestoreParamSet(worldCurrentSetIndex(i-1));
1736  mMutationAmplitude=mutationAmplitude(i-1);
1737  currentCost(i-1)=this->GetLogLikelihood();
1738  #endif
1739  }
1740  }
1741  #if 0
1742  //Try mating worlds- NEW !
1743  TAU_PROFILE_TIMER(timer1,\
1744  "MonteCarloObj::Optimize (Try mating Worlds)"\
1745  ,"", TAU_FIELD);
1746  TAU_PROFILE_START(timer1);
1747  if( (rand()/(REAL)RAND_MAX)<.1)
1748  for(int k=nbWorld-1;k>nbWorld/2;k--)
1749  for(int i=k-nbWorld/3;i<k;i++)
1750  {
1751  #if 0
1752  // Random switching of gene groups
1753  for(unsigned int j=0;j<nbGeneGroup;j++)
1754  crossoverGroupIndex(j)= (int) floor(rand()/((REAL)RAND_MAX-1)*2);
1755  for(int j=0;j<mRefParList.GetNbPar();j++)
1756  {
1757  if(0==crossoverGroupIndex(refParGeneGroupIndex(j)-1))
1758  {
1759  mRefParList.GetParamSet(parSetOffspringA)(j)=
1760  mRefParList.GetParamSet(worldCurrentSetIndex(i))(j);
1761  mRefParList.GetParamSet(parSetOffspringB)(j)=
1762  mRefParList.GetParamSet(worldCurrentSetIndex(k))(j);
1763  }
1764  else
1765  {
1766  mRefParList.GetParamSet(parSetOffspringA)(j)=
1767  mRefParList.GetParamSet(worldCurrentSetIndex(k))(j);
1768  mRefParList.GetParamSet(parSetOffspringB)(j)=
1769  mRefParList.GetParamSet(worldCurrentSetIndex(i))(j);
1770  }
1771  }
1772  #endif
1773  #if 1
1774  // Switch gene groups in two parts
1775  unsigned int crossoverPoint1=
1776  (int)(1+floor(rand()/((REAL)RAND_MAX-1)*(nbGeneGroup)));
1777  unsigned int crossoverPoint2=
1778  (int)(1+floor(rand()/((REAL)RAND_MAX-1)*(nbGeneGroup)));
1779  if(crossoverPoint2<crossoverPoint1)
1780  {
1781  int tmp=crossoverPoint1;
1782  crossoverPoint1=crossoverPoint2;
1783  crossoverPoint2=tmp;
1784  }
1785  if(crossoverPoint1==crossoverPoint2) crossoverPoint2+=1;
1786  for(int j=0;j<mRefParList.GetNbPar();j++)
1787  {
1788  if((refParGeneGroupIndex(j)>crossoverPoint1)&&refParGeneGroupIndex(j)<crossoverPoint2)
1789  {
1790  mRefParList.GetParamSet(parSetOffspringA)(j)=
1791  mRefParList.GetParamSet(worldCurrentSetIndex(i))(j);
1792  mRefParList.GetParamSet(parSetOffspringB)(j)=
1793  mRefParList.GetParamSet(worldCurrentSetIndex(k))(j);
1794  }
1795  else
1796  {
1797  mRefParList.GetParamSet(parSetOffspringA)(j)=
1798  mRefParList.GetParamSet(worldCurrentSetIndex(k))(j);
1799  mRefParList.GetParamSet(parSetOffspringB)(j)=
1800  mRefParList.GetParamSet(worldCurrentSetIndex(i))(j);
1801  }
1802  }
1803  #endif
1804  // Try both offspring
1805  for(int junk=0;junk<2;junk++)
1806  {
1807  if(junk==0) mRefParList.RestoreParamSet(parSetOffspringA);
1808  else mRefParList.RestoreParamSet(parSetOffspringB);
1809  REAL cost=this->GetLogLikelihood();
1810  //if(log((rand()+1)/(REAL)RAND_MAX)
1811  // < (-(cost-currentCost(k))/simAnnealTemp(k)))
1812  if(cost<currentCost(k))
1813  {
1814  // Also exchange genes for higher-temperature World ?
1815  //if(junk==0)
1816  // mRefParList.GetParamSet(worldCurrentSetIndex(i))=
1817  // mRefParList.GetParamSet(parSetOffspringB);
1818  //else
1819  // mRefParList.GetParamSet(worldCurrentSetIndex(i))=
1820  // mRefParList.GetParamSet(parSetOffspringA);
1821  currentCost(k)=cost;
1822  mRefParList.SaveParamSet(worldCurrentSetIndex(k));
1823  //worldNbAcceptedMoves(k)++;
1824  if(!silent) cout << "Accepted mating :"<<k<<"(with"<<i<<")"
1825  <<" (crossoverGene1="<< crossoverPoint1<<","
1826  <<" crossoverGene2="<< crossoverPoint2<<")"
1827  <<endl;
1828  if(cost<runBestCost)
1829  {
1830  runBestCost=cost;
1831  this->TagNewBestConfig();
1832  needUpdateDisplay=true;
1833  mRefParList.SaveParamSet(runBestIndex);
1834  if(cost<mBestCost)
1835  {
1836  mBestCost=cost;
1838  if(!silent) cout << "->Trial :" << mNbTrial
1839  << " World="<< worldSwapIndex(k)
1840  << " Temp="<< simAnnealTemp(k)
1841  << " Mutation Ampl.: "<<mMutationAmplitude
1842  << " NEW OVERALL Best Cost="<<mBestCost<< "(MATING !)"<<endl;
1843  }
1844  else if(!silent) cout << "->Trial :" << mNbTrial
1845  << " World="<< worldSwapIndex(k)
1846  << " Temp="<< simAnnealTemp(k)
1847  << " Mutation Ampl.: "<<mMutationAmplitude
1848  << " NEW RUN Best Cost="<<runBestCost<< "(MATING !)"<<endl;
1849  bestConfigNb=mNbTrial;
1850  if(!silent) this->DisplayReport();
1851  //for(int i=0;i<mRefinedObjList.GetNb();i++)
1852  // mRefinedObjList.GetObj(i).Print();
1853  }
1854  i=k;//Don't test other Worlds
1855  break;
1856  }
1857  //mNbTrial++;nbStep--;
1858  //if((mNbTrial%nbTrialsReport)==0) makeReport=true;
1859  }
1860  }
1861  TAU_PROFILE_STOP(timer1);
1862  #endif
1863  if(true==makeReport)
1864  {
1865  makeReport=false;
1866  worldNbAcceptedMoves*=nbWorld;
1867  if(!silent)
1868  {
1869  #if 0
1870  {// Experimental, dynamical weighting
1871  REAL max=0.;
1872  map<const RefinableObj*,REAL> ll,llvar;
1873  map<const RefinableObj*,LogLikelihoodStats>::iterator pos;
1874  for(pos=mvContextObjStats[0].begin();pos!=mvContextObjStats[0].end();++pos)
1875  {
1876  ll [pos->first]=0.;
1877  llvar[pos->first]=0.;
1878  }
1879  for(int i=0;i<nbWorld;i++)
1880  {
1881  for(pos=mvContextObjStats[0].begin();pos!=mvContextObjStats[0].end();++pos)
1882  {
1883  ll [pos->first] += pos->second.mTotalLogLikelihood;
1884  llvar[pos->first] += pos->second.mTotalLogLikelihoodDeltaSq;
1885  }
1886  }
1887  for(pos=mvContextObjStats[0].begin();pos!=mvContextObjStats[0].end();++pos)
1888  {
1889  cout << pos->first->GetName()
1890  << " " << llvar[pos->first]
1891  << " " << mvObjWeight[pos->first].mWeight
1892  << " " << max<<endl;
1893  llvar[pos->first] *= mvObjWeight[pos->first].mWeight;
1894  if(llvar[pos->first]>max) max=llvar[pos->first];
1895  }
1896  map<const RefinableObj*,REAL>::iterator pos2;
1897  for(pos2=llvar.begin();pos2!=llvar.end();++pos2)
1898  {
1899  const REAL d=pos2->second;
1900  if(d<(max/mvObjWeight.size()/10.))
1901  {
1902  if(d<1) continue;
1903  mvObjWeight[pos2->first].mWeight *=2;
1904  }
1905  }
1906  REAL ll1=0;
1907  REAL llt=0;
1908  for(pos2=ll.begin();pos2!=ll.end();++pos2)
1909  {
1910  llt += pos2->second;
1911  ll1 += pos2->second * mvObjWeight[pos2->first].mWeight;
1912  }
1913  map<const RefinableObj*,DynamicObjWeight>::iterator posw;
1914  for(posw=mvObjWeight.begin();posw!=mvObjWeight.end();++posw)
1915  {
1916  posw->second.mWeight *= llt/ll1;
1917  }
1918  }
1919  #endif //Experimental dynamical weighting
1920  #if 1 //def __DEBUG__
1921  for(int i=0;i<nbWorld;i++)
1922  {
1923  cout<<" World :"<<worldSwapIndex(i)<<":";
1924  map<const RefinableObj*,LogLikelihoodStats>::iterator pos;
1925  for(pos=mvContextObjStats[i].begin();pos!=mvContextObjStats[i].end();++pos)
1926  {
1927  cout << pos->first->GetName()
1928  << "(LLK="
1929  << pos->second.mLastLogLikelihood
1930  //<< "(<LLK>="
1931  //<< pos->second.mTotalLogLikelihood/nbTrialsReport
1932  //<< ", <delta(LLK)^2>="
1933  //<< pos->second.mTotalLogLikelihoodDeltaSq/nbTrialsReport
1934  << ", w="<<mvObjWeight[pos->first].mWeight
1935  <<") ";
1936  pos->second.mTotalLogLikelihood=0;
1937  pos->second.mTotalLogLikelihoodDeltaSq=0;
1938  }
1939  cout << endl;
1940  }
1941  #endif
1942  for(int i=0;i<nbWorld;i++)
1943  {
1944  //mRefParList.RestoreParamSet(worldCurrentSetIndex(i));
1945  cout <<" World :" << worldSwapIndex(i)
1946  <<" Temp.: " << simAnnealTemp(i)
1947  <<" Mutation Ampl.: " << mutationAmplitude(i)
1948  <<" Current Cost=" << currentCost(i)
1949  <<" Accepting "
1950  << (int)((REAL)worldNbAcceptedMoves(i)/nbTrialsReport*100)
1951  <<"% moves " <<endl;
1952  // <<"% moves " << mRefParList.GetPar("Pboccup").GetValue()<<endl;
1953  }
1954  }
1955  if(!silent) cout <<"Trial :" << mNbTrial << " Best Cost=" << runBestCost<< " ";
1956  if(!silent) chrono.print();
1957  //Change the mutation rate if necessary for each world
1958  if(ANNEALING_SMART==mAnnealingScheduleMutation.GetChoice())
1959  {
1960  for(int i=0;i<nbWorld;i++)
1961  {
1962  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)>0.30)
1963  mutationAmplitude(i)*=2.;
1964  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)<0.10)
1965  mutationAmplitude(i)/=2.;
1966  if(mutationAmplitude(i)>mMutationAmplitudeMax)
1967  mutationAmplitude(i)=mMutationAmplitudeMax;
1968  if(mutationAmplitude(i)<mMutationAmplitudeMin)
1969  mutationAmplitude(i)=mMutationAmplitudeMin;
1970  }
1971  }
1972  if(ANNEALING_SMART==mAnnealingScheduleTemp.GetChoice())
1973  {
1974  for(int i=0;i<nbWorld;i++)
1975  {
1976  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)>0.30)
1977  simAnnealTemp(i)/=1.5;
1978  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)>0.80)
1979  simAnnealTemp(i)/=1.5;
1980  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)>0.95)
1981  simAnnealTemp(i)/=1.5;
1982 
1983  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)<0.10)
1984  simAnnealTemp(i)*=1.5;
1985  if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)<0.04)
1986  simAnnealTemp(i)*=1.5;
1987  //if((worldNbAcceptedMoves(i)/(REAL)nbTrialsReport)<0.01)
1988  // simAnnealTemp(i)*=1.5;
1989  //cout<<"World#"<<i<<":"<<worldNbAcceptedMoves(i)<<":"<<nbTrialsReport<<endl;
1990  //if(simAnnealTemp(i)>mTemperatureMax) simAnnealTemp(i)=mTemperatureMax;
1991  //if(simAnnealTemp(i)<mTemperatureMin) simAnnealTemp(i)=mTemperatureMin;
1992  }
1993  }
1994  worldNbAcceptedMoves=0;
1995  //this->DisplayReport();
1996 
1997  #ifdef __WX__CRYST__
1998  if(0!=mpWXCrystObj) mpWXCrystObj->UpdateDisplayNbTrial();
1999  #endif
2000  }
2001  if( (needUpdateDisplay&&(lastUpdateDisplayTime<(chrono.seconds()-1)))||(lastUpdateDisplayTime<(chrono.seconds()-10)))
2002  {
2003  mRefParList.RestoreParamSet(runBestIndex);
2004  this->UpdateDisplay();
2005  needUpdateDisplay=false;
2006  lastUpdateDisplayTime=chrono.seconds();
2007  }
2008  #ifdef __WX__CRYST__
2009  mMutexStopAfterCycle.Lock();
2010  #endif
2011  if((runBestCost<finalcost) || mStopAfterCycle ||( (maxTime>0)&&(chrono.seconds()>maxTime)))
2012  {
2013  #ifdef __WX__CRYST__
2014  mMutexStopAfterCycle.Unlock();
2015  #endif
2016  if(!silent) cout << endl <<endl << "Refinement Stopped:"<<mBestCost<<endl;
2017  break;
2018  }
2019  #ifdef __WX__CRYST__
2020  mMutexStopAfterCycle.Unlock();
2021  #endif
2022  }//Trials
2023 
2024  TAU_PROFILE_START(timerN);
2025  if(mAutoLSQ.GetChoice()>0)
2026  {// LSQ
2027  if(!silent) cout<<"Beginning final LSQ refinement"<<endl;
2028  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(false);
2029  mRefParList.RestoreParamSet(runBestIndex);
2031  try {mLSQ.Refine(-50,true,true,false,0.001);}
2032  catch(const ObjCrystException &except){};
2033  if(!silent) cout<<"LSQ cost: "<<mCurrentCost<<" -> "<<this->GetLogLikelihood()<<endl;
2034 
2035  // Need to go back to optimization with approximations allowed (they are not during LSQ)
2036  for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).SetApproximationFlag(true);
2037 
2038  REAL cost=this->GetLogLikelihood();
2039  if(cost<mCurrentCost)
2040  {
2041  mCurrentCost=cost;
2042  mRefParList.SaveParamSet(lastParSavedSetIndex);
2043  if(mCurrentCost<runBestCost)
2044  {
2045  runBestCost=mCurrentCost;
2046  mRefParList.SaveParamSet(runBestIndex);
2047  if(runBestCost<mBestCost)
2048  {
2051  if(!silent) cout << "LSQ : NEW OVERALL Best Cost="<<runBestCost<< endl;
2052  }
2053  else if(!silent) cout << " LSQ : NEW Run Best Cost="<<runBestCost<< endl;
2054  }
2055  }
2056  if(!silent) cout<<"Finished LSQ refinement"<<endl;
2057  }
2058 
2059  mLastOptimTime=chrono.seconds();
2060  //Restore Best values
2061  //mRefParList.Print();
2062  if(!silent) this->DisplayReport();
2063  mRefParList.RestoreParamSet(runBestIndex);
2064  //for(int i=0;i<mRefinedObjList.GetNb();i++) mRefinedObjList.GetObj(i).Print();
2066  if(!silent) cout<<"Run Best Cost:"<<mCurrentCost<<endl;
2067  if(!silent) chrono.print();
2068  //Save density of states
2069  //ofstream out("densityOfStates.txt");
2070  //out << trialsDensity<<endl;
2071  //out.close();
2072  // Clear temporary param set
2073  for(int i=0;i<nbWorld;i++)
2074  {
2075  mRefParList.ClearParamSet(worldCurrentSetIndex(i));
2076  //mvSavedParamSet.push_back(make_pair(worldCurrentSetIndex(i),currentCost(i)));
2077  }
2078  mRefParList.ClearParamSet(lastParSavedSetIndex);
2079  mRefParList.ClearParamSet(runBestIndex);
2080  TAU_PROFILE_STOP(timerN);
2081 }
2082 
2083 void MonteCarloObj::XMLOutput(ostream &os,int indent)const
2084 {
2085  VFN_DEBUG_ENTRY("MonteCarloObj::XMLOutput():"<<this->GetName(),5)
2086  for(int i=0;i<indent;i++) os << " " ;
2087  XMLCrystTag tag("GlobalOptimObj");
2088  tag.AddAttribute("Name",this->GetName());
2089  tag.AddAttribute("NbTrialPerRun",(boost::format("%d")%(this->NbTrialPerRun())).str());
2090 
2091  os <<tag<<endl;
2092  indent++;
2093 
2094  mGlobalOptimType.XMLOutput(os,indent);
2095  os<<endl;
2096 
2097  mAnnealingScheduleTemp.XMLOutput(os,indent);
2098  os<<endl;
2099 
2100  mXMLAutoSave.XMLOutput(os,indent);
2101  os<<endl;
2102 
2103  mAutoLSQ.XMLOutput(os,indent);
2104  os<<endl;
2105 
2106  {
2107  XMLCrystTag tag2("TempMaxMin");
2108  for(int i=0;i<indent;i++) os << " " ;
2109  os<<tag2<<mTemperatureMax << " "<< mTemperatureMin;
2110  tag2.SetIsEndTag(true);
2111  os<<tag2<<endl;
2112  }
2113 
2115  os<<endl;
2116 
2117  mSaveTrackedData.XMLOutput(os,indent);
2118  os<<endl;
2119 
2120  {
2121  XMLCrystTag tag2("MutationMaxMin");
2122  for(int i=0;i<indent;i++) os << " " ;
2123  os<<tag2<<mMutationAmplitudeMax << " "<< mMutationAmplitudeMin;
2124  tag2.SetIsEndTag(true);
2125  os<<tag2<<endl;
2126  }
2127 
2128  for(int j=0;j<mRefinedObjList.GetNb();j++)
2129  {
2130  XMLCrystTag tag2("RefinedObject",false,true);
2131  tag2.AddAttribute("ObjectType",mRefinedObjList.GetObj(j).GetClassName());
2132  tag2.AddAttribute("ObjectName",mRefinedObjList.GetObj(j).GetName());
2133  for(int i=0;i<indent;i++) os << " " ;
2134  os<<tag2<<endl;
2135  }
2136 
2137  indent--;
2138  tag.SetIsEndTag(true);
2139  for(int i=0;i<indent;i++) os << " " ;
2140  os <<tag<<endl;
2141  VFN_DEBUG_EXIT("MonteCarloObj::XMLOutput():"<<this->GetName(),5)
2142 }
2143 
2144 void MonteCarloObj::XMLInput(istream &is,const XMLCrystTag &tagg)
2145 {
2146  VFN_DEBUG_ENTRY("MonteCarloObj::XMLInput():"<<this->GetName(),5)
2147  for(unsigned int i=0;i<tagg.GetNbAttribute();i++)
2148  {
2149  if("Name"==tagg.GetAttributeName(i)) this->SetName(tagg.GetAttributeValue(i));
2150  if("NbTrialPerRun"==tagg.GetAttributeName(i))
2151  {
2152  stringstream ss(tagg.GetAttributeValue(i));
2153  long v;
2154  ss>>v;
2155  this->NbTrialPerRun()=v;
2156  }
2157  }
2158  while(true)
2159  {
2160  XMLCrystTag tag(is);
2161  if(("GlobalOptimObj"==tag.GetName())&&tag.IsEndTag())
2162  {
2163  VFN_DEBUG_EXIT("MonteCarloObj::Exit():"<<this->GetName(),5)
2164  this->UpdateDisplay();
2165  return;
2166  }
2167  if("Option"==tag.GetName())
2168  {
2169  for(unsigned int i=0;i<tag.GetNbAttribute();i++)
2170  if("Name"==tag.GetAttributeName(i))
2171  {
2172  if("Algorithm"==tag.GetAttributeValue(i))
2173  {
2174  mGlobalOptimType.XMLInput(is,tag);
2175  break;
2176  }
2177  if("Temperature Schedule"==tag.GetAttributeValue(i))
2178  {
2180  break;
2181  }
2182  if("Displacement Amplitude Schedule"==tag.GetAttributeValue(i))
2183  {
2185  break;
2186  }
2187  if("Save Best Config Regularly"==tag.GetAttributeValue(i))
2188  {
2189  mXMLAutoSave.XMLInput(is,tag);
2190  break;
2191  }
2192  if("Save Tracked Data"==tag.GetAttributeValue(i))
2193  {
2194  mSaveTrackedData.XMLInput(is,tag);
2195  break;
2196  }
2197  if("Automatic Least Squares Refinement"==tag.GetAttributeValue(i))
2198  {
2199  mAutoLSQ.XMLInput(is,tag);
2200  break;
2201  }
2202  }
2203  continue;
2204  }
2205  if("TempMaxMin"==tag.GetName())
2206  {
2208  if(false==tag.IsEmptyTag()) XMLCrystTag junk(is);//:KLUDGE: for first release
2209  continue;
2210  }
2211  if("MutationMaxMin"==tag.GetName())
2212  {
2214  if(false==tag.IsEmptyTag()) XMLCrystTag junk(is);//:KLUDGE: for first release
2215  continue;
2216  }
2217  if("RefinedObject"==tag.GetName())
2218  {
2219  string name,type;
2220  for(unsigned int i=0;i<tag.GetNbAttribute();i++)
2221  {
2222  if("ObjectName"==tag.GetAttributeName(i)) name=tag.GetAttributeValue(i);
2223  if("ObjectType"==tag.GetAttributeName(i)) type=tag.GetAttributeValue(i);
2224  }
2225  RefinableObj* obj=& (gRefinableObjRegistry.GetObj(name,type));
2226  this->AddRefinableObj(*obj);
2227  continue;
2228  }
2229  }
2230 }
2231 
2232 const string MonteCarloObj::GetClassName()const { return "MonteCarloObj";}
2233 
2235 
2236 const LSQNumObj& MonteCarloObj::GetLSQObj() const{return mLSQ;}
2237 
2239 {
2240  TAU_PROFILE("MonteCarloObj::NewConfiguration()","void ()",TAU_DEFAULT);
2241  VFN_DEBUG_ENTRY("MonteCarloObj::NewConfiguration()",4)
2242  for(int i=0;i<mRefinedObjList.GetNb();i++)
2243  mRefinedObjList.GetObj(i).BeginGlobalOptRandomMove();
2244  for(int i=0;i<mRefinedObjList.GetNb();i++)
2245  mRefinedObjList.GetObj(i).GlobalOptRandomMove(mMutationAmplitude,type);
2246  VFN_DEBUG_EXIT("MonteCarloObj::NewConfiguration()",4)
2247 }
2248 
2250 {
2251  VFN_DEBUG_MESSAGE("MonteCarloObj::InitOptions()",5)
2253  static string GlobalOptimTypeName;
2254  static string GlobalOptimTypeChoices[2];//:TODO: Add Genetic Algorithm
2255 
2256  static string AnnealingScheduleChoices[6];
2257 
2258  static string AnnealingScheduleTempName;
2259  static string AnnealingScheduleMutationName;
2260 
2261  static string runAutoLSQName;
2262  static string runAutoLSQChoices[3];
2263 
2264  static string saveTrackedDataName;
2265  static string saveTrackedDataChoices[2];
2266 
2267  static bool needInitNames=true;
2268  if(true==needInitNames)
2269  {
2270  GlobalOptimTypeName="Algorithm";
2271  GlobalOptimTypeChoices[0]="Simulated Annealing";
2272  GlobalOptimTypeChoices[1]="Parallel Tempering";
2273  //GlobalOptimTypeChoices[2]="Random-LSQ";
2274 
2275  AnnealingScheduleTempName="Temperature Schedule";
2276  AnnealingScheduleMutationName="Displacement Amplitude Schedule";
2277  AnnealingScheduleChoices[0]="Constant";
2278  AnnealingScheduleChoices[1]="Boltzmann";
2279  AnnealingScheduleChoices[2]="Cauchy";
2280  AnnealingScheduleChoices[3]="Exponential";
2281  AnnealingScheduleChoices[4]="Smart";
2282  AnnealingScheduleChoices[5]="Gamma";
2283 
2284  runAutoLSQName="Automatic Least Squares Refinement";
2285  runAutoLSQChoices[0]="Never";
2286  runAutoLSQChoices[1]="At the end of each run";
2287  runAutoLSQChoices[2]="Every 150000 trials, and at the end of each run";
2288 
2289  saveTrackedDataName="Save Tracked Data";
2290  saveTrackedDataChoices[0]="No (recommended!)";
2291  saveTrackedDataChoices[1]="Yes (for tests ONLY)";
2292 
2293  needInitNames=false;//Only once for the class
2294  }
2295  mGlobalOptimType.Init(2,&GlobalOptimTypeName,GlobalOptimTypeChoices);
2296  mAnnealingScheduleTemp.Init(6,&AnnealingScheduleTempName,AnnealingScheduleChoices);
2297  mAnnealingScheduleMutation.Init(6,&AnnealingScheduleMutationName,AnnealingScheduleChoices);
2298  mSaveTrackedData.Init(2,&saveTrackedDataName,saveTrackedDataChoices);
2299  mAutoLSQ.Init(3,&runAutoLSQName,runAutoLSQChoices);
2300  this->AddOption(&mGlobalOptimType);
2303  this->AddOption(&mSaveTrackedData);
2304  this->AddOption(&mAutoLSQ);
2305  VFN_DEBUG_MESSAGE("MonteCarloObj::InitOptions():End",5)
2306 }
2307 
2308 void MonteCarloObj::InitLSQ(const bool useFullPowderPatternProfile)
2309 {
2310  mLSQ.SetRefinedObj(mRecursiveRefinedObjList.GetObj(0),0,true,true);
2311  for(unsigned int i=1;i<mRefinedObjList.GetNb();++i)
2312  mLSQ.SetRefinedObj(mRefinedObjList.GetObj(i),0,false,true);
2313 
2314  if(!useFullPowderPatternProfile)
2315  {// Use LSQ function #1 for powder patterns (integrated patterns - faster !)
2316  for(map<RefinableObj*,unsigned int>::iterator pos=mLSQ.GetRefinedObjMap().begin();pos!=mLSQ.GetRefinedObjMap().end();++pos)
2317  if(pos->first->GetClassName()=="PowderPattern") pos->second=1;
2318  }
2319  // Only refine structural parameters (excepting parameters already fixed) and scale factor
2320  mLSQ.PrepareRefParList(true);
2321 
2322  // Intensity corrections can be refined
2323  std::list<RefinablePar*> vIntCorrPar;
2324  for(int i=0; i<mLSQ.GetCompiledRefinedObj().GetNbPar();i++)
2326  vIntCorrPar.push_back(&mLSQ.GetCompiledRefinedObj().GetPar(i));
2327 
2330 
2331  for(std::list<RefinablePar*>::iterator pos=vIntCorrPar.begin();pos!=vIntCorrPar.end();pos++)
2332  (*pos)->SetIsFixed(false);
2333  mLSQ.SetParIsFixed(gpRefParTypeUnitCell,true);
2334  mLSQ.SetParIsFixed(gpRefParTypeScattPow,true);
2335  mLSQ.SetParIsFixed(gpRefParTypeRadiation,true);
2336 }
2337 
2339 {
2340  Chronometer chrono;
2341  #ifdef __WX__CRYST__
2342  if(0!=mpWXCrystObj) mpWXCrystObj->CrystUpdate(true,true);
2343  #endif
2345 }
2346 
2347 #ifdef __WX__CRYST__
2348 WXCrystObjBasic* MonteCarloObj::WXCreate(wxWindow *parent)
2349 {
2350  mpWXCrystObj=new WXMonteCarloObj (parent,this);
2351  return mpWXCrystObj;
2352 }
2353 WXOptimizationObj* MonteCarloObj::WXGet()
2354 {
2355  return mpWXCrystObj;
2356 }
2357 void MonteCarloObj::WXDelete()
2358 {
2359  if(0!=mpWXCrystObj) delete mpWXCrystObj;
2360  mpWXCrystObj=0;
2361 }
2362 void MonteCarloObj::WXNotifyDelete()
2363 {
2364  mpWXCrystObj=0;
2365 }
2366 #endif
2367 
2368 }//namespace
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: doc-main.h:25
void RefObjRegisterRecursive(T &obj, ObjRegistry< T > &reg)
Register a new object in a registry, and recursively include all included (sub)objects.
const RefParType * gpRefParTypeScattDataScale
Type for scattering data scale factors.
ObjRegistry< OptimizationObj > gOptimizationObjRegistry("List of all Optimization objects")
Global Registry for all OptimizationObj.
void(* fpObjCrystInformUser)(const string &)
Pointer to a function for passing info to the user during or after long/important processes (use scar...
Definition: Exception.cpp:76
AnnealingSchedule
Annealing schedule type.
const RefParType * gpRefParTypeObjCryst
Top RefParType for the ObjCryst++ library.
void GetSubRefObjListClockRecursive(ObjRegistry< RefinableObj > &reg, RefinableObjClock &clock)
Get the last time any object was added in the recursive list of objects.
ObjRegistry< RefinableObj > gRefinableObjRegistry("Global RefinableObj registry")
Global Registry for all RefinableObj.
const RefParType * gpRefParTypeScattDataCorrInt
Generic type for correction to calculated intensities.
void GetRefParListClockRecursive(ObjRegistry< RefinableObj > &reg, RefinableObjClock &clock)
Get the last time any RefinablePar was added in a recursive list of objects.
const RefParType * gpRefParTypeScattData
Generic type for scattering data.
void XMLCrystFileSaveGlobal(const string &filename)
Save all Objcryst++ objects.
Crystal class: Unit cell, spacegroup, scatterers.
Definition: Crystal.h:98
REAL GetBondValenceCost() const
Get the Bond-Valence cost function, which compares the expected valence to the one computed from Bond...
Definition: Crystal.cpp:1531
ObjRegistry< Scatterer > & GetScattererRegistry()
Get the registry of scatterers.
Definition: Crystal.cpp:232
REAL GetBumpMergeCost() const
Get the Anti-bumping/pro-Merging cost function.
Definition: Crystal.cpp:938
Scatterer & GetScatt(const string &scattName)
Provides an access to the scatterers.
Definition: Crystal.cpp:212
Exception class for ObjCryst++ library.
Definition: General.h:122
Molecule : class for complex scatterer descriptions using cartesian coordinates with bond length/angl...
Definition: Molecule.h:760
Base object for Optimization methods.
virtual const string GetClassName() const
Get the name for this class type.
void AddRefinableObj(RefinableObj &)
Add a refined object. All sub-objects are also added.
void SetName(const string &)
Set the name for this object.
ObjRegistry< RefinableObj > mRecursiveRefinedObjList
The refined objects, recursively including all sub-objects.
REAL GetLastOptimElapsedTime() const
Get the elapsed time (in seconds) during the last optimization.
virtual void UpdateDisplay() const
Update Display (if any display is available), when a new 'relevant' configuration is reached.
unsigned int GetNbParamSet() const
Get the number of saved parameters set.
map< unsigned long, map< const RefinableObj *, LogLikelihoodStats > > mvContextObjStats
Statistics for each context (mutable for dynamic update during optimization)
void RestoreParamSet(const unsigned int i, const bool update_display=true)
Restore a given saved parameter set.
ObjRegistry< RefObjOpt > mOptionRegistry
List of options for this object.
bool IsOptimizing() const
Are we busy optimizing ?
void RestoreBestConfiguration()
Restore the Best configuration.
void StopAfterCycle()
Stop after the current cycle. USed for interactive refinement.
virtual void Print() const
Print some information about this object.
RefinableObj & GetFullRefinableObj(const bool rebuild=true)
Get the RefinableObj with all the parameters from all refined objects.
virtual REAL GetLogLikelihood() const
The optimized (minimized, actually) function.
virtual void EndOptimization()
End optimization for all objects.
REAL mBestCost
Best value of the cost function so far.
void AddOption(RefObjOpt *opt)
map< const RefinableObj *, DynamicObjWeight > mvObjWeight
Weights for each objects in each context (mutable for dynamic update during optimization)
OptimizationObj()
Default constructor.
virtual void RandomizeStartingConfig()
Randomize starting configuration.
virtual void DisplayReport()
Show report to the user during refinement. Used for GUI update.
long GetParamSetCost(const unsigned int i) const
Get the cost (log-likelihood) of a saved parameters set.
ObjRegistry< RefObjOpt > & GetOptionList()
Access to the options registry.
virtual void XMLOutput(ostream &os, int indent=0) const =0
Output a description of the object in XML format to a stream.
long GetParamSetIndex(const unsigned int i) const
Get the index of a saved parameters set in the compiled RefinableObj.
bool mIsOptimizing
True if a refinement is being done. For multi-threaded environment.
unsigned long mContext
The current 'context', in the case the optimization is run in different parallel contexts.
ObjRegistry< RefinableObj > mRefinedObjList
The refined objects.
RefObjOpt & GetOption(const unsigned int i)
Access to the options.
void SetLimitsRelative(const string &parName, const REAL min, const REAL max)
Change the relative limits for a parameter from its name.
void BuildRecursiveRefObjList()
(Re)build OptimizationObj::mRecursiveRefinedObjList, if an object has been added or modified.
long mRun
Current run number (during multiple runs)
virtual void InitOptions()
Initialization of options.
std::vector< pair< long, REAL > > mvSavedParamSet
List of saved parameter sets.
long GetRun() const
Current run number (updated during a run)
long GetTrial() const
Current trial number (updated during a run)
RefObjOpt mXMLAutoSave
Periodic save of complete environment as an xml file.
void TagNewBestConfig()
During a global optimization, tell all objects that the current config is the latest "best" config.
RefinableObj mRefParList
The refinable par list used during refinement.
string mName
Name of the GlobalOptimization object.
long mNbTrialPerRun
Number of trial per run, to be saved/restored in XML output.
long mBestParSavedSetIndex
Index of the 'best' saved parameter set.
void SetParIsUsed(const string &parName, const bool use)
Set a parameter to be used.
virtual long & NbTrialPerRun()
Number of trial per run.
MainTracker mMainTracker
MainTracker object to track the evolution of cost functions, likelihood, and individual parameters.
bool mStopAfterCycle
If true, then stop at the end of the cycle. Used in multi-threaded environment.
REAL mLastOptimTime
The time elapsed after the last optimization, in seconds.
const REAL & GetBestCost() const
Access to current best cost.
void SetParIsFixed(const string &parName, const bool fix)
Fix one parameter.
unsigned int GetNbOption() const
Number of Options for this object.
void SetLimitsAbsolute(const string &parName, const REAL min, const REAL max)
Change the absolute limits for a parameter from its name.
virtual void BeginOptimization(const bool allowApproximations=false, const bool enableRestraints=false)
Begin optimization for all objects.
const string & GetName() const
Get the name for this object.
void UnFixAllPar()
UnFix All parameters.
virtual ~OptimizationObj()
Destructor.
const ObjRegistry< RefinableObj > & GetRefinedObjList() const
Access the list of refined object.
long mNbTrial
Current trial number.
void FixAllPar()
Fix all parameters.
MainTracker & GetMainTracker()
Get the MainTracker.
Statistics about each object contributing to the overall Log(likelihood)
REAL mTotalLogLikelihoodDeltaSq
total of (Delta(Log(Likelihood)))^2 between successive trials
REAL mTotalLogLikelihood
Total Log(Likelihood), to compute the average.
REAL mLastLogLikelihood
Previous log(likelihood)
Base object for Monte-Carlo Global Optimization methods.
REAL mTemperatureMax
Beginning temperature for annealing.
REAL mTemperature
Current temperature for annealing.
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...
REAL mMutationAmplitudeGamma
Gamma for the 'gamma' Mutation amplitude schedule.
long mNbTrialRetry
Number of trials before testing if we are below the given minimum cost.
LSQNumObj mLSQ
Least squares object.
RefObjOpt mAutoLSQ
Option to run automatic least-squares refinements.
virtual ~MonteCarloObj()
Destructor.
virtual void InitOptions()
Initialization of options.
virtual const string GetClassName() const
Get the name for this class type.
virtual void XMLOutput(ostream &os, int indent=0) const
Output a description of the object in XML format to a stream.
void SetAlgorithmParallTempering(const AnnealingSchedule scheduleTemp, const REAL tMax, const REAL tMin, const AnnealingSchedule scheduleMutation=ANNEALING_CONSTANT, const REAL mutMax=16., const REAL mutMin=.125)
Set the refinement method to Parallel Tempering.
RefObjOpt mAnnealingScheduleMutation
Schedule for the annealing.
virtual void NewConfiguration(const RefParType *type=gpRefParTypeObjCryst)
Make a random change in the configuration.
MonteCarloObj()
Default Constructor.
virtual void UpdateDisplay() const
Update Display (if any display is available), when a new 'relevant' configuration is reached.
REAL mMutationAmplitudeMin
Mutation amplitude at the end of the optimization.
void RunParallelTempering(long &nbSteps, const bool silent=false, const REAL finalcost=0, const REAL maxTime=-1)
void RunSimulatedAnnealing(long &nbSteps, const bool silent=false, const REAL finalcost=0, const REAL maxTime=-1)
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.
REAL mTemperatureMin
Lower temperature.
REAL mCurrentCost
Current value of the cost function.
REAL mMinCostRetry
Cost to reach unless an automatic randomization and retry is done.
void SetAlgorithmSimulAnnealing(const AnnealingSchedule scheduleTemp, const REAL tMax, const REAL tMin, const AnnealingSchedule scheduleMutation=ANNEALING_CONSTANT, const REAL mutMax=16., const REAL mutMin=.125, const long nbTrialRetry=0, const REAL minCostRetry=0.)
Set the refinement method to simulated Annealing.
RefObjOpt mSaveTrackedData
Option to save the evolution of tracked data (cost functions, likelihhod, individual parameters,...
virtual void InitLSQ(const bool useFullPowderPatternProfile=true)
Prepare mLSQ for least-squares refinement during the global optimization.
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.
LSQNumObj & GetLSQObj()
Access to the builtin LSQ optimization object.
REAL mMutationAmplitudeMax
Mutation amplitude at the beginning of the optimization.
RefObjOpt mAnnealingScheduleTemp
Schedule for the annealing.
REAL mTemperatureGamma
Gamma for the 'gamma' temperature schedule.
RefObjOpt mGlobalOptimType
Method used for the global optimization.
REAL mMutationAmplitude
Mutation amplitude.
class to input or output a well-formatted xml beginning or ending tag.
(Quick & dirty) Least-Squares Refinement Object with Numerical derivatives
Definition: LSQNumObj.h:39
void SetParIsFixed(const std::string &parName, const bool fix)
Fix one parameter.
const std::map< RefinableObj *, unsigned int > & GetRefinedObjMap() const
Get the map of refined objects - this is a recursive list of all the objects that are taken into acco...
Definition: LSQNumObj.cpp:837
void Refine(int nbCycle=1, bool useLevenbergMarquardt=false, const bool silent=false, const bool callBeginEndOptimization=true, const float minChi2var=0.01)
Do the refinement.
Definition: LSQNumObj.cpp:106
void SetRefinedObj(RefinableObj &obj, const unsigned int LSQFuncIndex=0, const bool init=true, const bool recursive=false)
Choose the object to refine.
Definition: LSQNumObj.cpp:824
RefinableObj & GetCompiledRefinedObj()
Access to the RefinableObj which is the compilation of all parameters from the object supplied for op...
Definition: LSQNumObj.cpp:848
void PrepareRefParList(const bool copy_param=false)
Prepare the full parameter list for the refinement.
Definition: LSQNumObj.cpp:913
class of refinable parameter types.
Definition: RefinableObj.h:80
bool IsDescendantFromOrSameAs(const RefParType *type) const
Returns true if the parameter is a descendant of 'type'.
We need to record exactly when refinable objects have been modified for the last time (to avoid re-co...
Definition: RefinableObj.h:140
REAL GetMin() const
Minimum value allowed (if limited or periodic)
void MutateTo(const REAL newValue)
Change the current value to the given one.
REAL GetMax() const
Get the maximum value allowed (if limited)
REAL GetPeriod() const
Get the period (if periodic)
Base class for options.
Definition: RefinableObj.h:552
void XMLInput(istream &is, const XMLCrystTag &tag)
XMLInput From stream.
void XMLOutput(ostream &os, int indent=0) const
XMLOutput to stream in well-formed XML.
Object Registry.
Definition: RefinableObj.h:645
Generic Refinable Object.
Definition: RefinableObj.h:784
void RestoreParamSet(const unsigned long id)
Restore a saved set of values.
void AddPar(const RefinablePar &newRefPar)
Add a refinable parameter.
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
virtual const string & GetName() const
Name of the object.
void SetDeleteRefParInDestructor(const bool b)
Set this object not to delete its list of parameters when destroyed.
long GetNbPar() const
Total number of refinable parameter in the object.
void ResetParList()
Re-init the list of refinable parameters, removing all parameters.
void SaveParamSet(const unsigned long id) const
Save the current set of refined values over a previously-created set of saved values.
void PrepareForRefinement() const
Find which parameters are used and not fixed, for a refinement /optimization.
RefinablePar & GetParNotFixed(const long i)
Access all parameters in the order they were inputted, skipping fixed parameters.
const RefinableObjClock & GetRefParListClock() const
What was the last time a RefinablePar was added/removed ?
const CrystVector_REAL & GetParamSet(const unsigned long setId) const
Access one save refpar set.
void ClearParamSet(const unsigned long id) const
Erase the param set with the given id, releasing memory.
unsigned long CreateParamSet(const string name="") const
Save the current set of refined values in a new set.
const void EraseAllParamSet()
Erase all saved refpar sets.
virtual REAL GetLogLikelihood() const
Get -log(likelihood) of the current configuration for the object.
long GetNbParNotFixed() const
Total number of non-fixed parameters. Is initialized by PrepareForRefinement()
A class to hold all trackers.
Definition: Tracker.h:69
void SaveAll(std::ostream &out) const
Will save to a single file if all recorded trial numbers are the same Otherwise ?
Definition: Tracker.cpp:105
void ClearTrackers()
Removes all Trackers.
Definition: Tracker.cpp:88
void ClearValues()
Removes all stored values.
Definition: Tracker.cpp:97
void UpdateDisplay() const
Update display, if any.
Definition: Tracker.cpp:133
Tracker for objects (RefinableObj, Crystal, PowderPattern, RefPar,...)
Definition: Tracker.h:110
Simple chronometer class, with microsecond precision.
Definition: Chronometer.h:35
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:128
Class for Graphical interface to Monte-Carlo objects (Simulated Annealing, Parallel Tempering)