ROL
ROL_AugmentedLagrangian.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_AUGMENTEDLAGRANGIAN_H
11 #define ROL_AUGMENTEDLAGRANGIAN_H
12 
13 #include "ROL_Objective.hpp"
14 #include "ROL_Constraint.hpp"
15 #include "ROL_QuadraticPenalty.hpp"
16 #include "ROL_Vector.hpp"
17 #include "ROL_Types.hpp"
18 #include "ROL_Ptr.hpp"
19 #include <iostream>
20 
49 namespace ROL {
50 
51 template <class Real>
52 class AugmentedLagrangian : public Objective<Real> {
53 private:
54  // Required for Augmented Lagrangian definition
55  const ROL::Ptr<Objective<Real> > obj_;
56  ROL::Ptr<QuadraticPenalty<Real> > pen_;
58 
59  // Auxiliary storage
60  ROL::Ptr<Vector<Real> > dualOptVector_;
61 
62  // Objective and constraint evaluations
63  Real fval_;
64  ROL::Ptr<Vector<Real> > gradient_;
65 
66  // Objective function scaling
67  Real fscale_;
68 
69  // Evaluation counters
70  int nfval_;
71  int ngval_;
72 
73  // User defined options
75 
76  // Flags to recompute quantities
79 
80 public:
92  AugmentedLagrangian(const ROL::Ptr<Objective<Real> > &obj,
93  const ROL::Ptr<Constraint<Real> > &con,
94  const Vector<Real> &multiplier,
95  const Real penaltyParameter,
96  const Vector<Real> &optVec,
97  const Vector<Real> &conVec,
98  ROL::ParameterList &parlist)
99  : obj_(obj), penaltyParameter_(penaltyParameter),
100  fval_(0), fscale_(1),
101  nfval_(0), ngval_(0),
102  isValueComputed_(false), isGradientComputed_(false) {
103 
104  gradient_ = optVec.dual().clone();
105  dualOptVector_ = optVec.dual().clone();
106 
107  ROL::ParameterList& sublist = parlist.sublist("Step").sublist("Augmented Lagrangian");
108  scaleLagrangian_ = sublist.get("Use Scaled Augmented Lagrangian", false);
109  int HessianApprox = sublist.get("Level of Hessian Approximation", 0);
110 
111  pen_ = ROL::makePtr<QuadraticPenalty<Real>>(con,multiplier,penaltyParameter,optVec,conVec,scaleLagrangian_,HessianApprox);
112  }
113 
125  AugmentedLagrangian(const ROL::Ptr<Objective<Real> > &obj,
126  const ROL::Ptr<Constraint<Real> > &con,
127  const Vector<Real> &multiplier,
128  const Real penaltyParameter,
129  const Vector<Real> &optVec,
130  const Vector<Real> &conVec,
131  const bool scaleLagrangian,
132  const int HessianApprox)
133  : obj_(obj), penaltyParameter_(penaltyParameter),
134  fval_(0), fscale_(1),
135  nfval_(0), ngval_(0),
136  scaleLagrangian_(scaleLagrangian),
137  isValueComputed_(false), isGradientComputed_(false) {
138 
139  gradient_ = optVec.dual().clone();
140  dualOptVector_ = optVec.dual().clone();
141 
142  pen_ = ROL::makePtr<QuadraticPenalty<Real>>(con,multiplier,penaltyParameter,optVec,conVec,scaleLagrangian_,HessianApprox);
143  }
144 
151  : obj_(ROL::nullPtr), pen_(ROL::nullPtr), dualOptVector_(ROL::nullPtr),
152  fval_(0), gradient_(ROL::nullPtr), fscale_(1),
153  nfval_(0), ngval_(0),
154  scaleLagrangian_(false), isValueComputed_(false), isGradientComputed_(false) {}
155 
156  virtual void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
157  obj_->update(x,flag,iter);
158  pen_->update(x,flag,iter);
159  isValueComputed_ = ((flag || (!flag && iter < 0)) ? false : isValueComputed_);
160  isGradientComputed_ = ((flag || (!flag && iter < 0)) ? false : isGradientComputed_);
161  }
162 
163  void setScaling(const Real fscale, const Real cscale = 1.0) {
164  fscale_ = fscale;
165  pen_->setScaling(cscale);
166  }
167 
168  virtual Real value( const Vector<Real> &x, Real &tol ) {
169  // Compute objective function value
170  if ( !isValueComputed_ ) {
171  fval_ = obj_->value(x,tol); nfval_++;
172  isValueComputed_ = true;
173  }
174  // Compute penalty term
175  Real pval = pen_->value(x,tol);
176  // Compute augmented Lagrangian
177  Real val = fscale_*fval_;
178  if (scaleLagrangian_) {
179  val /= penaltyParameter_;
180  }
181  return val + pval;
182  }
183 
184  virtual void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
185  // Compute objective function gradient
186  if ( !isGradientComputed_ ) {
187  obj_->gradient(*gradient_,x,tol); ngval_++;
188  isGradientComputed_ = true;
189  }
190  g.set(*gradient_);
191  g.scale(fscale_);
192  // Compute gradient of penalty
193  pen_->gradient(*dualOptVector_,x,tol);
194  // Compute gradient of Augmented Lagrangian
195  if ( scaleLagrangian_ ) {
196  g.scale(static_cast<Real>(1)/penaltyParameter_);
197  }
198  g.plus(*dualOptVector_);
199  }
200 
201  virtual void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
202  // Apply objective Hessian to a vector
203  obj_->hessVec(hv,v,x,tol);
204  hv.scale(fscale_);
205  // Apply penalty Hessian to a vector
206  pen_->hessVec(*dualOptVector_,v,x,tol);
207  // Build hessVec of Augmented Lagrangian
208  if ( scaleLagrangian_ ) {
209  hv.scale(static_cast<Real>(1)/penaltyParameter_);
210  }
211  hv.plus(*dualOptVector_);
212  }
213 
214  // Return objective function value
215  virtual Real getObjectiveValue(const Vector<Real> &x) {
216  Real tol = std::sqrt(ROL_EPSILON<Real>());
217  // Evaluate objective function value
218  if ( !isValueComputed_ ) {
219  fval_ = obj_->value(x,tol); nfval_++;
220  isValueComputed_ = true;
221  }
222  return fval_;
223  }
224 
225  const Ptr<const Vector<Real>> getObjectiveGradient(const Vector<Real> &x) {
226  Real tol = std::sqrt(ROL_EPSILON<Real>());
227  // Compute objective function gradient
228  if ( !isGradientComputed_ ) {
229  obj_->gradient(*gradient_,x,tol); ngval_++;
230  isGradientComputed_ = true;
231  }
232  return gradient_;
233  }
234 
235  // Return constraint value
236  virtual void getConstraintVec(Vector<Real> &c, const Vector<Real> &x) {
237  pen_->getConstraintVec(c,x);
238  }
239 
240  // Return total number of constraint evaluations
241  virtual int getNumberConstraintEvaluations(void) const {
242  return pen_->getNumberConstraintEvaluations();
243  }
244 
245  // Return total number of objective evaluations
246  virtual int getNumberFunctionEvaluations(void) const {
247  return nfval_;
248  }
249 
250  // Return total number of gradient evaluations
251  virtual int getNumberGradientEvaluations(void) const {
252  return ngval_;
253  }
254 
255  // Reset with upated penalty parameter
256  virtual void reset(const Vector<Real> &multiplier, const Real penaltyParameter) {
257  nfval_ = 0; ngval_ = 0;
258  pen_->reset(multiplier,penaltyParameter);
259  }
260 }; // class AugmentedLagrangian
261 
262 } // namespace ROL
263 
264 #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:192
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:46
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_
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, const bool scaleLagrangian, const int HessianApprox)
Constructor.
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:175
ROL::Ptr< QuadraticPenalty< Real > > pen_
virtual void getConstraintVec(Vector< Real > &c, const Vector< Real > &x)
Defines the general constraint operator interface.