ROL
ROL_QuadraticPenalty_SimOpt.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_QUADRATICPENALTY_SIMOPT_H
45 #define ROL_QUADRATICPENALTY_SIMOPT_H
46 
47 #include "ROL_Objective_SimOpt.hpp"
49 #include "ROL_Vector.hpp"
50 #include "ROL_Types.hpp"
51 #include "ROL_Ptr.hpp"
52 #include <iostream>
53 
88 namespace ROL {
89 
90 template <class Real>
92 private:
93  // Required for quadratic penalty definition
94  const ROL::Ptr<Constraint_SimOpt<Real> > con_;
95  ROL::Ptr<Vector<Real> > multiplier_;
97 
98  // Auxiliary storage
99  ROL::Ptr<Vector<Real> > primalMultiplierVector_;
100  ROL::Ptr<Vector<Real> > dualSimVector_;
101  ROL::Ptr<Vector<Real> > dualOptVector_;
102  ROL::Ptr<Vector<Real> > primalConVector_;
103 
104  // Constraint evaluations
105  ROL::Ptr<Vector<Real> > conValue_;
106 
107  // Evaluation counters
108  int ncval_;
109 
110  // User defined options
111  const bool useScaling_;
112  const int HessianApprox_;
113 
114  // Flags to recompute quantities
116 
117  void evaluateConstraint(const Vector<Real> &u, const Vector<Real> &z, Real &tol) {
118  if ( !isConstraintComputed_ ) {
119  // Evaluate constraint
120  con_->value(*conValue_,u,z,tol); ncval_++;
121  isConstraintComputed_ = true;
122  }
123  }
124 
125 public:
127  const Vector<Real> &multiplier,
128  const Real penaltyParameter,
129  const Vector<Real> &simVec,
130  const Vector<Real> &optVec,
131  const Vector<Real> &conVec,
132  const bool useScaling = false,
133  const int HessianApprox = 0 )
134  : con_(con), penaltyParameter_(penaltyParameter), ncval_(0),
135  useScaling_(useScaling), HessianApprox_(HessianApprox), isConstraintComputed_(false) {
136 
137  dualSimVector_ = simVec.dual().clone();
138  dualOptVector_ = optVec.dual().clone();
139  primalConVector_ = conVec.clone();
140  conValue_ = conVec.clone();
141  multiplier_ = multiplier.clone();
142  primalMultiplierVector_ = multiplier.clone();
143  }
144 
145  virtual void update( const Vector<Real> &u, const Vector<Real> &z, bool flag = true, int iter = -1 ) {
146  con_->update(u,z,flag,iter);
147  isConstraintComputed_ = ( flag ? false : isConstraintComputed_ );
148  }
149 
150  virtual Real value( const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
151  // Evaluate constraint
152  evaluateConstraint(u,z,tol);
153  // Apply Lagrange multiplier to constraint
154  Real cval = multiplier_->dot(conValue_->dual());
155  // Compute penalty term
156  Real pval = conValue_->dot(*conValue_);
157  // Compute quadratic penalty value
158  const Real half(0.5);
159  Real val(0);
160  if (useScaling_) {
161  val = cval/penaltyParameter_ + half*pval;
162  }
163  else {
164  val = cval + half*penaltyParameter_*pval;
165  }
166  return val;
167  }
168 
169  virtual void gradient_1( Vector<Real> &g, const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
170  // Evaluate constraint
171  evaluateConstraint(u,z,tol);
172  // Compute gradient of Augmented Lagrangian
173  primalMultiplierVector_->set(conValue_->dual());
174  if ( useScaling_ ) {
175  primalMultiplierVector_->axpy(static_cast<Real>(1)/penaltyParameter_,*multiplier_);
176  }
177  else {
180  }
181  con_->applyAdjointJacobian_1(g,*primalMultiplierVector_,u,z,tol);
182  }
183 
184  virtual void gradient_2( Vector<Real> &g, const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
185  // Evaluate constraint
186  evaluateConstraint(u,z,tol);
187  // Compute gradient of Augmented Lagrangian
188  primalMultiplierVector_->set(conValue_->dual());
189  if ( useScaling_ ) {
190  primalMultiplierVector_->axpy(static_cast<Real>(1)/penaltyParameter_,*multiplier_);
191  }
192  else {
195  }
196  con_->applyAdjointJacobian_2(g,*primalMultiplierVector_,u,z,tol);
197  }
198 
199  virtual void hessVec_11( Vector<Real> &hv, const Vector<Real> &v,
200  const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
201  // Apply objective Hessian to a vector
202  if (HessianApprox_ < 2) {
203  con_->applyJacobian_1(*primalConVector_,v,u,z,tol);
204  con_->applyAdjointJacobian_1(hv,primalConVector_->dual(),u,z,tol);
205  if (!useScaling_) {
207  }
208 
209  if (HessianApprox_ == 0) {
210  // Evaluate constraint
211  evaluateConstraint(u,z,tol);
212  // Apply Augmented Lagrangian Hessian to a vector
213  primalMultiplierVector_->set(conValue_->dual());
214  if ( useScaling_ ) {
215  primalMultiplierVector_->axpy(static_cast<Real>(1)/penaltyParameter_,*multiplier_);
216  }
217  else {
220  }
221  con_->applyAdjointHessian_11(*dualSimVector_,*primalMultiplierVector_,v,u,z,tol);
222  hv.plus(*dualSimVector_);
223  }
224  }
225  else {
226  hv.zero();
227  }
228  }
229 
230  virtual void hessVec_12( Vector<Real> &hv, const Vector<Real> &v,
231  const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
232  // Apply objective Hessian to a vector
233  if (HessianApprox_ < 2) {
234  con_->applyJacobian_2(*primalConVector_,v,u,z,tol);
235  con_->applyAdjointJacobian_1(hv,primalConVector_->dual(),u,z,tol);
236  if (!useScaling_) {
238  }
239 
240  if (HessianApprox_ == 0) {
241  // Evaluate constraint
242  evaluateConstraint(u,z,tol);
243  // Apply Augmented Lagrangian Hessian to a vector
244  primalMultiplierVector_->set(conValue_->dual());
245  if ( useScaling_ ) {
246  primalMultiplierVector_->axpy(static_cast<Real>(1)/penaltyParameter_,*multiplier_);
247  }
248  else {
251  }
252  con_->applyAdjointHessian_21(*dualSimVector_,*primalMultiplierVector_,v,u,z,tol);
253  hv.plus(*dualSimVector_);
254  }
255  }
256  else {
257  hv.zero();
258  }
259  }
260 
261  virtual void hessVec_21( Vector<Real> &hv, const Vector<Real> &v,
262  const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
263  // Apply objective Hessian to a vector
264  if (HessianApprox_ < 2) {
265  con_->applyJacobian_1(*primalConVector_,v,u,z,tol);
266  con_->applyAdjointJacobian_2(hv,primalConVector_->dual(),u,z,tol);
267  if (!useScaling_) {
269  }
270 
271  if (HessianApprox_ == 0) {
272  // Evaluate constraint
273  evaluateConstraint(u,z,tol);
274  // Apply Augmented Lagrangian Hessian to a vector
275  primalMultiplierVector_->set(conValue_->dual());
276  if ( useScaling_ ) {
277  primalMultiplierVector_->axpy(static_cast<Real>(1)/penaltyParameter_,*multiplier_);
278  }
279  else {
282  }
283  con_->applyAdjointHessian_12(*dualOptVector_,*primalMultiplierVector_,v,u,z,tol);
284  hv.plus(*dualOptVector_);
285  }
286  }
287  else {
288  hv.zero();
289  }
290  }
291 
292  virtual void hessVec_22( Vector<Real> &hv, const Vector<Real> &v,
293  const Vector<Real> &u, const Vector<Real> &z, Real &tol ) {
294  // Apply objective Hessian to a vector
295  if (HessianApprox_ < 2) {
296  con_->applyJacobian_2(*primalConVector_,v,u,z,tol);
297  con_->applyAdjointJacobian_2(hv,primalConVector_->dual(),u,z,tol);
298  if (!useScaling_) {
300  }
301 
302  if (HessianApprox_ == 0) {
303  // Evaluate constraint
304  evaluateConstraint(u,z,tol);
305  // Apply Augmented Lagrangian Hessian to a vector
306  primalMultiplierVector_->set(conValue_->dual());
307  if ( useScaling_ ) {
308  primalMultiplierVector_->axpy(static_cast<Real>(1)/penaltyParameter_,*multiplier_);
309  }
310  else {
313  }
314  con_->applyAdjointHessian_22(*dualOptVector_,*primalMultiplierVector_,v,u,z,tol);
315  hv.plus(*dualOptVector_);
316  }
317  }
318  else {
319  hv.zero();
320  }
321  }
322 
323  // Return constraint value
324  virtual void getConstraintVec(Vector<Real> &c, const Vector<Real> &u, const Vector<Real> &z) {
325  Real tol = std::sqrt(ROL_EPSILON<Real>());
326  // Evaluate constraint
327  evaluateConstraint(u,z,tol);
328  c.set(*conValue_);
329  }
330 
331  // Return total number of constraint evaluations
332  virtual int getNumberConstraintEvaluations(void) const {
333  return ncval_;
334  }
335 
336  // Reset with upated penalty parameter
337  virtual void reset(const Vector<Real> &multiplier, const Real penaltyParameter) {
338  ncval_ = 0;
339  multiplier_->set(multiplier);
340  penaltyParameter_ = penaltyParameter;
341  }
342 }; // class AugmentedLagrangian
343 
344 } // namespace ROL
345 
346 #endif
Provides the interface to evaluate simulation-based objective functions.
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Definition: ROL_Vector.hpp:226
const ROL::Ptr< Constraint_SimOpt< Real > > con_
virtual void scale(const Real alpha)=0
Compute where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void hessVec_21(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol)
virtual void plus(const Vector &x)=0
Compute , where .
Contains definitions of custom data types in ROL.
virtual void hessVec_22(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol)
Provides the interface to evaluate the quadratic SimOpt constraint penalty.
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:167
ROL::Ptr< Vector< Real > > multiplier_
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
virtual int getNumberConstraintEvaluations(void) const
ROL::Ptr< Vector< Real > > primalConVector_
ROL::Ptr< Vector< Real > > primalMultiplierVector_
virtual void hessVec_11(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol)
Apply Hessian approximation to vector.
ROL::Ptr< Vector< Real > > dualOptVector_
virtual Real value(const Vector< Real > &u, const Vector< Real > &z, Real &tol)
Compute value.
void evaluateConstraint(const Vector< Real > &u, const Vector< Real > &z, Real &tol)
virtual void hessVec_12(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol)
virtual void getConstraintVec(Vector< Real > &c, const Vector< Real > &u, const Vector< Real > &z)
ROL::Ptr< Vector< Real > > dualSimVector_
virtual void reset(const Vector< Real > &multiplier, const Real penaltyParameter)
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:209
virtual void update(const Vector< Real > &u, const Vector< Real > &z, bool flag=true, int iter=-1)
Update objective function. u is an iterate, z is an iterate, flag = true if the iterate has changed...
Defines the constraint operator interface for simulation-based optimization.
virtual void gradient_1(Vector< Real > &g, const Vector< Real > &u, const Vector< Real > &z, Real &tol)
Compute gradient with respect to first component.
virtual void gradient_2(Vector< Real > &g, const Vector< Real > &u, const Vector< Real > &z, Real &tol)
Compute gradient with respect to second component.
QuadraticPenalty_SimOpt(const ROL::Ptr< Constraint_SimOpt< Real > > &con, const Vector< Real > &multiplier, const Real penaltyParameter, const Vector< Real > &simVec, const Vector< Real > &optVec, const Vector< Real > &conVec, const bool useScaling=false, const int HessianApprox=0)