ROL
ROL_PrimalDualInteriorPointReducedResidual.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_PRIMALDUALINTERIORPOINTREDUCEDRESIDUAL_H
45 #define ROL_PRIMALDUALINTERIORPOINTREDUCEDRESIDUAL_H
46 
48 #include "ROL_Constraint.hpp"
49 
50 #include <iostream>
51 
108 namespace ROL {
109 
110 template<class Real>
112 
113  typedef ROL::ParameterList PL;
114 
115  typedef Vector<Real> V;
122 
123  typedef Elementwise::ValueSet<Real> ValueSet;
124 
125  typedef typename PV::size_type size_type;
126 
127 private:
128 
129  static const size_type OPT = 0;
130  static const size_type EQUAL = 1;
131  static const size_type LOWER = 2;
132  static const size_type UPPER = 3;
133 
134  ROL::Ptr<const V> x_; // Optimization vector
135  ROL::Ptr<const V> l_; // constraint multiplier
136  ROL::Ptr<const V> zl_; // Lower bound multiplier
137  ROL::Ptr<const V> zu_; // Upper bound multiplier
138 
139  ROL::Ptr<const V> xl_; // Lower bound
140  ROL::Ptr<const V> xu_; // Upper bound
141 
142  const ROL::Ptr<const V> maskL_;
143  const ROL::Ptr<const V> maskU_;
144 
145  ROL::Ptr<V> scratch_;
146 
147  const ROL::Ptr<PENALTY> penalty_;
148  const ROL::Ptr<OBJ> obj_;
149  const ROL::Ptr<CON> con_;
150 
151 
152 public:
153 
154  PrimalDualInteriorPointResidual( const ROL::Ptr<PENALTY> &penalty,
155  const ROL::Ptr<CON> &con,
156  const V &x,
157  ROL::Ptr<V> &scratch ) :
158  penalty_(penalty), con_(con), scratch_(scratch) {
159 
160  obj_ = penalty_->getObjective();
161  maskL_ = penalty_->getLowerMask();
162  maskU_ = penalty_->getUpperMask();
163 
164  ROL::Ptr<BND> bnd = penalty_->getBoundConstraint();
165  xl_ = bnd->getLowerBound();
166  xu_ = bnd->getUpperBound();
167 
168 
169  // Get access to the four components
170  const PV &x_pv = dynamic_cast<const PV&>(x);
171 
172  x_ = x_pv.get(OPT);
173  l_ = x_pv.get(EQUAL);
174  zl_ = x_pv.get(LOWER);
175  zu_ = x_pv.get(UPPER);
176 
177  }
178 
179 
180  void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
181 
182  // Get access to the four components
183  const PV &x_pv = dynamic_cast<const PV&>(x);
184 
185  x_ = x_pv.get(OPT);
186  l_ = x_pv.get(EQUAL);
187  zl_ = x_pv.get(LOWER);
188  zu_ = x_pv.get(UPPER);
189 
190  obj_->update(*x_,flag,iter);
191  con_->update(*x_,flag,iter);
192  }
193 
194 
195  // Evaluate the gradient of the Lagrangian
196  void value( V &c, const V &x, Real &tol ) {
197 
198 
199  PV &c_pv = dynamic_cast<PV&>(c);
200  const PV &x_pv = dynamic_cast<const PV&>(x);
201 
202  x_ = x_pv.get(OPT);
203  l_ = x_pv.get(EQUAL);
204  zl_ = x_pv.get(LOWER);
205  zu_ = x_pv.get(UPPER);
206 
207  ROL::Ptr<V> cx = c_pv.get(OPT);
208  ROL::Ptr<V> cl = c_pv.get(EQUAL);
209 
210  // TODO: Add check as to whether we really need to recompute these
211  penalty_->gradient(*cx,*x_,tol);
212  con_->applyAdjointJacobian(*scratch_,*l_,*x_,tol);
213 
214  // \f$ c_x = \nabla \phi_mu(x) + J^\ast \lambda \f$
215  cx_->plus(*scratch_);
216 
217  con_->value(*cl_,*x_,tol);
218 
219  }
220 
221  void applyJacobian( V &jv, const V &v, const V &x, Real &tol ) {
222 
223 
224 
225  PV &jv_pv = dynamic_cast<PV&>(jv);
226  const PV &v_pv = dynamic_cast<const PV&>(v);
227  const PV &x_pv = dynamic_cast<const PV&>(x);
228 
229  // output vector components
230  ROL::Ptr<V> jvx = jv_pv.get(OPT);
231  ROL::Ptr<V> jvl = jv_pv.get(EQUAL);
232 
233  // input vector components
234  ROL::Ptr<const V> vx = v_pv.get(OPT);
235  ROL::Ptr<const V> vl = v_pv.get(EQUAL);
236 
237  x_ = x_pv.get(OPT);
238  l_ = x_pv.get(EQUAL);
239 
240  // \f$
241  obj_->hessVec(*jvx,*vx,*x_,tol);
242  con_->applyAdjointHessian(*scratch_,*l_,*vx,*x_,tol);
243  jvx->plus(*scratch_);
244 
245  // \f$J^\ast d_\lambda \f$
246  con_->applyAdjointJacobian(*scratch_,*vl,*x_,tol);
247  jvx->plus(*scratch_);
248 
249 
250  Elementwise::DivideAndInvert<Real> divinv;
251  Elementwise::Multiply<Real> mult;
252 
253  // Note that indices corresponding to infinite bounds should automatically lead to
254  // zero diagonal contributions to the Sigma operators
255  scratch_->set(*x_);
256  scratch_->axpy(-1.0,*xl_); // x-l
257  scratch_->applyBinary(divinv,*zl_); // zl/(x-l)
258  scratch_->applyBinary(mult,*vx); // zl*vx/(x-l) = Sigma_l*vx
259 
260  jvx->plu(*scratch_);
261 
262  scratch_->set(*xu_);
263  scratch_->axpy(-1.0,*x_); // u-x
264  scratch_->applyBinary(divinv,*zu_); // zu/(u-x)
265  scratch_->applyBinary(mult,*vx); // zu*vx/(u-x) = Sigma_u*vx
266 
267  jvx->plus(*scratch_);
268 
269 
270 
271 
272 
273 
274 
275 // \f[ [W+(X-L)^{-1}+(U-X)^{-1}]d_x + J^\ast d_\lambda =
276 // -g_x + (U-X)^{-1}g_{z_u} - (L-X)^{-1}g_{z_l} \f]
277 
278 
279 
280  }
281 
283  return nfval_;
284  }
285 
287  return ngrad_;
288  }
289 
291  return ncval_;
292  }
293 
294 
295 }; // class PrimalDualInteriorPointResidual
296 
297 } // namespace ROL
298 
299 #endif // ROL_PRIMALDUALKKTOPERATOR_H
Provides the interface to evaluate objective functions.
void value(V &c, const V &x, Real &tol)
Evaluate the constraint operator at .
ROL::Ptr< const Vector< Real > > get(size_type i) const
Defines the linear algebra of vector space on a generic partitioned vector.
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update constraint functions. x is the optimization variable, flag = true if optimization variable is ...
Symmetrized form of the KKT operator for the Type-EB problem with equality and bound multipliers...
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
Provides the interface to evaluate the Interior Pointy log barrier penalty function with upper and lo...
PrimalDualInteriorPointResidual(const ROL::Ptr< PENALTY > &penalty, const ROL::Ptr< CON > &con, const V &x, ROL::Ptr< V > &scratch)
void applyJacobian(V &jv, const V &v, const V &x, Real &tol)
Apply the constraint Jacobian at , , to vector .
Provides the interface to apply a linear operator.
Provides the interface to apply upper and lower bound constraints.
std::vector< PV >::size_type size_type
Defines the general constraint operator interface.