NOMAD Source  Version 4.0.0 Beta
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NMUpdate.cpp
Go to the documentation of this file.
1 
2 #include "../../Algos/NelderMead/NMUpdate.hpp"
3 
4 #include "../../Algos/NelderMead/NMMegaIteration.hpp"
5 #include "../../Algos/NelderMead/NMIteration.hpp"
6 
7 #include "../../Algos/CacheInterface.hpp"
8 
9 #include "../../Output/OutputInfo.hpp"
10 
11 void NOMAD::NMUpdate::init()
12 {
13  _name = "NM update";
14  verifyParentNotNull();
15 
16 }
17 
18 void NOMAD::NMUpdate::start()
19 {
20  defaultStart();
21 }
22 
23 bool NOMAD::NMUpdate::run()
24 {
25 
26  const NOMAD::NMIteration * iter = dynamic_cast<const NOMAD::NMIteration*>(getParentOfType<NOMAD::NMIteration*>());
27  if (nullptr == iter)
28  {
29  throw NOMAD::Exception(__FILE__,__LINE__,"Update must have a NMIteration among its ancestors.");
30  }
31 
32  if ( iter->getY()->size() == 0 )
33  {
34  AddOutputDebug("No need to update because NM simplex is empty");
35  return true;
36  }
37 
38  const NOMAD::NMMegaIteration * megaIter = dynamic_cast<const NOMAD::NMMegaIteration*>(getParentOfType<NOMAD::NMMegaIteration*>());
39 
40  // megaIter barrier is already in subproblem.
41  // So no need to convert refBestFeas and refBestInf
42  // from full dimension to subproblem.
43  auto barrier = megaIter->getBarrier();
44 
45  if (NOMAD::CacheBase::getInstance()->size() > 1)
46  {
47  // Remember previous values
48  auto refBestFeas = barrier->getFirstXFeas();
49  auto refBestInf = barrier->getFirstXInf();
50 
51  // Update Best feasible and infeasible with cache.
52  updateBestInBarrier(true);
53  updateBestInBarrier(false);
54 
55  // Compute success
56  NOMAD::EvalPointPtr newBestFeas = barrier->getFirstXFeas();
57  NOMAD::EvalPointPtr newBestInf = barrier->getFirstXInf();
58 
59  NOMAD::SuccessType success = NOMAD::SuccessType::NOT_EVALUATED;
60  std::shared_ptr<NOMAD::EvalPoint> newBest;
61 
62  // Get which of newBestFeas and newBestInf is improving
63  // the solution. Check newBestFeas first.
64  NOMAD::ComputeSuccessType computeSuccess;
65  success = computeSuccess(newBestFeas, refBestFeas);
66  if (success >= NOMAD::SuccessType::PARTIAL_SUCCESS)
67  {
68  // newBestFeas is the improving point.
69  newBest = newBestFeas;
70  // Output Warning: When using '\n', the computed indentation for the
71  // Step will be ignored. Leaving it like this for now. Using an
72  // OutputInfo with AddMsg() would resolve the output layout.
73  AddOutputDebug("Update: improving feasible point");
74  if (refBestFeas)
75  {
76  AddOutputDebug(" from " + refBestFeas->display() );
77  }
78  AddOutputDebug( " to " + newBestFeas->display() );
79  }
80  else
81  {
82  // Check newBestInf
83  NOMAD::SuccessType success2 = computeSuccess(newBestInf, refBestInf);
84  if (success2 > success)
85  {
86  success = success2;
87  }
88  if (success >= NOMAD::SuccessType::PARTIAL_SUCCESS)
89  {
90  // newBestInf is the improving point.
91  newBest = newBestInf;
92  AddOutputDebug("Update: improving infeasible point");
93  if (refBestInf)
94  {
95  AddOutputDebug(" from " + refBestInf->display() );
96  }
97  AddOutputDebug(" to " + newBestInf->display());
98 
99  }
100  }
101  if (success == NOMAD::SuccessType::UNSUCCESSFUL)
102  {
103  std::string s = "Update: no success found";
104  AddOutputDebug(s);
105  }
106 
107  if (success >= NOMAD::SuccessType::PARTIAL_SUCCESS)
108  {
109  // Compute new direction for main mesh.
110  // The direction is related to the frame center which generated
111  // newBest.
112  auto pointFromPtr = newBest->getPointFrom();
113  // TODO: Make getX() return a shared_ptr!!
114  auto pointNewPtr = newBest->getX();
115  if (nullptr == pointFromPtr)
116  {
117  std::string s = "Update cannot compute new direction for successful point: pointFromPtr is NULL ";
118  s += newBest->display();
119  throw NOMAD::Exception(__FILE__,__LINE__, s);
120  }
121  // PointFrom is in full dimension. Convert it to subproblem
122  // to compute direction.
123  auto fixedVariable = _parentStep->getSubFixedVariable();
124  auto pointFromSub = std::make_shared<NOMAD::Point>(pointFromPtr->makeSubSpacePointFromFixed(fixedVariable));
125 
126  NOMAD::Direction dir = NOMAD::Point::vectorize(*pointFromSub, *pointNewPtr);
127  std::string dirStr = "New direction " + dir.display();
128  AddOutputInfo(dirStr);
129 
130  AddOutputInfo("Last NM step Successful.");
131  }
132  else
133  {
134  AddOutputInfo("Last NM step Unsuccessful.");
135  }
136  }
137 
138  return true;
139 }
140 
141 
142 void NOMAD::NMUpdate::updateBestInBarrier(bool feasible)
143 {
144  std::vector<NOMAD::EvalPoint> evalPointList;
145  auto barrier = getMegaIterationBarrier();
146 
147  NOMAD::Double hMax = 0.0;
148  if (!feasible)
149  {
150  hMax = barrier->getHMax();
151  }
152  // Find best points in cache.
153  NOMAD::CacheInterface cacheInterface(this);
154  if (feasible)
155  {
156  cacheInterface.findBestFeas(evalPointList, getSubFixedVariable());
157  }
158  else
159  {
160  cacheInterface.findBestInf(evalPointList, hMax, getSubFixedVariable());
161  }
162 
163  // Debug info
164  std::string s = "Found " + std::to_string(evalPointList.size());
165  s += (feasible) ? " feasible " : " infeasible ";
166  s += "best points";
167  NOMAD::OutputInfo outputInfo(_name, s, NOMAD::OutputLevel::LEVEL_DEBUG);
168  for (auto evalPoint : evalPointList)
169  {
170  outputInfo.addMsg(evalPoint.display());
171  }
172  NOMAD::OutputQueue::Add(std::move(outputInfo));
173 
174  if (_runParams->getAttributeValue<bool>("POLL_CENTER_USE_CACHE"))
175  {
176  // Clear barrier and add newly found points.
177  // Note: evalPoint for MegaIteration Barrier are in subspace - not full dimension.
178  // The points in evalPointList are also in subspace, thanks to the cacheInterface.
179  if (feasible)
180  {
181  barrier->clearXFeas();
182  for (auto evalPoint : evalPointList)
183  {
184  barrier->addXFeas(std::make_shared<NOMAD::EvalPoint>(evalPoint));
185  }
186  }
187  else
188  {
189  barrier->clearXInf();
190  for (auto evalPoint : evalPointList)
191  {
192  barrier->addXInf(std::make_shared<NOMAD::EvalPoint>(evalPoint));
193  }
194  }
195  }
196 
197  else
198  {
199  // If the found points have the same value as the one in the barrier,
200  // we want to keep the one that is already in the barrier.
201  if (evalPointList.size() > 0)
202  {
203  NOMAD::EvalPointPtr newBest = std::make_shared<NOMAD::EvalPoint>(evalPointList[0]);
204  NOMAD::EvalPointPtr refBest = (feasible) ? barrier->getFirstXFeas() : barrier->getFirstXInf();
205  NOMAD::ComputeSuccessType computeSuccess;
206  bool doUpdateBarrier = false;
207  if (nullptr == refBest)
208  {
209  // No previous point. Update the barrier.
210  doUpdateBarrier = true;
211  }
212  else if (computeSuccess(newBest, refBest) >= NOMAD::SuccessType::PARTIAL_SUCCESS)
213  {
214  // Dominance. Update the barrier.
215  doUpdateBarrier = true;
216  }
217  else if (computeSuccess(refBest, newBest) == NOMAD::SuccessType::UNSUCCESSFUL)
218  {
219  // No point dominates the other. Do not update the Barrier - unless it has too many
220  // points (due to initialization).
221  size_t nbPoints = (feasible) ? barrier->getAllXFeas().size() : barrier->getAllXInf().size();
222  if (nbPoints > 1)
223  {
224  doUpdateBarrier = true;
225  }
226  }
227  else
228  {
229  // If we end up here, it means that refBest dominates newBest.
230  // There is a problem.
231  std::string s = "Warning: Previous frame center is better than current.";
232  s += "\nPrevious frame center: " + refBest->display();
233  s += "\nCurrent frame center: " + newBest->display();
234  AddOutputWarning(s);
235  }
236 
237  if (doUpdateBarrier)
238  {
239  if (feasible)
240  {
241  barrier->clearXFeas();
242  barrier->addXFeas(newBest);
243  }
244  else
245  {
246  barrier->clearXInf();
247  barrier->addXInf(newBest);
248  }
249  }
250  }
251  }
252 }
253 
254 
255 void NOMAD::NMUpdate::end()
256 {
257  defaultEnd();
258 }
std::shared_ptr< EvalPoint > EvalPointPtr
Definition for eval point pointer.
Definition: EvalPoint.hpp:284
SuccessType
Success type of an iteration.
Definition: defines.hpp:107