1 // @HEADER
2 // ************************************************************************
3 //
4 //               Rapid Optimization Library (ROL) Package
5 //                 Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 //              Drew Kouri   (dpkouri@sandia.gov) and
39 //              Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #ifndef ROL_ALGORITHM_H
45 #define ROL_ALGORITHM_H
46 
47 #include "ROL_Types.hpp"
48 #include "ROL_Step.hpp"
49 #include "ROL_StatusTest.hpp"
50 #include "ROL_Objective.hpp"
51 #include "ROL_BoundConstraint.hpp"
52 #include "ROL_Constraint.hpp"
53 #include "ROL_ValidParameters.hpp"
54 
55 /** \class ROL::Algorithm
56     \brief Provides an interface to run optimization algorithms.
57 */
58 
59 
60 namespace ROL {
61 
62 template <class Real>
63 class Algorithm {
64 private:
65   ROL::Ptr<Step<Real> >           step_;
66   ROL::Ptr<StatusTest<Real> >     status_;
67   ROL::Ptr<AlgorithmState<Real> > state_;
68 
69   bool printHeader_;
70 
71 public:
72 
~Algorithm()73   virtual ~Algorithm() {}
74 
75   /** \brief Constructor, given a step and a status test.
76   */
Algorithm(const ROL::Ptr<Step<Real>> & step,const ROL::Ptr<StatusTest<Real>> & status,bool printHeader=false)77   Algorithm( const ROL::Ptr<Step<Real> > & step,
78              const ROL::Ptr<StatusTest<Real> > & status,
79              bool printHeader = false ) {
80     step_ = step;
81     status_ = status;
82     state_ = ROL::makePtr<AlgorithmState<Real>>();
83     printHeader_ = printHeader;
84   }
85 
86   /** \brief Constructor, given a step, a status test, and a
87              previously defined algorithm state.
88   */
Algorithm(const ROL::Ptr<Step<Real>> & step,const ROL::Ptr<StatusTest<Real>> & status,const ROL::Ptr<AlgorithmState<Real>> & state,bool printHeader=false)89   Algorithm( const ROL::Ptr<Step<Real> > & step,
90              const ROL::Ptr<StatusTest<Real> > & status,
91              const ROL::Ptr<AlgorithmState<Real> > & state,
92              bool printHeader = false ) {
93     step_ = step;
94     status_ = status;
95     state_ = state;
96     printHeader_ = printHeader;
97   }
98 
99   /** \brief Run algorithm on unconstrained problems (Type-U).
100              This is the primary Type-U interface.
101   */
run(Vector<Real> & x,Objective<Real> & obj,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)102   virtual std::vector<std::string> run( Vector<Real>      &x,
103                                         Objective<Real>   &obj,
104                                         bool              print = false,
105                                         std::ostream      &outStream = std::cout,
106                                         bool              printVectors = false,
107                                         std::ostream      &vectorStream = std::cout ) {
108     BoundConstraint<Real> bnd;
109     bnd.deactivate();
110     return run(x,x.dual(),obj,bnd,print,outStream,printVectors,vectorStream);
111   }
112 
113   /** \brief Run algorithm on unconstrained problems (Type-U).
114              This general interface supports the use of dual optimization vector spaces,
115              where the user does not define the dual() method.
116   */
run(Vector<Real> & x,const Vector<Real> & g,Objective<Real> & obj,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)117   virtual std::vector<std::string> run( Vector<Real>       &x,
118                                         const Vector<Real> &g,
119                                         Objective<Real>    &obj,
120                                         bool               print = false,
121                                         std::ostream       &outStream = std::cout,
122                                         bool               printVectors = false,
123                                         std::ostream       &vectorStream = std::cout ) {
124     BoundConstraint<Real> bnd;
125     bnd.deactivate();
126     return run(x,g,obj,bnd,print,outStream,printVectors,vectorStream);
127   }
128 
129   /** \brief Run algorithm on bound constrained problems (Type-B).
130              This is the primary Type-B interface.
131   */
run(Vector<Real> & x,Objective<Real> & obj,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)132   virtual std::vector<std::string> run( Vector<Real>          &x,
133                                         Objective<Real>       &obj,
134                                         BoundConstraint<Real> &bnd,
135                                         bool                  print = false,
136                                         std::ostream          &outStream = std::cout,
137                                         bool                  printVectors = false,
138                                         std::ostream          &vectorStream = std::cout ) {
139     return run(x,x.dual(),obj,bnd,print,outStream,printVectors,vectorStream);
140   }
141 
142   /** \brief Run algorithm on bound constrained problems (Type-B).
143              This general interface supports the use of dual optimization vector spaces,
144              where the user does not define the dual() method.
145   */
run(Vector<Real> & x,const Vector<Real> & g,Objective<Real> & obj,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)146   virtual std::vector<std::string> run( Vector<Real>          &x,
147                                         const Vector<Real>    &g,
148                                         Objective<Real>       &obj,
149                                         BoundConstraint<Real> &bnd,
150                                         bool                  print = false,
151                                         std::ostream          &outStream = std::cout,
152                                         bool                  printVectors = false,
153                                         std::ostream          &vectorStream = std::cout ) {
154     if(printVectors) {
155       x.print(vectorStream);
156     }
157 
158     std::vector<std::string> output;
159 
160     // Initialize Current Iterate Container
161     if ( state_->iterateVec == ROL::nullPtr ) {
162       state_->iterateVec = x.clone();
163     }
164     state_->iterateVec->set(x);
165 
166     // Initialize Step Container
167     ROL::Ptr<Vector<Real> > s = x.clone();
168 
169     // Initialize Step
170     step_->initialize(x, g, obj, bnd, *state_);
171     output.push_back(step_->print(*state_,true));
172     if ( print ) {
173       outStream << step_->print(*state_,true);
174     }
175 
176     // Initialize Minimum Value and Vector
177     if ( state_->minIterVec == ROL::nullPtr ) {
178       state_->minIterVec = x.clone();
179     }
180     state_->minIterVec->set(x);
181     state_->minIter = state_->iter;
182     state_->minValue = state_->value;
183 
184     // Run Algorithm
185     while (status_->check(*state_)) {
186       step_->compute(*s, x, obj, bnd, *state_);
187       step_->update(x, *s, obj, bnd, *state_);
188 
189       if( printVectors ) {
190         x.print(vectorStream);
191       }
192 
193       // Store Minimal Value and Vector
194       if ( state_->minValue > state_->value ) {
195         state_->minIterVec->set(*(state_->iterateVec));
196         state_->minValue = state_->value;
197         state_->minIter = state_->iter;
198       }
199       // Update Output
200       output.push_back(step_->print(*state_,printHeader_));
201       if ( print ) {
202         outStream << step_->print(*state_,printHeader_);
203       }
204     }
205     std::stringstream hist;
206     hist << "Optimization Terminated with Status: ";
207     hist << EExitStatusToString(state_->statusFlag);
208     hist << "\n";
209     output.push_back(hist.str());
210     if ( print ) {
211       outStream << hist.str();
212     }
213     return output;
214   }
215 
216 
217   /** \brief Run algorithm on equality constrained problems (Type-E).
218              This is the primary Type-E interface.
219   */
run(Vector<Real> & x,Vector<Real> & l,Objective<Real> & obj,Constraint<Real> & con,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)220   virtual std::vector<std::string> run( Vector<Real>             &x,
221                                         Vector<Real>             &l,
222                                         Objective<Real>          &obj,
223                                         Constraint<Real>         &con,
224                                         bool                     print = false,
225                                         std::ostream             &outStream = std::cout,
226                                         bool                     printVectors = false,
227                                         std::ostream             &vectorStream = std::cout ) {
228 
229     return run(x, x.dual(), l, l.dual(), obj, con, print, outStream, printVectors, vectorStream);
230 
231   }
232 
233 
234   /** \brief Run algorithm on equality constrained problems (Type-E).
235              This general interface supports the use of dual optimization and
236              constraint vector spaces, where the user does not define the dual() method.
237   */
run(Vector<Real> & x,const Vector<Real> & g,Vector<Real> & l,const Vector<Real> & c,Objective<Real> & obj,Constraint<Real> & con,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)238   virtual std::vector<std::string> run( Vector<Real>             &x,
239                                         const Vector<Real>       &g,
240                                         Vector<Real>             &l,
241                                         const Vector<Real>       &c,
242                                         Objective<Real>          &obj,
243                                         Constraint<Real>         &con,
244                                         bool                     print = false,
245                                         std::ostream             &outStream = std::cout,
246                                         bool                     printVectors = false,
247                                         std::ostream             &vectorStream = std::cout ) {
248     if( printVectors ) {
249       x.print(vectorStream);
250     }
251 
252     std::vector<std::string> output;
253 
254     // Initialize Current Iterate Container
255     if ( state_->iterateVec == ROL::nullPtr ) {
256       state_->iterateVec = x.clone();
257     }
258     state_->iterateVec->set(x);
259 
260     // Initialize Current Lagrange Multiplier Container
261     if ( state_->lagmultVec == ROL::nullPtr ) {
262       state_->lagmultVec = l.clone();
263     }
264     state_->lagmultVec->set(l);
265 
266     // Initialize Step Container
267     ROL::Ptr<Vector<Real> > s = x.clone();
268 
269     // Initialize Step
270     step_->initialize(x, g, l, c, obj, con, *state_);
271     output.push_back(step_->print(*state_,true));
272     if ( print ) {
273       outStream << step_->print(*state_,true);
274     }
275 
276     // Initialize Minimum Value and Vector
277     if ( state_->minIterVec == ROL::nullPtr ) {
278       state_->minIterVec = x.clone();
279     }
280     state_->minIterVec->set(x);
281     state_->minIter = state_->iter;
282     state_->minValue = state_->value;
283 
284     // Run Algorithm
285     while (status_->check(*state_)) {
286       step_->compute(*s, x, l, obj, con, *state_);
287       step_->update(x, l, *s, obj, con, *state_);
288 
289       if( printVectors ) {
290         x.print(vectorStream);
291       }
292 
293       output.push_back(step_->print(*state_,printHeader_));
294       if ( print ) {
295         outStream << step_->print(*state_,printHeader_);
296       }
297     }
298     std::stringstream hist;
299     hist << "Optimization Terminated with Status: ";
300     hist << EExitStatusToString(state_->statusFlag);
301     hist << "\n";
302     output.push_back(hist.str());
303     if ( print ) {
304       outStream << hist.str();
305     }
306     return output;
307   }
308 
309   /** \brief Run algorithm on equality and bound constrained problems (Type-EB).
310              This is the primary Type-EB interface.
311   */
run(Vector<Real> & x,Vector<Real> & l,Objective<Real> & obj,Constraint<Real> & con,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)312   virtual std::vector<std::string> run( Vector<Real>             &x,
313                                         Vector<Real>             &l,
314                                         Objective<Real>          &obj,
315                                         Constraint<Real>         &con,
316                                         BoundConstraint<Real>    &bnd,
317                                         bool                     print = false,
318                                         std::ostream             &outStream = std::cout,
319                                         bool                     printVectors = false,
320                                         std::ostream             &vectorStream = std::cout) {
321     return run(x,x.dual(),l,l.dual(),obj,con,bnd,print,outStream,printVectors,vectorStream);
322   }
323 
324   /** \brief Run algorithm on equality and bound constrained problems (Type-EB).
325              This general interface supports the use of dual optimization and
326              constraint vector spaces, where the user does not define the dual() method.
327   */
run(Vector<Real> & x,const Vector<Real> & g,Vector<Real> & l,const Vector<Real> & c,Objective<Real> & obj,Constraint<Real> & con,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)328   virtual std::vector<std::string> run( Vector<Real>             &x,
329                                         const Vector<Real>       &g,
330                                         Vector<Real>             &l,
331                                         const Vector<Real>       &c,
332                                         Objective<Real>          &obj,
333                                         Constraint<Real>         &con,
334                                         BoundConstraint<Real>    &bnd,
335                                         bool                     print = false,
336                                         std::ostream             &outStream = std::cout,
337                                         bool                     printVectors = false,
338                                         std::ostream             &vectorStream = std::cout ) {
339     if(printVectors) {
340       x.print(vectorStream);
341     }
342 
343     std::vector<std::string> output;
344 
345     // Initialize Current Iterate Container
346     if ( state_->iterateVec == ROL::nullPtr ) {
347       state_->iterateVec = x.clone();
348     }
349     state_->iterateVec->set(x);
350 
351     // Initialize Current Lagrange Multiplier Container
352     if ( state_->lagmultVec == ROL::nullPtr ) {
353       state_->lagmultVec = l.clone();
354     }
355     state_->lagmultVec->set(l);
356 
357     // Initialize Step Container
358     ROL::Ptr<Vector<Real> > s = x.clone();
359 
360     // Initialize Step
361     step_->initialize(x, g, l, c, obj, con, bnd, *state_);
362     output.push_back(step_->print(*state_,true));
363     if ( print ) {
364       outStream << step_->print(*state_,true);
365     }
366 
367     // Initialize Minimum Value and Vector
368     if ( state_->minIterVec == ROL::nullPtr ) {
369       state_->minIterVec = x.clone();
370     }
371     state_->minIterVec->set(x);
372     state_->minIter = state_->iter;
373     state_->minValue = state_->value;
374 
375     // Run Algorithm
376     while (status_->check(*state_)) {
377       step_->compute(*s, x, l, obj, con, bnd, *state_);
378       step_->update(x, l, *s, obj, con, bnd, *state_);
379       if( printVectors ) {
380         x.print(vectorStream);
381       }
382       output.push_back(step_->print(*state_,printHeader_));
383       if ( print ) {
384         outStream << step_->print(*state_,printHeader_);
385       }
386     }
387     std::stringstream hist;
388     hist << "Optimization Terminated with Status: ";
389     hist << EExitStatusToString(state_->statusFlag);
390     hist << "\n";
391     output.push_back(hist.str());
392     if ( print ) {
393       outStream << hist.str();
394     }
395     return output;
396   }
397 
getIterHeader(void)398   std::string getIterHeader(void) {
399     return step_->printHeader();
400   }
401 
getIterInfo(bool withHeader=false)402   std::string getIterInfo(bool withHeader = false) {
403     return step_->print(*state_,withHeader);
404   }
405 
getState(void) const406   ROL::Ptr<const AlgorithmState<Real> > getState(void) const {
407     return state_;
408   }
409 
reset(void)410   void reset(void) {
411     state_->reset();
412   }
413 
414 
415 
416 
417 
418 
419 }; // class Algorithm
420 
421 
422 } // namespace ROL
423 
424 #endif
425