ROL
ROL_MoreauYosidaPenaltyStep.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_MOREAUYOSIDAPENALTYSTEP_H
11#define ROL_MOREAUYOSIDAPENALTYSTEP_H
12
14#include "ROL_Types.hpp"
16#include "ROL_CompositeStep.hpp"
17#include "ROL_FletcherStep.hpp"
18#include "ROL_BundleStep.hpp"
21#include "ROL_Algorithm.hpp"
24#include "ROL_ParameterList.hpp"
25
86
87
88namespace ROL {
89
90template<class Real>
92
93template <class Real>
94class MoreauYosidaPenaltyStep : public Step<Real> {
95private:
96 ROL::Ptr<StatusTest<Real>> status_;
97 ROL::Ptr<Step<Real>> step_;
98 ROL::Ptr<Algorithm<Real>> algo_;
99 ROL::Ptr<Vector<Real>> x_;
100 ROL::Ptr<Vector<Real>> g_;
101 ROL::Ptr<Vector<Real>> l_;
102 ROL::Ptr<BoundConstraint<Real>> bnd_;
103
106 Real tau_;
107 bool print_;
109
110 ROL::ParameterList parlist_;
113
115 std::string stepname_;
116
117 void updateState(const Vector<Real> &x, const Vector<Real> &l,
118 Objective<Real> &obj,
120 AlgorithmState<Real> &algo_state) {
122 = dynamic_cast<MoreauYosidaPenalty<Real>&>(obj);
123 Real zerotol = std::sqrt(ROL_EPSILON<Real>());
124 ROL::Ptr<StepState<Real> > state = Step<Real>::getState();
125 // Update objective and constraint.
126 myPen.update(x,true,algo_state.iter);
127 con.update(x,true,algo_state.iter);
128 // Compute norm of the gradient of the Lagrangian
129 algo_state.value = myPen.value(x, zerotol);
130 myPen.gradient(*(state->gradientVec), x, zerotol);
131 con.applyAdjointJacobian(*g_,l,x,zerotol);
132 state->gradientVec->plus(*g_);
133 gLnorm_ = (state->gradientVec)->norm();
134 // Compute constraint violation
135 con.value(*(state->constraintVec),x, zerotol);
136 algo_state.cnorm = (state->constraintVec)->norm();
138 algo_state.gnorm = std::max(gLnorm_,compViolation_);
139 // Update state
140 algo_state.nfval++;
141 algo_state.ngrad++;
142 algo_state.ncval++;
143 }
144
146 Objective<Real> &obj,
148 AlgorithmState<Real> &algo_state) {
150 = dynamic_cast<MoreauYosidaPenalty<Real>&>(obj);
151 Real zerotol = std::sqrt(ROL_EPSILON<Real>());
152 ROL::Ptr<StepState<Real> > state = Step<Real>::getState();
153 // Update objective and constraint.
154 myPen.update(x,true,algo_state.iter);
155 // Compute norm of the gradient of the Lagrangian
156 algo_state.value = myPen.value(x, zerotol);
157 myPen.gradient(*(state->gradientVec), x, zerotol);
158 gLnorm_ = (state->gradientVec)->norm();
159 // Compute constraint violation
160 algo_state.cnorm = static_cast<Real>(0);
162 algo_state.gnorm = std::max(gLnorm_,compViolation_);
163 // Update state
164 algo_state.nfval++;
165 algo_state.ngrad++;
166 }
167
168public:
169
170 using Step<Real>::initialize;
171 using Step<Real>::compute;
172 using Step<Real>::update;
173
175
176 MoreauYosidaPenaltyStep(ROL::ParameterList &parlist)
177 : Step<Real>(), algo_(ROL::nullPtr),
178 x_(ROL::nullPtr), g_(ROL::nullPtr), l_(ROL::nullPtr),
179 tau_(10), print_(false), parlist_(parlist), subproblemIter_(0),
180 hasEquality_(false) {
181 // Parse parameters
182 Real ten(10), oem6(1.e-6), oem8(1.e-8);
183 ROL::ParameterList& steplist = parlist.sublist("Step").sublist("Moreau-Yosida Penalty");
184 Step<Real>::getState()->searchSize = steplist.get("Initial Penalty Parameter",ten);
185 tau_ = steplist.get("Penalty Parameter Growth Factor",ten);
186 updatePenalty_ = steplist.get("Update Penalty",true);
187 print_ = steplist.sublist("Subproblem").get("Print History",false);
188 // Set parameters for step subproblem
189 Real gtol = steplist.sublist("Subproblem").get("Optimality Tolerance",oem8);
190 Real ctol = steplist.sublist("Subproblem").get("Feasibility Tolerance",oem8);
191 Real stol = oem6*std::min(gtol,ctol);
192 int maxit = steplist.sublist("Subproblem").get("Iteration Limit",1000);
193 parlist_.sublist("Status Test").set("Gradient Tolerance", gtol);
194 parlist_.sublist("Status Test").set("Constraint Tolerance", ctol);
195 parlist_.sublist("Status Test").set("Step Tolerance", stol);
196 parlist_.sublist("Status Test").set("Iteration Limit", maxit);
197 // Get step name from parameterlist
198 stepname_ = steplist.sublist("Subproblem").get("Step Type","Composite Step");
200 }
201
206 AlgorithmState<Real> &algo_state ) {
207 hasEquality_ = true;
208 // Initialize step state
209 ROL::Ptr<StepState<Real> > state = Step<Real>::getState();
210 state->descentVec = x.clone();
211 state->gradientVec = g.clone();
212 state->constraintVec = c.clone();
213 // Initialize additional storage
214 x_ = x.clone();
215 g_ = g.clone();
216 l_ = l.clone();
217 // Project x onto the feasible set
218 if ( bnd.isActivated() ) {
219 bnd.project(x);
220 }
221 // Initialize the algorithm state
222 algo_state.nfval = 0;
223 algo_state.ncval = 0;
224 algo_state.ngrad = 0;
225 updateState(x,l,obj,con,bnd,algo_state);
226 }
227
232 AlgorithmState<Real> &algo_state ) {
233 // Initialize step state
234 ROL::Ptr<StepState<Real> > state = Step<Real>::getState();
235 state->descentVec = x.clone();
236 state->gradientVec = g.clone();
237 // Initialize additional storage
238 x_ = x.clone();
239 g_ = g.clone();
240 // Project x onto the feasible set
241 if ( bnd.isActivated() ) {
242 bnd.project(x);
243 }
244 // Initialize the algorithm state
245 algo_state.nfval = 0;
246 algo_state.ncval = 0;
247 algo_state.ngrad = 0;
248 updateState(x,obj,bnd,algo_state);
249
250 bnd_ = ROL::makePtr<BoundConstraint<Real>>();
251 bnd_->deactivate();
252 }
253
256 void compute( Vector<Real> &s, const Vector<Real> &x, const Vector<Real> &l,
259 AlgorithmState<Real> &algo_state ) {
260 //MoreauYosidaPenalty<Real> &myPen
261 // = dynamic_cast<MoreauYosidaPenalty<Real>&>(obj);
262 Real one(1);
263 Ptr<Objective<Real>> penObj;
265 Ptr<Objective<Real>> raw_obj = makePtrFromRef(obj);
266 Ptr<Constraint<Real>> raw_con = makePtrFromRef(con);
267 Ptr<StepState<Real>> state = Step<Real>::getState();
268 penObj = makePtr<AugmentedLagrangian<Real>>(raw_obj,raw_con,l,one,x,*(state->constraintVec),parlist_);
269 step_ = makePtr<AugmentedLagrangianStep<Real>>(parlist_);
270 }
271 else if (stepType_ == STEP_FLETCHER) {
272 Ptr<Objective<Real>> raw_obj = makePtrFromRef(obj);
273 Ptr<Constraint<Real>> raw_con = makePtrFromRef(con);
274 Ptr<StepState<Real>> state = Step<Real>::getState();
275 penObj = makePtr<Fletcher<Real>>(raw_obj,raw_con,x,*(state->constraintVec),parlist_);
276 step_ = makePtr<FletcherStep<Real>>(parlist_);
277 }
278 else {
279 penObj = makePtrFromRef(obj);
280 stepname_ = "Composite Step";
282 step_ = makePtr<CompositeStep<Real>>(parlist_);
283 }
284 status_ = makePtr<ConstraintStatusTest<Real>>(parlist_);
285 algo_ = ROL::makePtr<Algorithm<Real>>(step_,status_,false);
286 x_->set(x); l_->set(l);
287 algo_->run(*x_,*l_,*penObj,con,print_);
288 s.set(*x_); s.axpy(-one,x);
289 subproblemIter_ = (algo_->getState())->iter;
290 }
291
296 AlgorithmState<Real> &algo_state ) {
297 Real one(1);
299 = dynamic_cast<MoreauYosidaPenalty<Real>&>(obj);
300 if (stepType_ == STEP_BUNDLE) {
301 status_ = makePtr<BundleStatusTest<Real>>(parlist_);
302 step_ = makePtr<BundleStep<Real>>(parlist_);
303 }
304 else if (stepType_ == STEP_LINESEARCH) {
305 status_ = makePtr<StatusTest<Real>>(parlist_);
306 step_ = makePtr<LineSearchStep<Real>>(parlist_);
307 }
308 else {
309 status_ = makePtr<StatusTest<Real>>(parlist_);
310 step_ = makePtr<TrustRegionStep<Real>>(parlist_);
311 }
312 algo_ = ROL::makePtr<Algorithm<Real>>(step_,status_,false);
313 x_->set(x);
314 algo_->run(*x_,myPen,*bnd_,print_);
315 s.set(*x_); s.axpy(-one,x);
316 subproblemIter_ = (algo_->getState())->iter;
317 }
318
319
325 AlgorithmState<Real> &algo_state ) {
327 = dynamic_cast<MoreauYosidaPenalty<Real>&>(obj);
328 ROL::Ptr<StepState<Real> > state = Step<Real>::getState();
329 state->SPiter = subproblemIter_;
330 state->descentVec->set(s);
331 // Update iterate and Lagrange multiplier
332 x.plus(s);
333 l.set(*l_);
334 // Update objective and constraint
335 algo_state.iter++;
336 con.update(x,true,algo_state.iter);
337 myPen.update(x,true,algo_state.iter);
338 // Update state
339 updateState(x,l,obj,con,bnd,algo_state);
340 // Update multipliers
341 if (updatePenalty_) {
342 state->searchSize *= tau_;
343 }
344 myPen.updateMultipliers(state->searchSize,x);
345 algo_state.nfval += myPen.getNumberFunctionEvaluations() + ((algo_->getState())->nfval);
346 algo_state.ngrad += myPen.getNumberGradientEvaluations() + ((algo_->getState())->ngrad);
347 algo_state.ncval += (algo_->getState())->ncval;
348 algo_state.snorm = s.norm();
349 algo_state.iterateVec->set(x);
350 algo_state.lagmultVec->set(l);
351 }
352
355 void update( Vector<Real> &x, const Vector<Real> &s,
357 AlgorithmState<Real> &algo_state ) {
359 = dynamic_cast<MoreauYosidaPenalty<Real>&>(obj);
360 ROL::Ptr<StepState<Real> > state = Step<Real>::getState();
361 state->descentVec->set(s);
362 // Update iterate and Lagrange multiplier
363 x.plus(s);
364 // Update objective and constraint
365 algo_state.iter++;
366 myPen.update(x,true,algo_state.iter);
367 // Update state
368 updateState(x,obj,bnd,algo_state);
369 // Update multipliers
370 if (updatePenalty_) {
371 state->searchSize *= tau_;
372 }
373 myPen.updateMultipliers(state->searchSize,x);
374 algo_state.nfval += myPen.getNumberFunctionEvaluations() + ((algo_->getState())->nfval);
375 algo_state.ngrad += myPen.getNumberGradientEvaluations() + ((algo_->getState())->ngrad);
376 algo_state.snorm = s.norm();
377 algo_state.iterateVec->set(x);
378 }
379
382 std::string printHeader( void ) const {
383 std::stringstream hist;
384 hist << " ";
385 hist << std::setw(6) << std::left << "iter";
386 hist << std::setw(15) << std::left << "fval";
387 if (hasEquality_) {
388 hist << std::setw(15) << std::left << "cnorm";
389 }
390 hist << std::setw(15) << std::left << "gnorm";
391 hist << std::setw(15) << std::left << "ifeas";
392 hist << std::setw(15) << std::left << "snorm";
393 hist << std::setw(10) << std::left << "penalty";
394 hist << std::setw(8) << std::left << "#fval";
395 hist << std::setw(8) << std::left << "#grad";
396 if (hasEquality_) {
397 hist << std::setw(8) << std::left << "#cval";
398 }
399 hist << std::setw(8) << std::left << "subIter";
400 hist << "\n";
401 return hist.str();
402 }
403
406 std::string printName( void ) const {
407 std::stringstream hist;
408 hist << "\n" << " Moreau-Yosida Penalty solver";
409 hist << "\n";
410 return hist.str();
411 }
412
415 std::string print( AlgorithmState<Real> &algo_state, bool pHeader = false ) const {
416 std::stringstream hist;
417 hist << std::scientific << std::setprecision(6);
418 if ( algo_state.iter == 0 ) {
419 hist << printName();
420 }
421 if ( pHeader ) {
422 hist << printHeader();
423 }
424 if ( algo_state.iter == 0 ) {
425 hist << " ";
426 hist << std::setw(6) << std::left << algo_state.iter;
427 hist << std::setw(15) << std::left << algo_state.value;
428 if (hasEquality_) {
429 hist << std::setw(15) << std::left << algo_state.cnorm;
430 }
431 hist << std::setw(15) << std::left << gLnorm_;
432 hist << std::setw(15) << std::left << compViolation_;
433 hist << std::setw(15) << std::left << " ";
434 hist << std::scientific << std::setprecision(2);
435 hist << std::setw(10) << std::left << Step<Real>::getStepState()->searchSize;
436 hist << "\n";
437 }
438 else {
439 hist << " ";
440 hist << std::setw(6) << std::left << algo_state.iter;
441 hist << std::setw(15) << std::left << algo_state.value;
442 if (hasEquality_) {
443 hist << std::setw(15) << std::left << algo_state.cnorm;
444 }
445 hist << std::setw(15) << std::left << gLnorm_;
446 hist << std::setw(15) << std::left << compViolation_;
447 hist << std::setw(15) << std::left << algo_state.snorm;
448 hist << std::scientific << std::setprecision(2);
449 hist << std::setw(10) << std::left << Step<Real>::getStepState()->searchSize;
450 hist << std::scientific << std::setprecision(6);
451 hist << std::setw(8) << std::left << algo_state.nfval;
452 hist << std::setw(8) << std::left << algo_state.ngrad;
453 if (hasEquality_) {
454 hist << std::setw(8) << std::left << algo_state.ncval;
455 }
456 hist << std::setw(8) << std::left << subproblemIter_;
457 hist << "\n";
458 }
459 return hist.str();
460 }
461
462}; // class MoreauYosidaPenaltyStep
463
464} // namespace ROL
465
466#endif
virtual void update(const Vector< Real > &u_old, const Vector< Real > &u_new, const Vector< Real > &z, bool flag=true, int iter=-1)
virtual void initialize(const Vector< Real > &x)
Initialize temporary variables.
Contains definitions of custom data types in ROL.
Provides the interface to compute augmented Lagrangian steps.
Provides the interface to apply upper and lower bound constraints.
bool isActivated(void) const
Check if bounds are on.
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.
Defines the general constraint operator interface.
virtual void value(Vector< Real > &c, const Vector< Real > &x, Real &tol)=0
Evaluate the constraint operator at .
virtual void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update constraint function.
virtual void applyAdjointJacobian(Vector< Real > &ajv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the adjoint of the the constraint Jacobian at , , to vector .
void initialize(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
Initialize step without equality constraint.
MoreauYosidaPenaltyStep(ROL::ParameterList &parlist)
void compute(Vector< Real > &s, const Vector< Real > &x, const Vector< Real > &l, Objective< Real > &obj, Constraint< Real > &con, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
Compute step (equality and bound constraints).
void updateState(const Vector< Real > &x, Objective< Real > &obj, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
void update(Vector< Real > &x, const Vector< Real > &s, Objective< Real > &obj, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
Update step, for bound constraints.
ROL::Ptr< BoundConstraint< Real > > bnd_
void update(Vector< Real > &x, Vector< Real > &l, const Vector< Real > &s, Objective< Real > &obj, Constraint< Real > &con, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
Update step, if successful (equality and bound constraints).
void updateState(const Vector< Real > &x, const Vector< Real > &l, Objective< Real > &obj, Constraint< Real > &con, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
std::string printHeader(void) const
Print iterate header.
void initialize(Vector< Real > &x, const Vector< Real > &g, Vector< Real > &l, const Vector< Real > &c, Objective< Real > &obj, Constraint< Real > &con, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
Initialize step with equality constraint.
std::string print(AlgorithmState< Real > &algo_state, bool pHeader=false) const
Print iterate status.
void compute(Vector< Real > &s, const Vector< Real > &x, Objective< Real > &obj, BoundConstraint< Real > &bnd, AlgorithmState< Real > &algo_state)
Compute step for bound constraints.
std::string printName(void) const
Print step name.
ROL::Ptr< Algorithm< Real > > algo_
ROL::Ptr< StatusTest< Real > > status_
Provides the interface to evaluate the Moreau-Yosida penalty function.
Real testComplementarity(const ROL::Vector< Real > &x)
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update Moreau-Yosida penalty function.
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
void updateMultipliers(Real mu, const ROL::Vector< Real > &x)
Provides the interface to evaluate objective functions.
Provides the interface to compute optimization steps.
Definition ROL_Step.hpp:34
ROL::Ptr< StepState< Real > > getState(void)
Definition ROL_Step.hpp:39
Step(void)
Definition ROL_Step.hpp:47
Defines the linear algebra or vector space interface.
virtual Real norm() const =0
Returns where .
virtual void set(const Vector &x)
Set where .
virtual void plus(const Vector &x)=0
Compute , where .
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 .
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition ROL_Types.hpp:57
@ STEP_BUNDLE
@ STEP_AUGMENTEDLAGRANGIAN
@ STEP_LINESEARCH
@ STEP_COMPOSITESTEP
@ STEP_FLETCHER
EStep StringToEStep(std::string s)
State for algorithm class. Will be used for restarts.
ROL::Ptr< Vector< Real > > lagmultVec
ROL::Ptr< Vector< Real > > iterateVec