ROL
ROL_AugmentedLagrangian.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_AUGMENTEDLAGRANGIAN_H
45 #define ROL_AUGMENTEDLAGRANGIAN_H
46 
47 #include "ROL_Objective.hpp"
48 #include "ROL_Constraint.hpp"
49 #include "ROL_QuadraticPenalty.hpp"
50 #include "ROL_Vector.hpp"
51 #include "ROL_Types.hpp"
52 #include "ROL_Ptr.hpp"
53 #include <iostream>
54 
83 namespace ROL {
84 
85 template <class Real>
86 class AugmentedLagrangian : public Objective<Real> {
87 private:
88  // Required for Augmented Lagrangian definition
89  const ROL::Ptr<Objective<Real> > obj_;
90  ROL::Ptr<QuadraticPenalty<Real> > pen_;
92 
93  // Auxiliary storage
94  ROL::Ptr<Vector<Real> > dualOptVector_;
95 
96  // Objective and constraint evaluations
97  Real fval_;
98  ROL::Ptr<Vector<Real> > gradient_;
99 
100  // Objective function scaling
101  Real fscale_;
102 
103  // Evaluation counters
104  int nfval_;
105  int ngval_;
106 
107  // User defined options
109 
110  // Flags to recompute quantities
113 
114 public:
126  AugmentedLagrangian(const ROL::Ptr<Objective<Real> > &obj,
127  const ROL::Ptr<Constraint<Real> > &con,
128  const Vector<Real> &multiplier,
129  const Real penaltyParameter,
130  const Vector<Real> &optVec,
131  const Vector<Real> &conVec,
132  ROL::ParameterList &parlist)
133  : obj_(obj), penaltyParameter_(penaltyParameter),
134  fval_(0), fscale_(1),
135  nfval_(0), ngval_(0),
136  isValueComputed_(false), isGradientComputed_(false) {
137 
138  gradient_ = optVec.dual().clone();
139  dualOptVector_ = optVec.dual().clone();
140 
141  ROL::ParameterList& sublist = parlist.sublist("Step").sublist("Augmented Lagrangian");
142  scaleLagrangian_ = sublist.get("Use Scaled Augmented Lagrangian", false);
143  int HessianApprox = sublist.get("Level of Hessian Approximation", 0);
144 
145  pen_ = ROL::makePtr<QuadraticPenalty<Real>>(con,multiplier,penaltyParameter,optVec,conVec,scaleLagrangian_,HessianApprox);
146  }
147 
154  : obj_(ROL::nullPtr), pen_(ROL::nullPtr), dualOptVector_(ROL::nullPtr),
155  fval_(0), gradient_(ROL::nullPtr), fscale_(1),
156  nfval_(0), ngval_(0),
157  scaleLagrangian_(false), isValueComputed_(false), isGradientComputed_(false) {}
158 
159  virtual void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
160  obj_->update(x,flag,iter);
161  pen_->update(x,flag,iter);
162  isValueComputed_ = (flag ? false : isValueComputed_);
163  isGradientComputed_ = (flag ? false : isGradientComputed_);
164  }
165 
166  void setScaling(const Real fscale, const Real cscale = 1.0) {
167  fscale_ = fscale;
168  pen_->setScaling(cscale);
169  }
170 
171  virtual Real value( const Vector<Real> &x, Real &tol ) {
172  // Compute objective function value
173  if ( !isValueComputed_ ) {
174  fval_ = obj_->value(x,tol); nfval_++;
175  isValueComputed_ = true;
176  }
177  // Compute penalty term
178  Real pval = pen_->value(x,tol);
179  // Compute augmented Lagrangian
180  Real val = fscale_*fval_;
181  if (scaleLagrangian_) {
182  val /= penaltyParameter_;
183  }
184  return val + pval;
185  }
186 
187  virtual void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
188  // Compute objective function gradient
189  if ( !isGradientComputed_ ) {
190  obj_->gradient(*gradient_,x,tol); ngval_++;
191  isGradientComputed_ = true;
192  }
193  g.set(*gradient_);
194  g.scale(fscale_);
195  // Compute gradient of penalty
196  pen_->gradient(*dualOptVector_,x,tol);
197  // Compute gradient of Augmented Lagrangian
198  if ( scaleLagrangian_ ) {
199  g.scale(static_cast<Real>(1)/penaltyParameter_);
200  }
201  g.plus(*dualOptVector_);
202  }
203 
204  virtual void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
205  // Apply objective Hessian to a vector
206  obj_->hessVec(hv,v,x,tol);
207  hv.scale(fscale_);
208  // Apply penalty Hessian to a vector
209  pen_->hessVec(*dualOptVector_,v,x,tol);
210  // Build hessVec of Augmented Lagrangian
211  if ( scaleLagrangian_ ) {
212  hv.scale(static_cast<Real>(1)/penaltyParameter_);
213  }
214  hv.plus(*dualOptVector_);
215  }
216 
217  // Return objective function value
218  virtual Real getObjectiveValue(const Vector<Real> &x) {
219  Real tol = std::sqrt(ROL_EPSILON<Real>());
220  // Evaluate objective function value
221  if ( !isValueComputed_ ) {
222  fval_ = obj_->value(x,tol); nfval_++;
223  isValueComputed_ = true;
224  }
225  return fval_;
226  }
227 
228  const Ptr<const Vector<Real>> getObjectiveGradient(const Vector<Real> &x) {
229  Real tol = std::sqrt(ROL_EPSILON<Real>());
230  // Compute objective function gradient
231  if ( !isGradientComputed_ ) {
232  obj_->gradient(*gradient_,x,tol); ngval_++;
233  isGradientComputed_ = true;
234  }
235  return gradient_;
236  }
237 
238  // Return constraint value
239  virtual void getConstraintVec(Vector<Real> &c, const Vector<Real> &x) {
240  pen_->getConstraintVec(c,x);
241  }
242 
243  // Return total number of constraint evaluations
244  virtual int getNumberConstraintEvaluations(void) const {
245  return pen_->getNumberConstraintEvaluations();
246  }
247 
248  // Return total number of objective evaluations
249  virtual int getNumberFunctionEvaluations(void) const {
250  return nfval_;
251  }
252 
253  // Return total number of gradient evaluations
254  virtual int getNumberGradientEvaluations(void) const {
255  return ngval_;
256  }
257 
258  // Reset with upated penalty parameter
259  virtual void reset(const Vector<Real> &multiplier, const Real penaltyParameter) {
260  nfval_ = 0; ngval_ = 0;
261  pen_->reset(multiplier,penaltyParameter);
262  }
263 }; // class AugmentedLagrangian
264 
265 } // namespace ROL
266 
267 #endif
Provides the interface to evaluate objective functions.
Provides the interface to evaluate the augmented Lagrangian.
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Definition: ROL_Vector.hpp:226
ROL::Ptr< Vector< Real > > dualOptVector_
virtual void scale(const Real alpha)=0
Compute where .
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
virtual void plus(const Vector &x)=0
Compute , where .
virtual int getNumberConstraintEvaluations(void) const
Contains definitions of custom data types in ROL.
virtual Real getObjectiveValue(const Vector< Real > &x)
virtual Real value(const Vector< Real > &x, Real &tol)
Compute value.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
virtual void reset(const Vector< Real > &multiplier, const Real penaltyParameter)
AugmentedLagrangian(const ROL::Ptr< Objective< Real > > &obj, const ROL::Ptr< Constraint< Real > > &con, const Vector< Real > &multiplier, const Real penaltyParameter, const Vector< Real > &optVec, const Vector< Real > &conVec, ROL::ParameterList &parlist)
Constructor.
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
AugmentedLagrangian()
Null constructor.
virtual void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update objective function.
ROL::Ptr< Vector< Real > > gradient_
virtual int getNumberGradientEvaluations(void) const
const ROL::Ptr< Objective< Real > > obj_
virtual int getNumberFunctionEvaluations(void) const
void setScaling(const Real fscale, const Real cscale=1.0)
const Ptr< const Vector< Real > > getObjectiveGradient(const Vector< Real > &x)
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:209
ROL::Ptr< QuadraticPenalty< Real > > pen_
virtual void getConstraintVec(Vector< Real > &c, const Vector< Real > &x)
Defines the general constraint operator interface.