ROL
ROL_FletcherObjectiveE_Def.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_FLETCHEROBJECTIVEEDEF_H
11 #define ROL_FLETCHEROBJECTIVEEDEF_H
12 
13 namespace ROL {
14 
15 template<typename Real>
17  const ROL::Ptr<Constraint<Real>> &con,
18  const Vector<Real> &xprim,
19  const Vector<Real> &xdual,
20  const Vector<Real> &cprim,
21  const Vector<Real> &cdual,
22  ROL::ParameterList &parlist)
23  : FletcherObjectiveBase<Real>(obj, con, xprim, xdual, cprim, cdual, parlist) {
24  Tv_ = xdual.clone();
25  w_ = xdual.clone();
26  wdual_ = xprim.clone();
27  v_ = cdual.clone();
28  wg_ = xdual.clone();
29  vg_ = cdual.clone();
30 
31  xzeros_ = xdual.clone(); xzeros_->zero();
32  czeros_ = cprim.clone(); czeros_->zero();
33 }
34 
35 template<typename Real>
36 Real FletcherObjectiveE<Real>::value( const Vector<Real> &x, Real &tol ) {
37  Real val(0);
38  int key(0);
39  bool isComputed = fPhi_->get(val,key);
40  if( isComputed && multSolverError_*cnorm_ <= tol) {
41  tol = multSolverError_*cnorm_;
42  }
43  else {
44  // Reset tolerances
45  Real origTol = tol;
46  Real tol2 = origTol;
47  // Compute penalty function value
48  Real fval = FletcherObjectiveBase<Real>::objValue(x, tol2); tol2 = origTol;
49  multSolverError_ = origTol / (static_cast<Real>(2) * std::max(static_cast<Real>(1), cnorm_));
50  FletcherObjectiveBase<Real>::computeMultipliers(*cdual_, *gLdual_, x, *xdual_, *cprim_, multSolverError_);
51  tol = multSolverError_*cnorm_;
52  //val = fval - cprim_->dot(cdual_->dual());
53  val = fval - cprim_->apply(*cdual_);
54  if( quadPenaltyParameter_ > static_cast<Real>(0) )
55  val += static_cast<Real>(0.5)*quadPenaltyParameter_*(cprim_->dot(*cprim_));
56  // Store new penalty function value
57  fPhi_->set(val,key);
58  }
59  return val;
60 }
61 
62 template<typename Real>
64  int key(0);
65  bool isComputed = gPhi_->get(g,key);
66  if( isComputed && gradSolveError_ <= tol) {
67  tol = gradSolveError_;
68  }
69  else {
70  // Reset tolerances
71  Real origTol = tol;
72  Real tol2 = origTol;
73  // Compute penalty function gradient
74  gradSolveError_ = origTol / static_cast<Real>(2);
75  FletcherObjectiveBase<Real>::computeMultipliers(*cdual_, *gLdual_, x, *xdual_, *cprim_, gradSolveError_);
76  gL_->set(gLdual_->dual());
77  bool refine = isComputed;
78  // gPhi = sum y_i H_i w + sigma w + sum v_i H_i gL - H w + gL
79  solveAugmentedSystem( *wdual_, *vg_, *xzeros_, *cprim_, x, gradSolveError_, refine );
80  gradSolveError_ += multSolverError_;
81  tol = gradSolveError_;
82  wg_->set(wdual_->dual());
83  con_->applyAdjointHessian( g, *cdual_, *wdual_, x, tol2 ); tol2 = origTol;
84  g.axpy( sigma_, *wg_ );
85  obj_->hessVec( *Tv_, *wdual_, x, tol2 ); tol2 = origTol;
86  g.axpy( static_cast<Real>(-1), *Tv_ );
87  con_->applyAdjointHessian( *Tv_, *vg_, *gLdual_, x, tol2 ); tol2 = origTol;
88  g.plus( *Tv_ );
89  g.plus( *gL_ );
90  if( quadPenaltyParameter_ > static_cast<Real>(0) ) {
91  con_->applyAdjointJacobian( *Tv_, *cprim_, x, tol2 ); tol2 = origTol;
92  g.axpy( quadPenaltyParameter_, *Tv_ );
93  }
94  gPhi_->set(g,key);
95  }
96 }
97 
98 template<typename Real>
99 void FletcherObjectiveE<Real>::hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
100  // Reset tolerances
101  Real origTol = tol;
102  Real tol2 = origTol;
103  int key(0);
104  bool isComputed = y_->get(*cdual_,key);
105  if( !isComputed || !useInexact_) {
106  // hessVec tol is always set to ~1e-8. So if inexact linear system solves are used, then
107  // the multipliers will always get re-evaluated to high precision, which defeats the purpose
108  // of computing the objective/gradient approximately.
109  // Thus if inexact linear system solves are used, we will not update the multiplier estimates
110  // to high precision.
111  FletcherObjectiveBase<Real>::computeMultipliers(*cdual_, *gLdual_, x, *xdual_, *cprim_, tol);
112  }
113 
114  obj_->hessVec( hv, v, x, tol2 ); tol2 = origTol;
115  con_->applyAdjointHessian( *Tv_, *cdual_, v, x, tol2 ); tol2 = origTol;
116  hv.axpy(static_cast<Real>(-1), *Tv_ );
117 
118  tol2 = tol;
119  solveAugmentedSystem( *w_, *v_, hv, *czeros_, x, tol2 ); tol2 = origTol;
120  hv.scale( static_cast<Real>(-1) );
121  hv.plus( *w_ );
122 
123  Tv_->set(v.dual());
124  tol2 = tol;
125  solveAugmentedSystem( *w_, *v_, *Tv_, *czeros_, x, tol2 ); tol2 = origTol;
126  hv.axpy(static_cast<Real>(-2)*sigma_, *w_);
127 
128  wdual_->set(w_->dual());
129 
130  obj_->hessVec( *Tv_, *wdual_, x, tol2 ); tol2 = origTol;
131  hv.plus( *Tv_ );
132  con_->applyAdjointHessian( *Tv_, *cdual_, *wdual_, x, tol2 ); tol2 = origTol;
133  hv.axpy( static_cast<Real>(-1), *Tv_ );
134 
135  hv.axpy( static_cast<Real>(2)*sigma_, v );
136 
137  if( quadPenaltyParameter_ > static_cast<Real>(0) ) {
138  con_->applyJacobian( *b2_, v, x, tol2 ); tol2 = origTol;
139  con_->applyAdjointJacobian( *Tv_, *b2_, x, tol2 ); tol2 = origTol;
140  hv.axpy( quadPenaltyParameter_, *Tv_ );
141  con_->applyAdjointHessian( *Tv_, *cprim_, v, x, tol2); tol2 = origTol;
142  hv.axpy( -quadPenaltyParameter_, *Tv_ );
143  }
144 }
145 
146 template<typename Real>
148  Vector<Real> &v2,
149  const Vector<Real> &b1,
150  const Vector<Real> &b2,
151  const Vector<Real> &x,
152  Real &tol,
153  bool refine) {
154  // Ignore tol for now
155  ROL::Ptr<LinearOperator<Real>>
156  K = ROL::makePtr<AugSystem>(con_, makePtrFromRef(x), delta_);
157  ROL::Ptr<LinearOperator<Real>>
158  P = ROL::makePtr<AugSystemPrecond>(con_, makePtrFromRef(x), makePtrFromRef(b1));
159 
160  vv_->zero();
161  bb_->zero();
162  if( refine ) {
163  // TODO: Make sure this tol is actually ok...
164  Real origTol = tol;
165  w1_->set(v1);
166  w2_->set(v2);
167  K->apply(*bb_, *ww_, tol); tol = origTol;
168  bb_->scale(static_cast<Real>(-1));
169  }
170  b1_->plus(b1);
171  b2_->plus(b2);
172 
173  // If inexact, change tolerance
174  if( useInexact_ ) krylov_->resetAbsoluteTolerance(tol);
175 
176  //con_->solveAugmentedSystem(*v1_,*v2_,*b1_,*b2_,x,tol);
177  flagKrylov_ = 0;
178  tol = krylov_->run(*vv_,*K,*bb_,*P,iterKrylov_,flagKrylov_);
179 
180  if( refine ) {
181  v1.plus(*v1_);
182  v2.plus(*v2_);
183  } else {
184  v1.set(*v1_);
185  v2.set(*v2_);
186  }
187 }
188 
189 } // namespace ROL
190 
191 #endif
Provides the interface to evaluate objective functions.
void solveAugmentedSystem(Vector< Real > &v1, Vector< Real > &v2, const Vector< Real > &b1, const Vector< Real > &b2, const Vector< Real > &x, Real &tol, bool refine=false) override
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:192
virtual void scale(const Real alpha)=0
Compute where .
void computeMultipliers(Vector< Real > &y, Vector< Real > &gL, const Vector< Real > &x, Vector< Real > &g, Vector< Real > &c, Real tol)
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Real objValue(const Vector< Real > &x, Real &tol)
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:119
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol) override
Compute gradient.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Ptr< Vector< Real > > czeros_
FletcherObjectiveE(const ROL::Ptr< Objective< Real >> &obj, const ROL::Ptr< Constraint< Real >> &con, const Vector< Real > &xprim, const Vector< Real > &xdual, const Vector< Real > &cprim, const Vector< Real > &cdual, ROL::ParameterList &parlist)
Ptr< Vector< Real > > xzeros_
Real value(const Vector< Real > &x, Real &tol) override
Compute value.
Ptr< Vector< Real > > wdual_
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol) override
Apply Hessian approximation to vector.
const Ptr< Obj > obj_
Defines the general constraint operator interface.