ROL
ROL_AugmentedLagrangianObjective.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_AUGMENTEDLAGRANGIANOBJECTIVE_H
11 #define ROL_AUGMENTEDLAGRANGIANOBJECTIVE_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 "ROL_ScalarController.hpp"
20 #include "ROL_ParameterList.hpp"
21 #include <iostream>
22 
51 namespace ROL {
52 
53 template <class Real>
55 private:
56  // Required for Augmented Lagrangian definition
57  const Ptr<Objective<Real>> obj_;
58  const Ptr<Constraint<Real>> con_;
59 
61  Ptr<Vector<Real>> multiplier_;
62 
63  // Auxiliary storage
64  Ptr<Vector<Real>> dualOptVector_;
65  Ptr<Vector<Real>> dualConVector_;
66  Ptr<Vector<Real>> primConVector_;
67 
68  // Objective and constraint evaluations
69  Ptr<ScalarController<Real,int>> fval_;
70  Ptr<VectorController<Real,int>> gradient_;
71  Ptr<VectorController<Real,int>> conValue_;
72 
73  // Objective function and constraint scaling
74  Real fscale_;
75  Real cscale_;
76 
77  // Evaluation counters
78  int nfval_;
79  int ngval_;
80  int ncval_;
81 
82  // User defined options
85 
86 public:
88  const Ptr<Constraint<Real>> &con,
89  const Real penaltyParameter,
90  const Vector<Real> &dualOptVec,
91  const Vector<Real> &primConVec,
92  const Vector<Real> &dualConVec,
93  ParameterList &parlist)
94  : obj_(obj), con_(con), penaltyParameter_(penaltyParameter),
95  fscale_(1), cscale_(1), nfval_(0), ngval_(0), ncval_(0) {
96 
97  fval_ = makePtr<ScalarController<Real,int>>();
98  gradient_ = makePtr<VectorController<Real,int>>();
99  conValue_ = makePtr<VectorController<Real,int>>();
100 
101  multiplier_ = dualConVec.clone();
102  dualOptVector_ = dualOptVec.clone();
103  dualConVector_ = dualConVec.clone();
104  primConVector_ = primConVec.clone();
105 
106  ParameterList& sublist = parlist.sublist("Step").sublist("Augmented Lagrangian");
107  scaleLagrangian_ = sublist.get("Use Scaled Augmented Lagrangian", false);
108  HessianApprox_ = sublist.get("Level of Hessian Approximation", 0);
109  }
110 
112  const Ptr<Constraint<Real>> &con,
113  const Real penaltyParameter,
114  const Vector<Real> &dualOptVec,
115  const Vector<Real> &primConVec,
116  const Vector<Real> &dualConVec,
117  const bool scaleLagrangian,
118  const int HessianApprox)
119  : obj_(obj), con_(con), penaltyParameter_(penaltyParameter),
120  fscale_(1), cscale_(1), nfval_(0), ngval_(0), ncval_(0),
121  scaleLagrangian_(scaleLagrangian), HessianApprox_(HessianApprox) {
122 
123  fval_ = makePtr<ScalarController<Real,int>>();
124  gradient_ = makePtr<VectorController<Real,int>>();
125  conValue_ = makePtr<VectorController<Real,int>>();
126 
127  multiplier_ = dualConVec.clone();
128  dualOptVector_ = dualOptVec.clone();
129  dualConVector_ = dualConVec.clone();
130  primConVector_ = primConVec.clone();
131  }
132 
133  void update( const Vector<Real> &x, UpdateType type, int iter = -1 ) {
134  obj_->update(x,type,iter);
135  con_->update(x,type,iter);
136  fval_->objectiveUpdate(type);
137  gradient_->objectiveUpdate(type);
138  conValue_->objectiveUpdate(type);
139  }
140 
141  void setScaling(const Real fscale = 1.0, const Real cscale = 1.0) {
142  fscale_ = fscale;
143  cscale_ = cscale;
144  }
145 
146  Real value( const Vector<Real> &x, Real &tol ) {
147  // Compute objective function value
148  Real val = getObjectiveValue(x,tol);
149  val *= fscale_;
150  // Compute penalty term
151  const Real half(0.5);
153  dualConVector_->axpy(half*cscale_*penaltyParameter_,getConstraintVec(x,tol)->dual());
154  val += cscale_*dualConVector_->apply(*getConstraintVec(x,tol));
155  //val += cscale_*getConstraintVec(x,tol)->dot(*primConVector_);
156  // Scale augmented Lagrangian
158  return val;
159  }
160 
161  void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
162  // Compute objective function gradient
163  g.set(*getObjectiveGradient(x,tol));
164  g.scale(fscale_);
165  // Compute gradient of penalty
168  con_->applyAdjointJacobian(*dualOptVector_,*dualConVector_,x,tol);
170  // Compute gradient of Augmented Lagrangian
171  if ( scaleLagrangian_ ) g.scale(static_cast<Real>(1)/penaltyParameter_);
172  }
173 
174  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
175  // Apply objective Hessian to a vector
176  obj_->hessVec(hv,v,x,tol);
177  hv.scale(fscale_);
178  // Apply penalty Hessian to a vector
179  if (HessianApprox_ < 3) {
180  con_->applyJacobian(*primConVector_,v,x,tol);
181  con_->applyAdjointJacobian(*dualOptVector_,primConVector_->dual(),x,tol);
183  if (HessianApprox_ == 1) {
185  con_->applyAdjointHessian(*dualOptVector_,*dualConVector_,v,x,tol);
187  }
188  if (HessianApprox_ == 0) {
190  dualConVector_->axpy(cscale_*penaltyParameter_,getConstraintVec(x,tol)->dual());
191  con_->applyAdjointHessian(*dualOptVector_,*dualConVector_,v,x,tol);
193  }
194  }
195  else {
196  hv.zero();
197  }
198  // Build hessVec of Augmented Lagrangian
199  if ( scaleLagrangian_ ) hv.scale(static_cast<Real>(1)/penaltyParameter_);
200  }
201 
202  // Return objective function value
203  Real getObjectiveValue(const Vector<Real> &x, Real &tol) {
204  Real val(0);
205  int key(0);
206  bool isComputed = fval_->get(val,key);
207  if ( !isComputed ) {
208  val = obj_->value(x,tol); nfval_++;
209  fval_->set(val,key);
210  }
211  return val;
212  }
213 
214  // Compute objective function gradient
215  const Ptr<const Vector<Real>> getObjectiveGradient(const Vector<Real> &x, Real &tol) {
216  int key(0);
217  if (!gradient_->isComputed(key)) {
218  if (gradient_->isNull(key)) gradient_->allocate(*dualOptVector_,key);
219  obj_->gradient(*gradient_->set(key),x,tol); ngval_++;
220  }
221  return gradient_->get(key);
222  }
223 
224  // Return constraint value
225  const Ptr<const Vector<Real>> getConstraintVec(const Vector<Real> &x, Real &tol) {
226  int key(0);
227  if (!conValue_->isComputed(key)) {
228  if (conValue_->isNull(key)) conValue_->allocate(*primConVector_,key);
229  con_->value(*conValue_->set(key),x,tol); ncval_++;
230  }
231  return conValue_->get(key);
232  }
233 
234  // Return total number of constraint evaluations
236  return ncval_;
237  }
238 
239  // Return total number of objective evaluations
241  return nfval_;
242  }
243 
244  // Return total number of gradient evaluations
246  return ngval_;
247  }
248 
249  // Reset with upated penalty parameter
250  void reset(const Vector<Real> &multiplier, const Real penaltyParameter) {
251  nfval_ = 0; ngval_ = 0; ncval_ = 0;
252  multiplier_->set(multiplier);
253  penaltyParameter_ = penaltyParameter;
254  }
255 }; // class AugmentedLagrangianObjective
256 
257 } // namespace ROL
258 
259 #endif
Provides the interface to evaluate objective functions.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
virtual void scale(const Real alpha)=0
Compute where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
AugmentedLagrangianObjective(const Ptr< Objective< Real >> &obj, const Ptr< Constraint< Real >> &con, const Real penaltyParameter, const Vector< Real > &dualOptVec, const Vector< Real > &primConVec, const Vector< Real > &dualConVec, ParameterList &parlist)
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:119
const Ptr< const Vector< Real > > getConstraintVec(const Vector< Real > &x, Real &tol)
Contains definitions of custom data types in ROL.
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:133
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
void reset(const Vector< Real > &multiplier, const Real penaltyParameter)
void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
Ptr< VectorController< Real, int > > conValue_
Ptr< ScalarController< Real, int > > fval_
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
AugmentedLagrangianObjective(const Ptr< Objective< Real >> &obj, const Ptr< Constraint< Real >> &con, const Real penaltyParameter, const Vector< Real > &dualOptVec, const Vector< Real > &primConVec, const Vector< Real > &dualConVec, const bool scaleLagrangian, const int HessianApprox)
Provides the interface to evaluate the augmented Lagrangian.
void setScaling(const Real fscale=1.0, const Real cscale=1.0)
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
const Ptr< const Vector< Real > > getObjectiveGradient(const Vector< Real > &x, Real &tol)
Ptr< VectorController< Real, int > > gradient_
Real getObjectiveValue(const Vector< Real > &x, Real &tol)
Defines the general constraint operator interface.