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"
16#include "ROL_Vector.hpp"
17#include "ROL_Types.hpp"
18#include "ROL_Ptr.hpp"
20#include "ROL_ParameterList.hpp"
21#include <iostream>
22
51namespace ROL {
52
53template <class Real>
55private:
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
86public:
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) {
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
Contains definitions of custom data types in ROL.
Provides the interface to evaluate the augmented Lagrangian.
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)
void reset(const Vector< Real > &multiplier, const Real penaltyParameter)
Real value(const Vector< Real > &x, Real &tol)
Compute value.
void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
Ptr< VectorController< Real, int > > conValue_
Real getObjectiveValue(const Vector< Real > &x, Real &tol)
Ptr< VectorController< Real, int > > gradient_
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
void setScaling(const Real fscale=1.0, const Real cscale=1.0)
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)
const Ptr< const Vector< Real > > getObjectiveGradient(const Vector< Real > &x, Real &tol)
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Ptr< ScalarController< Real, int > > fval_
const Ptr< const Vector< Real > > getConstraintVec(const Vector< Real > &x, Real &tol)
Defines the general constraint operator interface.
Provides the interface to evaluate objective functions.
Defines the linear algebra or vector space interface.
virtual void set(const Vector &x)
Set where .
virtual void scale(const Real alpha)=0
Compute where .
virtual void zero()
Set to zero vector.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .