ROL
ROL_BoundFletcher.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 
45 #ifndef ROL_BOUNDFLETCHER_H
46 #define ROL_BOUNDFLETCHER_H
47 
48 #include "ROL_FletcherBase.hpp"
49 #include "ROL_Objective.hpp"
50 #include "ROL_Constraint.hpp"
51 #include "ROL_Vector.hpp"
52 #include "ROL_Types.hpp"
53 #include "ROL_Ptr.hpp"
54 #include "ROL_Krylov.hpp"
56 #include <iostream>
57 
58 namespace ROL {
59 
60 template <class Real>
61 class BoundFletcher : public FletcherBase<Real> {
62 private:
63  // Required for Fletcher penalty function definition
66  Ptr<const Vector<Real> > low_;
67  Ptr<const Vector<Real> > upp_;
68 
70 
71  // Evaluation counters
75 
76  using FletcherBase<Real>::fPhi_; // value of penalty function
77  using FletcherBase<Real>::gPhi_; // gradient of penalty function
78 
79  using FletcherBase<Real>::y_; // multiplier estimate
80 
81  using FletcherBase<Real>::fval_; // value of objective function
82  using FletcherBase<Real>::g_; // gradient of objective value
83  using FletcherBase<Real>::c_; // constraint value
84  using FletcherBase<Real>::scaledc_; // penaltyParameter_ * c_
85  using FletcherBase<Real>::gL_; // gradient of Lagrangian (g - A*y)
86 
93 
94  using FletcherBase<Real>::delta_; // regularization parameter
95 
96  Ptr<Vector<Real> > Q_;
97  Ptr<Vector<Real> > umx_;
98  Ptr<Vector<Real> > DQ_;
99  Ptr<Vector<Real> > Qsqrt_;
100 
102  // Flag to determine type of augmented system to solve
103  // AugSolve_ = 0 : Symmetric system
104  // [ I Q^{1/2} A][w] = [b1]
105  // [A'Q^{1/2} ][v] [b2]
106  // AugSolve_ = 1 : Nonsymmetric system
107  // [ I A][w] = [b1]
108  // [A'Q ][v] [b2]
110 
111  Ptr<Vector<Real> > QsgL_; // scaled gradient of Lagrangian Q^{1/2}*(g-A*y)
112  Ptr<Vector<Real> > QgL_; // scaled gradient of Lagrangian Q*(g-A*y)
113  Ptr<Vector<Real> > Qsg_; // Scaled gradient of objective Q^{1/2}*g
114  Ptr<Vector<Real> > DQgL_; // gradient of Lagrangian scaled by DQ, DQ*(g-A*y)
115  Ptr<Vector<Real> > Qv_; // used in augmented system solve
116 
117  // Temporaries
118  Ptr<Vector<Real> > Tv_; // Temporary for matvecs
119  Ptr<Vector<Real> > w_; // first component of augmented system solve solution
120  Ptr<Vector<Real> > v_; // second component of augmented system solve solution
121  Ptr<Vector<Real> > htmp1_; // Temporary for rhs
122  Ptr<Vector<Real> > htmp2_; // Temporary for rhs
123 
124  Ptr<Vector<Real> > xzeros_; // zero vector
125  Ptr<Vector<Real> > czeros_; // zero vector
126 
128 
131 
132  using FletcherBase<Real>::multSolverError_; // Error from augmented system solve in value()
133  using FletcherBase<Real>::gradSolveError_; // Error from augmented system solve in gradient()
134 
135  // For Augmented system solves
145 
146  class DiffLower : public Elementwise::BinaryFunction<Real> {
147  public:
148  DiffLower(void) {}
149  Real apply(const Real& x, const Real& y) const {
150  const Real NINF(ROL_NINF<Real>());
151  return (y <= NINF ? static_cast<Real>(-1.) : x - y);
152  }
153  };
154 
155  class DiffUpper : public Elementwise::BinaryFunction<Real> {
156  public:
157  DiffUpper(void) {}
158  Real apply(const Real& x, const Real& y) const {
159  const Real INF(ROL_INF<Real>());
160  return (y >= INF ? static_cast<Real>(-1.) : y - x);
161  }
162  };
163 
164  class FormQ : public Elementwise::BinaryFunction<Real> {
165  public:
166  FormQ(void) {}
167  Real apply(const Real& x, const Real& y) const {
168  Real zero(0.);
169  if( x < zero && y < zero) {
170  return static_cast<Real>(1);
171  }
172  if( x < zero && y >= zero ) {
173  return y;
174  }
175  if( x >= zero && y < zero ) {
176  return x;
177  }
178  return std::min(x, y);
179  }
180  };
181 
182  class FormDQ : public Elementwise::BinaryFunction<Real> {
183  public:
184  FormDQ(void) {}
185  Real apply(const Real& x, const Real& y) const {
186  Real zero(0.), one(1.), mone(-1.);
187  if( x < zero && y < zero) {
188  return zero;
189  }
190  if( x < zero && y >= zero ) {
191  return mone;
192  }
193  if( x >= zero && y < zero ) {
194  return one;
195  }
196  if( x < y ) {
197  return one;
198  } else if( y < x) {
199  return mone;
200  } else {
201  return zero;
202  }
203  }
204  };
205 
206  class AugSystemSym : public LinearOperator<Real> {
207  private:
208  const Ptr<Constraint<Real> > con_;
209  const Ptr<const Vector<Real> > x_;
210  const Ptr<Vector<Real> > Qsqrt_;
211  const Ptr<Vector<Real> > Qv_;
212  const Real delta_;
213  public:
214  AugSystemSym(const Ptr<Constraint<Real> > &con,
215  const Ptr<const Vector<Real> > &x,
216  const Ptr<Vector<Real> > &Qsqrt,
217  const Ptr<Vector<Real> > &Qv,
218  const Real delta) : con_(con), x_(x), Qsqrt_(Qsqrt), Qv_(Qv), delta_(delta) {}
219 
220  void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
221  PartitionedVector<Real> &Hvp = dynamic_cast<PartitionedVector<Real>&>(Hv);
222  const PartitionedVector<Real> &vp = dynamic_cast<const PartitionedVector<Real>&>(v);
223 
224  con_->applyAdjointJacobian(*(Hvp.get(0)), *(vp.get(1)), *x_, tol);
225  Hvp.get(0)->applyBinary(Elementwise::Multiply<Real>(), *Qsqrt_);
226  Hvp.get(0)->plus(*(vp.get(0)));
227 
228  Qv_->set(*(vp.get(0)));
229  Qv_->applyBinary(Elementwise::Multiply<Real>(), *Qsqrt_);
230  con_->applyJacobian(*(Hvp.get(1)), *(Qv_), *x_, tol);
231  Hvp.get(1)->axpy(-delta_*delta_, *(vp.get(1)));
232  }
233  };
234 
235  class AugSystemNonSym : public LinearOperator<Real> {
236  private:
237  const Ptr<Constraint<Real> > con_;
238  const Ptr<const Vector<Real> > x_;
239  const Ptr<Vector<Real> > Q_;
240  const Ptr<Vector<Real> > Qv_;
241  const Real delta_;
242  public:
244  const Ptr<const Vector<Real> > &x,
245  const Ptr<Vector<Real> > &Q,
246  const Ptr<Vector<Real> > &Qv,
247  const Real delta) : con_(con), x_(x), Q_(Q), Qv_(Qv), delta_(delta) {}
248 
249  void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
250  PartitionedVector<Real> &Hvp = dynamic_cast<PartitionedVector<Real>&>(Hv);
251  const PartitionedVector<Real> &vp = dynamic_cast<const PartitionedVector<Real>&>(v);
252 
253  con_->applyAdjointJacobian(*(Hvp.get(0)), *(vp.get(1)), *x_, tol);
254  Hvp.get(0)->plus(*(vp.get(0)));
255 
256  Qv_->set(*(vp.get(0)));
257  Qv_->applyBinary(Elementwise::Multiply<Real>(), *Q_);
258  con_->applyJacobian(*(Hvp.get(1)), *(Qv_), *x_, tol);
259  Hvp.get(1)->axpy(-delta_*delta_, *(vp.get(1)));
260  }
261  };
262 
263  class AugSystemPrecond : public LinearOperator<Real> {
264  private:
265  const Ptr<Constraint<Real> > con_;
266  const Ptr<const Vector<Real> > x_;
267  public:
269  const Ptr<const Vector<Real> > x) : con_(con), x_(x) {}
270 
271  void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
272  Hv.set(v.dual());
273  }
274  void applyInverse(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
275  Real zero(0);
276  PartitionedVector<Real> &Hvp = dynamic_cast<PartitionedVector<Real>&>(Hv);
277  const PartitionedVector<Real> &vp = dynamic_cast<const PartitionedVector<Real>&>(v);
278 
279  Hvp.set(0, *(vp.get(0)));
280  // Second x should be dual, but unused?
281  con_->applyPreconditioner(*(Hvp.get(1)),*(vp.get(1)),*x_,*x_, zero);
282  }
283  };
284 
285 public:
286  BoundFletcher(const ROL::Ptr<Objective<Real> > &obj,
287  const ROL::Ptr<Constraint<Real> > &con,
288  const ROL::Ptr<BoundConstraint<Real> > &bnd,
289  const Vector<Real> &optVec,
290  const Vector<Real> &conVec,
291  ROL::ParameterList &parlist)
292  : FletcherBase<Real>(obj, con), isQComputed_(false), isDQComputed_(false) {
293 
294  low_ = bnd->getLowerBound();
295  upp_ = bnd->getUpperBound();
296 
297  gPhi_ = optVec.dual().clone();
298  y_ = conVec.dual().clone();
299  g_ = optVec.dual().clone();
300  gL_ = optVec.dual().clone();
301  c_ = conVec.clone();
302  scaledc_ = conVec.clone();
303 
304  Q_ = optVec.clone();
305  DQ_ = optVec.clone();
306  umx_ = optVec.clone();
307  Qsqrt_ = optVec.clone();
308  Qv_ = optVec.dual().clone();
309  QsgL_ = optVec.dual().clone();
310  QgL_ = optVec.dual().clone();
311  Qsg_ = optVec.dual().clone();
312  DQgL_ = optVec.dual().clone();
313 
314  Tv_ = optVec.dual().clone();
315  w_ = optVec.dual().clone();
316  v_ = conVec.dual().clone();
317  htmp1_ = optVec.dual().clone();
318  htmp2_ = conVec.clone();
319 
320  xzeros_ = optVec.dual().clone();
321  xzeros_->zero();
322  czeros_ = conVec.clone();
323  czeros_->zero();
324 
325  v1_ = optVec.dual().clone();
326  v2_ = conVec.dual().clone();
327  vv_ = makePtr<PartitionedVector<Real>>(std::vector<Ptr<Vector<Real>> >({v1_, v2_}));
328 
329  b1_ = optVec.dual().clone();
330  b2_ = conVec.clone();
331  bb_ = makePtr<PartitionedVector<Real>>(std::vector<Ptr<Vector<Real>> >({b1_, b2_}));
332 
333  ROL::ParameterList& sublist = parlist.sublist("Step").sublist("Fletcher");
334  HessianApprox_ = sublist.get("Level of Hessian Approximation", 0);
335 
336  AugSolve_ = sublist.get("Type of Augmented System Solve", 0);
337  AugSolve_ = (0 < AugSolve_ && AugSolve_ < 2) ? AugSolve_ : 0;
338 
339  penaltyParameter_ = sublist.get("Penalty Parameter", 1.0);
340 
341  delta_ = sublist.get("Regularization Parameter", 0.0);
342 
343  useInexact_ = sublist.get("Inexact Solves", false);
344 
345  ROL::ParameterList krylovList;
346  Real atol = static_cast<Real>(1e-12);
347  Real rtol = static_cast<Real>(1e-2);
348  krylovList.sublist("General").sublist("Krylov").set("Type", "GMRES");
349  krylovList.sublist("General").sublist("Krylov").set("Absolute Tolerance", atol);
350  krylovList.sublist("General").sublist("Krylov").set("Relative Tolerance", rtol);
351  krylovList.sublist("General").sublist("Krylov").set("Iteration Limit", 200);
352  krylov_ = KrylovFactory<Real>(krylovList);
353  }
354 
355  void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
356  obj_->update(x,flag,iter);
357  con_->update(x,flag,iter);
358  isValueComputed_ = (flag ? false : isValueComputed_);
359  isGradientComputed_ = (flag ? false : isGradientComputed_);
360  isMultiplierComputed_ = (flag ? false : isMultiplierComputed_);
361  isObjValueComputed_ = (flag ? false : isObjValueComputed_);
362  isObjGradComputed_ = (flag ? false : isObjGradComputed_);
363  isConValueComputed_ = (flag ? false : isConValueComputed_);
364  isQComputed_ = (flag ? false : isQComputed_);
365  isDQComputed_ = (flag ? false : isDQComputed_);
366  multSolverError_ = (flag ? ROL_INF<Real>() : multSolverError_);
367  gradSolveError_ = (flag ? ROL_INF<Real>() : gradSolveError_);
368  }
369 
370  Real value( const Vector<Real> &x, Real &tol ) {
371  if( isValueComputed_ )
372  return fPhi_;
373 
374  // Reset tolerances
375  Real origTol = tol;
376  Real tol2 = origTol;
377 
378  FletcherBase<Real>::objValue(x, tol2); tol2 = origTol;
379  multSolverError_ = origTol / static_cast<Real>(2);
381  tol = multSolverError_;
382 
383  fPhi_ = fval_ - c_->dot(y_->dual());
384  isValueComputed_ = true;
385 
386  return fPhi_;
387  }
388 
389  void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
390  if( isGradientComputed_ && gradSolveError_ <= tol) {
391  tol = gradSolveError_;
392  g.set(*gPhi_);
393  return;
394  }
395 
396  // Reset tolerances
397  Real origTol = tol;
398  Real tol2 = origTol;
399 
400  gradSolveError_ = origTol / static_cast<Real>(2);
402 
403  switch( AugSolve_ ) {
404  case 0: {
407  tol = gradSolveError_;
408 
409  w_->applyBinary(Elementwise::Multiply<Real>(), *Qsqrt_);
410  con_->applyAdjointHessian( *gPhi_, *y_, *w_, x, tol2 ); tol2 = origTol;
411  obj_->hessVec( *Tv_, *w_, x, tol2 ); tol2 = origTol;
412  gPhi_->axpy( static_cast<Real>(-1), *Tv_ );
413 
414  con_->applyAdjointJacobian( *Tv_, *v_, x, tol2); tol2 = origTol;
415  gPhi_->axpy( -penaltyParameter_, *Tv_);
416 
417  Tv_->applyBinary(Elementwise::Multiply<Real>(), *DQgL_);
418  gPhi_->plus( *Tv_ );
419 
420  con_->applyAdjointHessian( *Tv_, *v_, *QgL_, x, tol2 ); tol2 = origTol;
421  gPhi_->plus( *Tv_ );
422 
423  gPhi_->plus( *gL_ );
424  break;
425  }
426  case 1: {
429  tol = gradSolveError_;
430 
431  gPhi_->set( *w_ );
432  gPhi_->scale( penaltyParameter_ );
433  Tv_->set( *w_ );
434  Tv_->applyBinary( Elementwise::Multiply<Real>(), *DQgL_ );
435  gPhi_->axpy(static_cast<Real>(-1), *Tv_);
436 
437  w_->applyBinary( Elementwise::Multiply<Real>(), *Q_ );
438  obj_->hessVec( *Tv_, *w_, x, tol2); tol2 = origTol;
439  gPhi_->axpy( static_cast<Real>(-1), *Tv_ );
440  con_->applyAdjointHessian( *Tv_, *y_, *w_, x, tol2 ); tol2 = origTol;
441  gPhi_->plus( *Tv_ );
442 
443  con_->applyAdjointHessian( *Tv_, *v_, *QgL_, x, tol2 ); tol2 = origTol;
444  gPhi_->plus( *Tv_ );
445 
446  gPhi_->plus( *gL_ );
447 
448  break;
449  }
450  }
451 
452  g.set(*gPhi_);
453  isGradientComputed_ = true;
454  }
455 
456  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
457  // Reset tolerances
458  Real origTol = tol;
459  Real tol2 = origTol;
460 
461  // Make sure everything is already computed
462  value(x, tol2); tol2 = origTol;
463  computeMultipliers(x, tol2); tol2 = origTol;
464  gradient(*Tv_, x, tol2); tol2 = origTol;
465 
466  switch( AugSolve_ ) {
467  case 0: {
468  // hv <- HL*v
469  obj_->hessVec( hv, v, x, tol2 ); tol2 = origTol;
470  con_->applyAdjointHessian( *Tv_, *y_, v, x, tol2 ); tol2 = origTol;
471  hv.axpy(static_cast<Real>(-1), *Tv_ );
472 
473  // htmp1_ <- Q^{1/2}*hv
474  htmp1_->set(hv);
475  htmp1_->applyBinary(Elementwise::Multiply<Real>(), *Qsqrt_);
476  htmp1_->scale(static_cast<Real>(-1));
477  // htmp2_ <- A'*(R(gL) - sigma*I)*v
478  Tv_->set( *DQgL_ );
479  Tv_->applyBinary( Elementwise::Multiply<Real>(), v );
480  Tv_->axpy(-penaltyParameter_, v);
481  con_->applyJacobian( *htmp2_, *Tv_, x, tol2); tol2 = origTol;
482  // v_ <- - (A'QA)^-1 [A' (R(gL)-sigma I) u + A' Q HL u]
483  solveAugmentedSystem( *w_, *v_, *htmp1_, *htmp2_, x, tol2 ); tol2 = origTol;
484  con_->applyAdjointJacobian( *Tv_, *v_, x, tol2 ); tol2 = origTol;
485  hv.plus(*Tv_);
486 
487  con_->applyJacobian( *htmp2_, v, x, tol2 ); tol2 = origTol;
488  solveAugmentedSystem( *w_, *v_, *xzeros_, *htmp2_, x, tol2 ); tol2 = origTol;
489  con_->applyAdjointJacobian( *Tv_, *v_, x, tol2 ); tol2 = origTol;
490  hv.axpy( -penaltyParameter_, *Tv_);
491  Tv_->applyBinary( Elementwise::Multiply<Real>(), *DQgL_ );
492  hv.plus( *Tv_ );
493 
494  w_->applyBinary( Elementwise::Multiply<Real>(), *Qsqrt_ );
495  obj_->hessVec( *Tv_, *w_, x, tol2 ); tol2 = origTol;
496  hv.axpy( static_cast<Real>(-1), *Tv_);
497  con_->applyAdjointHessian( *Tv_, *y_, *w_, x, tol2 ); tol2 = origTol;
498  hv.plus( *Tv_ );
499  break;
500  }
501  case 1: {
502  // hv <- HL*v
503  obj_->hessVec( hv, v, x, tol2 ); tol2 = origTol;
504  con_->applyAdjointHessian( *Tv_, *y_, v, x, tol2 ); tol2 = origTol;
505  hv.axpy(static_cast<Real>(-1), *Tv_ );
506 
507  htmp1_->set(hv);
508  Tv_->set(v);
509  Tv_->applyBinary( Elementwise::Multiply<Real>(), *DQgL_ );
510  Tv_->axpy( -penaltyParameter_, v );
511  Tv_->scale( static_cast<Real>(-1) );
512  con_->applyJacobian( *htmp2_, *Tv_, x, tol2 ); tol2 = origTol;
513  solveAugmentedSystem( *w_, *v_, *htmp1_, *htmp2_, x, tol2 ); tol2 = origTol;
514  hv.set( *w_ );
515 
516  con_->applyJacobian( *htmp2_, v, x, tol2 ); tol2 = origTol;
517  solveAugmentedSystem( *w_, *v_, *xzeros_, *htmp2_, x, tol2 ); tol2 = origTol;
518  hv.axpy( penaltyParameter_, *w_ );
519  Tv_->set( *w_ );
520  Tv_->applyBinary( Elementwise::Multiply<Real>(), *DQgL_ );
521  hv.axpy( static_cast<Real>(-1), *Tv_ );
522 
523  w_->applyBinary( Elementwise::Multiply<Real>(), *Q_ );
524  obj_->hessVec( *Tv_, *w_, x, tol2 ); tol2 = tol;
525  hv.axpy( static_cast<Real>(-1), *Tv_);
526  con_->applyAdjointHessian( *Tv_, *y_, *w_, x, tol2 ); tol2 = origTol;
527  hv.plus( *Tv_ );
528  break;
529  }
530  }
531  }
532 
534  Vector<Real> &v2,
535  const Vector<Real> &b1,
536  const Vector<Real> &b2,
537  const Vector<Real> &x,
538  Real &tol) {
539  // Ignore tol for now
540  ROL::Ptr<LinearOperator<Real> > K;
541  switch( AugSolve_ ) {
542  case 0: {
543  K = ROL::makePtr<AugSystemSym>(con_, makePtrFromRef(x), Qsqrt_, Qv_, delta_);
544  break;
545  }
546  case 1: {
547  K = ROL::makePtr<AugSystemNonSym>(con_, makePtrFromRef(x), Q_, Qv_, delta_);
548  break;
549  }
550  }
551  ROL::Ptr<LinearOperator<Real> > P
552  = ROL::makePtr<AugSystemPrecond>(con_, makePtrFromRef(x));
553 
554  v1_->set(v1);
555  v2_->set(v2);
556 
557  b1_->set(b1);
558  b2_->set(b2);
559 
560  // If inexact, change tolerance
561  if( useInexact_ ) {
562  krylov_->resetAbsoluteTolerance(tol);
563  }
564 
565  flagKrylov_ = 0;
566  tol = krylov_->run(*vv_,*K,*bb_,*P,iterKrylov_,flagKrylov_);
567  v1.set(*v1_);
568  v2.set(*v2_);
569  }
570 
571  void computeMultipliers(const Vector<Real>& x, const Real tol) {
572  if( isMultiplierComputed_ && multSolverError_ <= tol) {
573  return;
574  }
575  Real tol2 = tol;
576  FletcherBase<Real>::objGrad(x, tol2); tol2 = tol;
577  FletcherBase<Real>::conValue(x, tol2); tol2 = tol;
578  computeQ(x);
579  computeDQ(x);
580 
581  switch( AugSolve_ ) {
582  case 0: {
583  Qsg_->set(*g_);
584  Qsg_->applyBinary(Elementwise::Multiply<Real>(), *Qsqrt_);
585 
586  multSolverError_ = tol;
588 
589  gL_->set(*QsgL_);
590  gL_->applyBinary(Elementwise::Divide<Real>(), *Qsqrt_);
591  QgL_->set(*QsgL_);
592  QgL_->applyBinary(Elementwise::Multiply<Real>(), *Qsqrt_);
593  break;
594  }
595  case 1: {
596  multSolverError_ = tol;
598  QgL_->set(*gL_);
599  QgL_->applyBinary(Elementwise::Multiply<Real>(), *Q_);
600  break;
601  }
602  }
603 
604  DQgL_->set(*gL_);
605  DQgL_->applyBinary(Elementwise::Multiply<Real>(), *DQ_);
606 
607  isMultiplierComputed_ = true;
608  }
609 
610  void computeQ(const Vector<Real>& x) {
611  if( isQComputed_ ) {
612  return;
613  }
614 
615  Q_->set(x);
616  Q_->applyBinary(DiffLower(), *low_);
617  umx_->set(x);
618  umx_->applyBinary(DiffUpper(), *upp_);
619  Q_->applyBinary(FormQ(), *umx_);
620  Qsqrt_->set(*Q_);
621  Qsqrt_->applyUnary(Elementwise::SquareRoot<Real>());
622 
623  isQComputed_ = true;
624  }
625 
626  void computeDQ(const Vector<Real> &x) {
627  if( isDQComputed_ ) {
628  return;
629  }
630 
631  DQ_->set(x);
632  DQ_->applyBinary(DiffLower(), *low_);
633  umx_->set(x);
634  umx_->applyBinary(DiffUpper(), *upp_);
635  DQ_->applyBinary(FormDQ(), *umx_);
636 
637  isDQComputed_ = true;
638  }
639 
640 }; // class Fletcher
641 
642 } // namespace ROL
643 
644 #endif
Provides the interface to evaluate objective functions.
Ptr< Vector< Real > > c_
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
Ptr< Vector< Real > > gPhi_
Ptr< Vector< Real > > Qsg_
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
const Ptr< Constraint< Real > > con_
Real apply(const Real &x, const Real &y) const
ROL::Ptr< const Vector< Real > > get(size_type i) const
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:153
Defines the linear algebra of vector space on a generic partitioned vector.
AugSystemSym(const Ptr< Constraint< Real > > &con, const Ptr< const Vector< Real > > &x, const Ptr< Vector< Real > > &Qsqrt, const Ptr< Vector< Real > > &Qv, const Real delta)
void objValue(const Vector< Real > &x, Real &tol)
const Ptr< Objective< Real > > obj_
Contains definitions of custom data types in ROL.
const Ptr< Constraint< Real > > con_
Ptr< Vector< Real > > czeros_
Real apply(const Real &x, const Real &y) const
Real apply(const Real &x, const Real &y) const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
Ptr< Krylov< Real > > krylov_
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
void applyInverse(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply inverse of linear operator.
const Ptr< const Vector< Real > > x_
void solveAugmentedSystem(Vector< Real > &v1, Vector< Real > &v2, const Vector< Real > &b1, const Vector< Real > &b2, const Vector< Real > &x, Real &tol)
BoundFletcher(const ROL::Ptr< Objective< Real > > &obj, const ROL::Ptr< Constraint< Real > > &con, const ROL::Ptr< BoundConstraint< Real > > &bnd, const Vector< Real > &optVec, const Vector< Real > &conVec, ROL::ParameterList &parlist)
Ptr< Vector< Real > > QgL_
Ptr< Vector< Real > > gL_
Ptr< Vector< Real > > DQgL_
Ptr< const Vector< Real > > low_
Ptr< Vector< Real > > Tv_
Ptr< Vector< Real > > v1_
Ptr< Vector< Real > > b1_
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
Ptr< Vector< Real > > Qv_
Real value(const Vector< Real > &x, Real &tol)
Compute value.
void computeMultipliers(const Vector< Real > &x, const Real tol)
const Ptr< const Vector< Real > > x_
Ptr< Vector< Real > > scaledc_
const Ptr< Constraint< Real > > con_
Ptr< Vector< Real > > v_
Ptr< Vector< Real > > g_
void conValue(const Vector< Real > &x, Real &tol)
Ptr< Vector< Real > > Qsqrt_
Ptr< Vector< Real > > Q_
const Ptr< Constraint< Real > > con_
void computeDQ(const Vector< Real > &x)
void set(const V &x)
Set where .
Ptr< Vector< Real > > y_
const Ptr< Vector< Real > > Qsqrt_
Ptr< PartitionedVector< Real > > vv_
AugSystemPrecond(const Ptr< Constraint< Real > > con, const Ptr< const Vector< Real > > x)
Provides the interface to apply a linear operator.
Provides the interface to apply upper and lower bound constraints.
Ptr< const Vector< Real > > upp_
AugSystemNonSym(const Ptr< Constraint< Real > > &con, const Ptr< const Vector< Real > > &x, const Ptr< Vector< Real > > &Q, const Ptr< Vector< Real > > &Qv, const Real delta)
Ptr< Vector< Real > > umx_
Ptr< Vector< Real > > DQ_
Ptr< Vector< Real > > w_
const Ptr< Vector< Real > > Qv_
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:209
Ptr< Vector< Real > > v2_
Ptr< Vector< Real > > QsgL_
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Real apply(const Real &x, const Real &y) const
Ptr< Vector< Real > > b2_
Ptr< PartitionedVector< Real > > bb_
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update objective function.
Ptr< Vector< Real > > htmp1_
const Ptr< const Vector< Real > > x_
void computeQ(const Vector< Real > &x)
Ptr< Vector< Real > > htmp2_
void objGrad(const Vector< Real > &x, Real &tol)
Defines the general constraint operator interface.
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Ptr< Vector< Real > > xzeros_