ROL
Loading...
Searching...
No Matches
ROL_AugmentedLagrangianPenalty.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_AUGMENTEDLAGRANGIANPENALTY_H
11#define ROL_AUGMENTEDLAGRANGIANPENALTY_H
12
13#include "ROL_Constraint.hpp"
14#include "ROL_Objective.hpp"
15#include "ROL_ParameterList.hpp"
16#include "ROL_Projection.hpp"
18
19namespace ROL {
20
21template <class Real>
23private:
24 // Required for Augmented Lagrangian definition
25 const Ptr<Constraint<Real>> con_;
26 const Ptr<Projection<Real>> proj_;
27 nullstream bhs_;
28
30 Ptr<Vector<Real>> multiplier_;
31
32 // Auxiliary storage
33 Ptr<Vector<Real>> dualOptVector_;
34 Ptr<Vector<Real>> dualConVector_;
35 Ptr<Vector<Real>> primConVector1_;
36 Ptr<Vector<Real>> primConVector2_;
37
38 // Constraint evaluations
39 Ptr<VectorController<Real,int>> conValue_;
40 Ptr<VectorController<Real,int>> dualValue_;
41
42 // Constraint scaling
43 Real cscale_;
44
45 // Evaluation counter
46 int ncval_;
47
48 // User defined options
50
51public:
52
54 const Ptr<Projection<Real>> &proj,
55 const Real penaltyParameter,
56 const Vector<Real> &dualOptVec,
57 const Vector<Real> &primConVec,
58 const Vector<Real> &dualConVec,
59 ParameterList &parlist)
60 : con_(con), proj_(proj), penaltyParameter_(penaltyParameter),
61 cscale_(1), ncval_(0) {
62
63 conValue_ = makePtr<VectorController<Real,int>>();
64 dualValue_ = makePtr<VectorController<Real,int>>();
65
66 multiplier_ = dualConVec.clone();
67 multiplier_->zero();
68 dualOptVector_ = dualOptVec.clone();
69 dualConVector_ = dualConVec.clone();
70 primConVector1_ = primConVec.clone();
71 primConVector2_ = primConVec.clone();
72
73 ParameterList& sublist = parlist.sublist("Step").sublist("Augmented Lagrangian");
74 hessianApprox_ = sublist.get("Level of Hessian Approximation", 0);
75 }
76
78 const Ptr<Projection<Real>> &proj,
79 const Real penaltyParameter,
80 const Vector<Real> &dualOptVec,
81 const Vector<Real> &primConVec,
82 const Vector<Real> &dualConVec,
83 const int hessianApprox)
84 : con_(con), proj_(proj), penaltyParameter_(penaltyParameter),
85 cscale_(1), ncval_(0), hessianApprox_(hessianApprox) {
86
87 conValue_ = makePtr<VectorController<Real,int>>();
88 dualValue_ = makePtr<VectorController<Real,int>>();
89
90 multiplier_ = dualConVec.clone();
91 multiplier_->zero();
92 dualOptVector_ = dualOptVec.clone();
93 dualConVector_ = dualConVec.clone();
94 primConVector1_ = primConVec.clone();
95 primConVector2_ = primConVec.clone();
96 }
97
98 virtual void update( const Vector<Real> &x, UpdateType type, int iter = -1 ) {
99 con_->update(x,type,iter);
100 conValue_->objectiveUpdate(type);
101 dualValue_->objectiveUpdate(type);
102 }
103
104 void setScaling(const Real cscale = 1.0) {
105 cscale_ = cscale;
106 }
107
108 Real getScaling() {
109 return cscale_;
110 }
111
112 virtual Real value( const Vector<Real> &x, Real &tol ) {
113 // Compute penalty function value
114 Real val = getDualVec(x,tol)->norm();
115 val = val*val/(Real(2)*penaltyParameter_);
116 val *= cscale_;
117 return val;
118 }
119
120 virtual void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
121 // Compute penalty function gradient
122 con_->applyAdjointJacobian(g,*getDualVec(x,tol),x,tol);
123 g.scale(cscale_);
124 }
125
126 virtual void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
127 // Apply penalty Hessian to a vector
128 if (hessianApprox_ >= 3) {
129 hv.zero();
130 return;
131 }
132 con_->applyJacobian(*primConVector1_,v,x,tol);
133 dualConVector_->set(primConVector1_->dual());
134 primConVector2_->set(*getConstraintVec(x,tol));
135 primConVector2_->axpy(Real(1)/penaltyParameter_,multiplier_->dual());
136 proj_->applyJacobian(*primConVector1_,*primConVector2_);
137 dualConVector_->axpy(-1,primConVector1_->dual());
139 con_->applyAdjointJacobian(hv,*dualConVector_,x,tol);
140 if (hessianApprox_ == 0) {
141 con_->applyAdjointHessian(*dualOptVector_,*getDualVec(x,tol),v,x,tol);
142 hv.plus(*dualOptVector_);
143 }
144 hv.scale(cscale_);
145 }
146
147 Real dualNorm( const Vector<Real> &x, Real &tol ) {
148 return getDualVec(x,tol)->norm();
149 }
150
151 Real dualResidual( const Vector<Real> &x, Real &tol ) {
152 dualConVector_->set(*getDualVec(x,tol));
153 dualConVector_->axpy(Real(-1),*multiplier_);
154 return dualConVector_->norm();
155 }
156
157 Real feasibility( const Vector<Real> &x, Real &tol ) {
158 primConVector1_->set(*getConstraintVec(x,tol));
159 proj_->project(*primConVector1_,bhs_);
160 primConVector1_->axpy(Real(-1),*getConstraintVec(x,tol));
161 return primConVector1_->norm();
162 }
163
164 void setPenaltyParameter( const Real penaltyParameter ) {
165 penaltyParameter_ = penaltyParameter;
166 }
167
169 return penaltyParameter_;
170 }
171
172 void setMultiplier( const Vector<Real> &multiplier ) {
173 multiplier_->set(multiplier);
174 }
175
176 void updateMultiplier( const Vector<Real> &x, Real &tol ) {
177 multiplier_->set(*getDualVec(x,tol));
178 }
179
180 // Return constraint value
181 const Ptr<const Vector<Real>> getConstraintVec( const Vector<Real> &x, Real &tol ) {
182 int key(0);
183 if (!conValue_->isComputed(key)) {
184 if (conValue_->isNull(key)) conValue_->allocate(*primConVector1_,key);
185 con_->value(*conValue_->set(key),x,tol); ncval_++;
186 }
187 return conValue_->get(key);
188 }
189
190 // Return dual value (proximal point step)
191 const Ptr<const Vector<Real>> getDualVec( const Vector<Real> &x, Real &tol ) {
192 int key(0);
193 if (!dualValue_->isComputed(key)) {
194 if (dualValue_->isNull(key)) dualValue_->allocate(*dualConVector_,key);
195 primConVector1_->set(*getConstraintVec(x,tol));
196 primConVector1_->axpy(Real(1)/penaltyParameter_,multiplier_->dual());
197 dualConVector_->set(primConVector1_->dual());
198 proj_->project(*primConVector1_,bhs_);
199 dualConVector_->axpy(Real(-1),primConVector1_->dual());
201 dualValue_->set(key)->set(*dualConVector_);
202 }
203 return dualValue_->get(key);
204 }
205
206 // Return total number of constraint evaluations
208 return ncval_;
209 }
210
211 // Reset counter
212 void reset(void) {
213 ncval_ = 0;
214 }
215
216}; // class AugmentedLagrangianPenalty
217
218} // namespace ROL
219
220#endif
Ptr< VectorController< Real, int > > dualValue_
Ptr< VectorController< Real, int > > conValue_
const Ptr< const Vector< Real > > getDualVec(const Vector< Real > &x, Real &tol)
virtual void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
const Ptr< const Vector< Real > > getConstraintVec(const Vector< Real > &x, Real &tol)
void updateMultiplier(const Vector< Real > &x, Real &tol)
virtual Real value(const Vector< Real > &x, Real &tol)
Compute value.
AugmentedLagrangianPenalty(const Ptr< Constraint< Real > > &con, const Ptr< Projection< Real > > &proj, const Real penaltyParameter, const Vector< Real > &dualOptVec, const Vector< Real > &primConVec, const Vector< Real > &dualConVec, const int hessianApprox)
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Real dualResidual(const Vector< Real > &x, Real &tol)
void setPenaltyParameter(const Real penaltyParameter)
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Real dualNorm(const Vector< Real > &x, Real &tol)
AugmentedLagrangianPenalty(const Ptr< Constraint< Real > > &con, const Ptr< Projection< Real > > &proj, const Real penaltyParameter, const Vector< Real > &dualOptVec, const Vector< Real > &primConVec, const Vector< Real > &dualConVec, ParameterList &parlist)
void setMultiplier(const Vector< Real > &multiplier)
Real feasibility(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 scale(const Real alpha)=0
Compute where .
virtual void plus(const Vector &x)=0
Compute , where .
virtual void zero()
Set to zero vector.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.