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);
152  primConVector_->set(multiplier_->dual());
154  val += cscale_*getConstraintVec(x,tol)->dot(*primConVector_);
155  // Scale augmented Lagrangian
156  if (scaleLagrangian_) {
157  val /= penaltyParameter_;
158  }
159  return val;
160  }
161 
162  void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
163  // Compute objective function gradient
164  g.set(*getObjectiveGradient(x,tol));
165  g.scale(fscale_);
166  // Compute gradient of penalty
169  con_->applyAdjointJacobian(*dualOptVector_,*dualConVector_,x,tol);
171  // Compute gradient of Augmented Lagrangian
172  if ( scaleLagrangian_ ) {
173  const Real one(1);
174  g.scale(one/penaltyParameter_);
175  }
176  }
177 
178  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
179  // Apply objective Hessian to a vector
180  obj_->hessVec(hv,v,x,tol);
181  hv.scale(fscale_);
182  // Apply penalty Hessian to a vector
183  if (HessianApprox_ < 3) {
184  con_->applyJacobian(*primConVector_,v,x,tol);
185  con_->applyAdjointJacobian(*dualOptVector_,primConVector_->dual(),x,tol);
187  if (HessianApprox_ == 1) {
189  con_->applyAdjointHessian(*dualOptVector_,*dualConVector_,v,x,tol);
191  }
192  if (HessianApprox_ == 0) {
194  dualConVector_->axpy(cscale_*penaltyParameter_,getConstraintVec(x,tol)->dual());
195  con_->applyAdjointHessian(*dualOptVector_,*dualConVector_,v,x,tol);
197  }
198  }
199  else {
200  hv.zero();
201  }
202  // Build hessVec of Augmented Lagrangian
203  if ( scaleLagrangian_ ) {
204  hv.scale(static_cast<Real>(1)/penaltyParameter_);
205  }
206  }
207 
208  // Return objective function value
209  Real getObjectiveValue(const Vector<Real> &x, Real &tol) {
210  Real val(0);
211  int key(0);
212  bool isComputed = fval_->get(val,key);
213  if ( !isComputed ) {
214  val = obj_->value(x,tol); nfval_++;
215  fval_->set(val,key);
216  }
217  return val;
218  }
219 
220  // Compute objective function gradient
221  const Ptr<const Vector<Real>> getObjectiveGradient(const Vector<Real> &x, Real &tol) {
222  int key(0);
223  if (!gradient_->isComputed(key)) {
224  if (gradient_->isNull(key)) gradient_->allocate(*dualOptVector_,key);
225  obj_->gradient(*gradient_->set(key),x,tol); ngval_++;
226  }
227  return gradient_->get(key);
228  }
229 
230  // Return constraint value
231  const Ptr<const Vector<Real>> getConstraintVec(const Vector<Real> &x, Real &tol) {
232  int key(0);
233  if (!conValue_->isComputed(key)) {
234  if (conValue_->isNull(key)) conValue_->allocate(*primConVector_,key);
235  con_->value(*conValue_->set(key),x,tol); ncval_++;
236  }
237  return conValue_->get(key);
238  }
239 
240  // Return total number of constraint evaluations
242  return ncval_;
243  }
244 
245  // Return total number of objective evaluations
247  return nfval_;
248  }
249 
250  // Return total number of gradient evaluations
252  return ngval_;
253  }
254 
255  // Reset with upated penalty parameter
256  void reset(const Vector<Real> &multiplier, const Real penaltyParameter) {
257  nfval_ = 0; ngval_ = 0; ncval_ = 0;
258  multiplier_->set(multiplier);
259  penaltyParameter_ = penaltyParameter;
260  }
261 }; // class AugmentedLagrangianObjective
262 
263 } // namespace ROL
264 
265 #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.