ROL
ROL_AugmentedLagrangianObjective.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_AUGMENTEDLAGRANGIANOBJECTIVE_H
45 #define ROL_AUGMENTEDLAGRANGIANOBJECTIVE_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 "ROL_ScalarController.hpp"
54 #include "ROL_ParameterList.hpp"
55 #include <iostream>
56 
85 namespace ROL {
86 
87 template <class Real>
89 private:
90  // Required for Augmented Lagrangian definition
91  const Ptr<Objective<Real>> obj_;
92  const Ptr<Constraint<Real>> con_;
93 
95  Ptr<Vector<Real>> multiplier_;
96 
97  // Auxiliary storage
98  Ptr<Vector<Real>> dualOptVector_;
99  Ptr<Vector<Real>> dualConVector_;
100  Ptr<Vector<Real>> primConVector_;
101 
102  // Objective and constraint evaluations
103  Ptr<ScalarController<Real,int>> fval_;
104  Ptr<VectorController<Real,int>> gradient_;
105  Ptr<VectorController<Real,int>> conValue_;
106 
107  // Objective function and constraint scaling
108  Real fscale_;
109  Real cscale_;
110 
111  // Evaluation counters
112  int nfval_;
113  int ngval_;
114  int ncval_;
115 
116  // User defined options
119 
120 public:
122  const Ptr<Constraint<Real>> &con,
123  const Real penaltyParameter,
124  const Vector<Real> &dualOptVec,
125  const Vector<Real> &primConVec,
126  const Vector<Real> &dualConVec,
127  ParameterList &parlist)
128  : obj_(obj), con_(con), penaltyParameter_(penaltyParameter),
129  fscale_(1), cscale_(1), nfval_(0), ngval_(0), ncval_(0) {
130 
131  fval_ = makePtr<ScalarController<Real,int>>();
132  gradient_ = makePtr<VectorController<Real,int>>();
133  conValue_ = makePtr<VectorController<Real,int>>();
134 
135  multiplier_ = dualConVec.clone();
136  dualOptVector_ = dualOptVec.clone();
137  dualConVector_ = dualConVec.clone();
138  primConVector_ = primConVec.clone();
139 
140  ParameterList& sublist = parlist.sublist("Step").sublist("Augmented Lagrangian");
141  scaleLagrangian_ = sublist.get("Use Scaled Augmented Lagrangian", false);
142  HessianApprox_ = sublist.get("Level of Hessian Approximation", 0);
143  }
144 
146  const Ptr<Constraint<Real>> &con,
147  const Real penaltyParameter,
148  const Vector<Real> &dualOptVec,
149  const Vector<Real> &primConVec,
150  const Vector<Real> &dualConVec,
151  const bool scaleLagrangian,
152  const int HessianApprox)
153  : obj_(obj), con_(con), penaltyParameter_(penaltyParameter),
154  fscale_(1), cscale_(1), nfval_(0), ngval_(0), ncval_(0),
155  scaleLagrangian_(scaleLagrangian), HessianApprox_(HessianApprox) {
156 
157  fval_ = makePtr<ScalarController<Real,int>>();
158  gradient_ = makePtr<VectorController<Real,int>>();
159  conValue_ = makePtr<VectorController<Real,int>>();
160 
161  multiplier_ = dualConVec.clone();
162  dualOptVector_ = dualOptVec.clone();
163  dualConVector_ = dualConVec.clone();
164  primConVector_ = primConVec.clone();
165  }
166 
167  void update( const Vector<Real> &x, UpdateType type, int iter = -1 ) {
168  obj_->update(x,type,iter);
169  con_->update(x,type,iter);
170  fval_->objectiveUpdate(type);
171  gradient_->objectiveUpdate(type);
172  conValue_->objectiveUpdate(type);
173  }
174 
175  void setScaling(const Real fscale = 1.0, const Real cscale = 1.0) {
176  fscale_ = fscale;
177  cscale_ = cscale;
178  }
179 
180  Real value( const Vector<Real> &x, Real &tol ) {
181  // Compute objective function value
182  Real val = getObjectiveValue(x,tol);
183  val *= fscale_;
184  // Compute penalty term
185  const Real half(0.5);
186  primConVector_->set(multiplier_->dual());
188  val += cscale_*getConstraintVec(x,tol)->dot(*primConVector_);
189  // Scale augmented Lagrangian
190  if (scaleLagrangian_) {
191  val /= penaltyParameter_;
192  }
193  return val;
194  }
195 
196  void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
197  // Compute objective function gradient
198  g.set(*getObjectiveGradient(x,tol));
199  g.scale(fscale_);
200  // Compute gradient of penalty
203  con_->applyAdjointJacobian(*dualOptVector_,*dualConVector_,x,tol);
205  // Compute gradient of Augmented Lagrangian
206  if ( scaleLagrangian_ ) {
207  const Real one(1);
208  g.scale(one/penaltyParameter_);
209  }
210  }
211 
212  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
213  // Apply objective Hessian to a vector
214  obj_->hessVec(hv,v,x,tol);
215  hv.scale(fscale_);
216  // Apply penalty Hessian to a vector
217  if (HessianApprox_ < 3) {
218  con_->applyJacobian(*primConVector_,v,x,tol);
219  con_->applyAdjointJacobian(*dualOptVector_,primConVector_->dual(),x,tol);
221  if (HessianApprox_ == 1) {
223  con_->applyAdjointHessian(*dualOptVector_,*dualConVector_,v,x,tol);
225  }
226  if (HessianApprox_ == 0) {
228  dualConVector_->axpy(cscale_*penaltyParameter_,getConstraintVec(x,tol)->dual());
229  con_->applyAdjointHessian(*dualOptVector_,*dualConVector_,v,x,tol);
231  }
232  }
233  else {
234  hv.zero();
235  }
236  // Build hessVec of Augmented Lagrangian
237  if ( scaleLagrangian_ ) {
238  hv.scale(static_cast<Real>(1)/penaltyParameter_);
239  }
240  }
241 
242  // Return objective function value
243  Real getObjectiveValue(const Vector<Real> &x, Real &tol) {
244  Real val(0);
245  int key(0);
246  bool isComputed = fval_->get(val,key);
247  if ( !isComputed ) {
248  val = obj_->value(x,tol); nfval_++;
249  fval_->set(val,key);
250  }
251  return val;
252  }
253 
254  // Compute objective function gradient
255  const Ptr<const Vector<Real>> getObjectiveGradient(const Vector<Real> &x, Real &tol) {
256  int key(0);
257  if (!gradient_->isComputed(key)) {
258  if (gradient_->isNull(key)) gradient_->allocate(*dualOptVector_,key);
259  obj_->gradient(*gradient_->set(key),x,tol); ngval_++;
260  }
261  return gradient_->get(key);
262  }
263 
264  // Return constraint value
265  const Ptr<const Vector<Real>> getConstraintVec(const Vector<Real> &x, Real &tol) {
266  int key(0);
267  if (!conValue_->isComputed(key)) {
268  if (conValue_->isNull(key)) conValue_->allocate(*primConVector_,key);
269  con_->value(*conValue_->set(key),x,tol); ncval_++;
270  }
271  return conValue_->get(key);
272  }
273 
274  // Return total number of constraint evaluations
276  return ncval_;
277  }
278 
279  // Return total number of objective evaluations
281  return nfval_;
282  }
283 
284  // Return total number of gradient evaluations
286  return ngval_;
287  }
288 
289  // Reset with upated penalty parameter
290  void reset(const Vector<Real> &multiplier, const Real penaltyParameter) {
291  nfval_ = 0; ngval_ = 0; ncval_ = 0;
292  multiplier_->set(multiplier);
293  penaltyParameter_ = penaltyParameter;
294  }
295 }; // class AugmentedLagrangianObjective
296 
297 } // namespace ROL
298 
299 #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:153
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:167
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
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:209
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.