ROL
ROL_OptimizationSolver.hpp
Go to the documentation of this file.
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_OPTIMIZATIONSOLVER_HPP
45 #define ROL_OPTIMIZATIONSOLVER_HPP
46 
47 #include "ROL_Algorithm.hpp"
50 
51 #include "ROL_Stream.hpp"
52 
58 namespace ROL {
59 
60 template<class Real>
62 private:
63 
64  ROL::Ptr<Algorithm<Real> > algo_;
65  ROL::Ptr<Step<Real> > step_;
66  ROL::Ptr<StatusTest<Real> > status0_;
67  ROL::Ptr<CombinedStatusTest<Real> > status_;
68  ROL::Ptr<AlgorithmState<Real> > state_;
69 
70  ROL::Ptr<Vector<Real> > x_;
71  ROL::Ptr<Vector<Real> > g_;
72  ROL::Ptr<Vector<Real> > l_;
73  ROL::Ptr<Vector<Real> > c_;
74 
75  ROL::Ptr<Objective<Real> > obj_;
76  ROL::Ptr<BoundConstraint<Real> > bnd_;
77  ROL::Ptr<Constraint<Real> > con_;
78 
79  std::vector<std::string> output_;
80 
83  std::string stepname_;
84 
85  Real pen_;
86 
87 public:
88 
97  ROL::ParameterList &parlist ) {
98 
99  // Get optimization problem type: U, E, B, EB
101 
102  // Initialize AlgorithmState
103  state_ = ROL::makePtr<AlgorithmState<Real>>();
104 
105  // Get step name from parameterlist
106  stepname_ = parlist.sublist("Step").get("Type","Last Type (Dummy)");
107  stepType_ = StringToEStep(stepname_);
108 
109  // Set default algorithm if provided step is incompatible with problem type
111  switch ( problemType_ ) {
112  case TYPE_U:
113  stepType_ = STEP_TRUSTREGION; break;
114  case TYPE_B:
115  stepType_ = STEP_TRUSTREGION; break;
116  case TYPE_E:
117  stepType_ = STEP_COMPOSITESTEP; break;
118  case TYPE_EB:
120  case TYPE_LAST:
121  default:
122  throw Exception::NotImplemented(">>> ROL::OptimizationSolver: Unknown problem type!");
123  }
124  }
125  stepname_ = EStepToString(stepType_);
126 
127  // Build status test
128  StatusTestFactory<Real> statusTestFactory;
129  status0_ = statusTestFactory.getStatusTest(stepname_,parlist);
130  status_ = ROL::makePtr<CombinedStatusTest<Real>>();
131 
132  // Get optimization vector and a vector for the gradient
133  x_ = opt.getSolutionVector();
134  g_ = x_->dual().clone();
135 
136  // Initialize Step
138  step_ = stepFactory.getStep(stepname_,parlist);
139 
140  // If there is an equality constraint, get the multiplier and create a constraint vector
141  if( problemType_ == TYPE_E || problemType_ == TYPE_EB ) {
142  l_ = opt.getMultiplierVector();
143  c_ = l_->dual().clone();
144  }
145 
146  // Create modified objectives if needed
147  const Real one(1), ten(10);
149  ROL::Ptr<Objective<Real> > raw_obj = opt.getObjective();
150  con_ = opt.getConstraint();
151  // TODO: Provide access to change initial penalty
152  obj_ = ROL::makePtr<AugmentedLagrangian<Real>>(raw_obj,con_,*l_,1.0,*x_,*c_,parlist);
153  bnd_ = opt.getBoundConstraint();
154  pen_ = parlist.sublist("Step").sublist("Augmented Lagrangian").get("Initial Penalty Parameter",ten);
155  }
156  else if( stepType_ == STEP_MOREAUYOSIDAPENALTY ) {
157  ROL::Ptr<Objective<Real> > raw_obj = opt.getObjective();
158  bnd_ = opt.getBoundConstraint();
159  con_ = opt.getConstraint();
160  // TODO: Provide access to change initial penalty
161  obj_ = ROL::makePtr<MoreauYosidaPenalty<Real>>(raw_obj,bnd_,*x_,parlist);
162  pen_ = parlist.sublist("Step").sublist("Moreau-Yosida Penalty").get("Initial Penalty Parameter",ten);
163  }
164  else if( stepType_ == STEP_INTERIORPOINT ) {
165  ROL::Ptr<Objective<Real> > raw_obj = opt.getObjective();
166  bnd_ = opt.getBoundConstraint();
167  con_ = opt.getConstraint();
168  // TODO: Provide access to change initial penalty
169  obj_ = ROL::makePtr<InteriorPoint::PenalizedObjective<Real>>(raw_obj,bnd_,*x_,parlist);
170  pen_ = parlist.sublist("Step").sublist("Interior Point").get("Initial Barrier Parameter",ten);
171  }
172  else if( stepType_ == STEP_FLETCHER ) {
173  ROL::Ptr<Objective<Real> > raw_obj = opt.getObjective();
174  bnd_ = opt.getBoundConstraint();
175  con_ = opt.getConstraint();
176  if( bnd_->isActivated() ) {
177  obj_ = ROL::makePtr<BoundFletcher<Real> >(raw_obj,con_,bnd_,*x_,*c_,parlist);
178  }
179  else {
180  obj_ = ROL::makePtr<Fletcher<Real> >(raw_obj,con_,*x_,*c_,parlist);
181  }
182  pen_ = parlist.sublist("Step").sublist("Fletcher").get("Penalty Parameter",one);
183  }
184  else {
185  obj_ = opt.getObjective();
186  bnd_ = opt.getBoundConstraint();
187  con_ = opt.getConstraint();
188  if( stepType_ == STEP_TRUSTREGION ) {
189  pen_ = parlist.sublist("Step").sublist("Trust Region").get("Initial Radius",ten);
190  }
191  else if( stepType_ == STEP_BUNDLE ) {
192  pen_ = parlist.sublist("Step").sublist("Bundle").get("Initial Trust-Region Parameter",ten);
193  }
194  }
195  }
196 
201  std::vector<std::string> getOutput(void) const {
202  return output_;
203  }
204 
212  int solve(const ROL::Ptr<StatusTest<Real> > &status = ROL::nullPtr,
213  const bool combineStatus = true) {
214  ROL::nullstream bhs;
215  return solve(bhs,status,combineStatus);
216  }
217 
226  int solve( std::ostream &outStream,
227  const ROL::Ptr<StatusTest<Real> > &status = ROL::nullPtr,
228  const bool combineStatus = true ) {
229  // Build algorithm
230  status_->reset(); // Clear previous status test
231  status_->add(status0_); // Default StatusTest
232  if (status != ROL::nullPtr) {
233  if (!combineStatus) { // Use only user-defined StatusTest
234  status_->reset();
235  }
236  status_->add(status); // Add user-defined StatusTest
237  }
238  algo_ = ROL::makePtr<Algorithm<Real>>( step_, status_, state_ );
239 
240  switch(problemType_) {
241  case TYPE_U:
242  output_ = algo_->run(*x_,*g_,*obj_,true,outStream);
243  break;
244  case TYPE_B:
245  output_ = algo_->run(*x_,*g_,*obj_,*bnd_,true,outStream);
246  break;
247  case TYPE_E:
248  output_ = algo_->run(*x_,*g_,*l_,*c_,*obj_,*con_,true,outStream);
249  break;
250  case TYPE_EB:
251  output_ = algo_->run(*x_,*g_,*l_,*c_,*obj_,*con_,*bnd_,true,outStream);
252  break;
253  case TYPE_LAST:
254  ROL_TEST_FOR_EXCEPTION(true,std::invalid_argument,
255  "Error in OptimizationSolver::solve() : Unsupported problem type");
256  break;
257  }
258 
259  // TODO: Interrogate AlgorithmState and StatusTest to generate a return code
260  // that indicates why the solver has stopped
261 
262  // Return an integer code
263  return 0;
264  }
265 
270  ROL::Ptr<const AlgorithmState<Real> > getAlgorithmState(void) const {
271  return state_;
272  }
273 
280  void resetAlgorithmState(void) {
281  state_ = ROL::makePtr<AlgorithmState<Real>>();
282  }
283 
295  void reset(const bool resetAlgo = true) {
296  // Reset AlgorithmState
297  if (resetAlgo) {
299  }
300  // Reset StepState
301  step_->reset(pen_);
302  // Reset penalty objectives
304  ROL::dynamicPtrCast<AugmentedLagrangian<Real> >(obj_)->reset(*l_,pen_);
305  }
306  else if( stepType_ == STEP_MOREAUYOSIDAPENALTY ) {
307  ROL::dynamicPtrCast<MoreauYosidaPenalty<Real> >(obj_)->reset(pen_);
308  }
309  else if( stepType_ == STEP_INTERIORPOINT ) {
310  ROL::dynamicPtrCast<InteriorPoint::PenalizedObjective<Real> >(obj_)->updatePenalty(pen_);
311  }
312  }
313 
322  std::string getStepName(void) const {
323  return stepname_;
324  }
325 
326 }; // class OptimizationSolver
327 
328 } // namespace ROL
329 
330 #endif // ROL_OPTIMIZATIONSOLVER_HPP
331 
332 
ROL::Ptr< BoundConstraint< Real > > bnd_
ROL::Ptr< Objective< Real > > obj_
ROL::Ptr< StatusTest< Real > > getStatusTest(const std::string step, ROL::ParameterList &parlist)
EStep StringToEStep(std::string s)
Definition: ROL_Types.hpp:389
ROL::Ptr< StatusTest< Real > > status0_
void stepFactory(ROL::ParameterList &parlist, ROL::Ptr< ROL::Step< Real > > &step)
A minimalist step factory which specializes the Step Type depending on whether a Trust-Region or Line...
ROL::Ptr< Step< Real > > getStep(const std::string &type, ROL::ParameterList &parlist) const
virtual Ptr< Objective< Real > > getObjective(void)
std::vector< std::string > output_
virtual Ptr< BoundConstraint< Real > > getBoundConstraint(void)
ROL::Ptr< Vector< Real > > c_
int solve(std::ostream &outStream, const ROL::Ptr< StatusTest< Real > > &status=ROL::nullPtr, const bool combineStatus=true)
Solve optimization problem.
ROL::Ptr< Step< Real > > step_
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
ROL::Ptr< Vector< Real > > g_
ROL::Ptr< CombinedStatusTest< Real > > status_
ROL::Ptr< Constraint< Real > > con_
std::vector< std::string > getOutput(void) const
Returns iteration history as a vector of strings.
void reset(const bool resetAlgo=true)
Reset both Algorithm and Step.
virtual Ptr< Vector< Real > > getSolutionVector(void)
Provides an interface to check status of optimization algorithms.
virtual Ptr< Vector< Real > > getMultiplierVector(void)
ROL::Ptr< Algorithm< Real > > algo_
Provides a simplified interface for solving a wide range of optimization problems.
ROL::Ptr< Vector< Real > > x_
std::string getStepName(void) const
Grab step name (after check for consistency).
basic_nullstream< char, char_traits< char >> nullstream
Definition: ROL_Stream.hpp:72
void resetAlgorithmState(void)
Reset the AlgorithmState.
ROL::Ptr< Vector< Real > > l_
int solve(const ROL::Ptr< StatusTest< Real > > &status=ROL::nullPtr, const bool combineStatus=true)
Solve optimization problem with no iteration output.
std::string EStepToString(EStep tr)
Definition: ROL_Types.hpp:287
EStep
Enumeration of step types.
Definition: ROL_Types.hpp:274
ROL::Ptr< AlgorithmState< Real > > state_
EProblem
Definition: ROL_Types.hpp:255
OptimizationSolver(OptimizationProblem< Real > &opt, ROL::ParameterList &parlist)
Constructor.
ROL::Ptr< const AlgorithmState< Real > > getAlgorithmState(void) const
Return the AlgorithmState.
virtual Ptr< Constraint< Real > > getConstraint(void)
bool isCompatibleStep(EProblem p, EStep s)
Definition: ROL_Types.hpp:305