ROL
ROL_LineSearchStep.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_LINESEARCHSTEP_H
45 #define ROL_LINESEARCHSTEP_H
46 
47 #include "ROL_Types.hpp"
48 #include "ROL_HelperFunctions.hpp"
49 
50 #include "ROL_Step.hpp"
51 #include "ROL_Secant.hpp"
52 #include "ROL_Krylov.hpp"
53 #include "ROL_NonlinearCG.hpp"
54 #include "ROL_LineSearch.hpp"
55 #include "ROL_ProjectedHessian.hpp"
57 
58 #include <sstream>
59 #include <iomanip>
60 
130 namespace ROL {
131 
132 template <class Real>
133 class LineSearchStep : public Step<Real> {
134 private:
135 
136  Teuchos::RCP<Secant<Real> > secant_;
137  Teuchos::RCP<Krylov<Real> > krylov_;
138  Teuchos::RCP<NonlinearCG<Real> > nlcg_;
139  Teuchos::RCP<LineSearch<Real> > lineSearch_;
140 
141  Teuchos::RCP<ProjectedHessian<Real> > hessian_;
142  Teuchos::RCP<ProjectedPreconditioner<Real> > precond_;
143 
144  Teuchos::RCP<Vector<Real> > d_;
145  Teuchos::RCP<Vector<Real> > gp_;
146 
149 
156 
157  int ls_nfval_;
158  int ls_ngrad_;
159 
162 
164 
165  std::vector<bool> useInexact_;
166 
167  bool softUp_;
168 
170 
171 public:
172 
173  virtual ~LineSearchStep() {}
174 
182  LineSearchStep( Teuchos::ParameterList &parlist )
183  : Step<Real>(),
184  secant_(Teuchos::null), krylov_(Teuchos::null),
185  nlcg_(Teuchos::null), lineSearch_(Teuchos::null),
186  hessian_(Teuchos::null), precond_(Teuchos::null),
187  d_(Teuchos::null), gp_(Teuchos::null),
188  iterKrylov_(0), flagKrylov_(0),
191  econd_(CURVATURECONDITION_WOLFE),
192  edesc_(DESCENT_STEEPEST),
193  esec_(SECANT_LBFGS),
194  ekv_(KRYLOV_CG),
195  ls_nfval_(0), ls_ngrad_(0),
196  useSecantHessVec_(false), useSecantPrecond_(false),
197  useProjectedGrad_(false), softUp_(false) {
198  Teuchos::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
199  Teuchos::ParameterList& Glist = parlist.sublist("General");
200  // Initialize Linesearch Object
201  edesc_ = StringToEDescent(Llist.sublist("Descent Method").get("Type","Quasi-Newton Method") );
202  els_ = StringToELineSearch(Llist.sublist("Line-Search Method").get("Type","Cubic Interpolation") );
203  econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") );
204  useProjectedGrad_ = Glist.get("Projected Gradient Criticality Measure", false);
205  acceptLastAlpha_ = Llist.get("Accept Last Alpha", false);
206  lineSearch_ = LineSearchFactory<Real>(parlist);
207  // Inexactness Information
208  useInexact_.clear();
209  useInexact_.push_back(Glist.get("Inexact Objective Function", false));
210  useInexact_.push_back(Glist.get("Inexact Gradient", false));
211  useInexact_.push_back(Glist.get("Inexact Hessian-Times-A-Vector", false));
212  // Changing Objective Functions
213  softUp_ = Glist.get("Variable Objective Function",false);
214  // Initialize Krylov Object
215  ekv_ = StringToEKrylov(Glist.sublist("Krylov").get("Type","Conjugate Gradients"));
216  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
217  krylov_ = KrylovFactory<Real>(parlist);
218  }
219  // Initialize Secant Object
220  esec_ = StringToESecant(Glist.sublist("Secant").get("Type","Limited-Memory BFGS"));
221  useSecantHessVec_ = Glist.sublist("Secant").get("Use as Hessian", false);
222  useSecantHessVec_ = ((edesc_==DESCENT_SECANT) ? true : useSecantHessVec_);
223  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
224  if ( edesc_ == DESCENT_SECANT || (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
225  secant_ = SecantFactory<Real>(parlist);
226  }
227  // Initialize Nonlinear CG Object
228  enlcg_ = StringToENonlinearCG(Llist.sublist("Descent Method").get("Nonlinear CG Type","Oren-Luenberger"));
229  if ( edesc_ == DESCENT_NONLINEARCG ) {
230  nlcg_ = Teuchos::rcp( new NonlinearCG<Real>(enlcg_) );
231  }
232  }
233 
242  LineSearchStep(Teuchos::RCP<LineSearch<Real> > &lineSearch, Teuchos::ParameterList &parlist)
243  : Step<Real>(),
244  secant_(Teuchos::null), krylov_(Teuchos::null),
245  nlcg_(Teuchos::null), lineSearch_(lineSearch),
246  hessian_(Teuchos::null), precond_(Teuchos::null),
247  d_(Teuchos::null), gp_(Teuchos::null),
248  iterKrylov_(0), flagKrylov_(0),
251  econd_(CURVATURECONDITION_WOLFE),
252  edesc_(DESCENT_STEEPEST),
253  esec_(SECANT_LBFGS),
254  ekv_(KRYLOV_CG),
255  ls_nfval_(0), ls_ngrad_(0),
256  useSecantHessVec_(false), useSecantPrecond_(false),
257  useProjectedGrad_(false), softUp_(false) {
258  Teuchos::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
259  Teuchos::ParameterList& Glist = parlist.sublist("General");
260  // Initialize Linesearch Object
261  edesc_ = StringToEDescent(Llist.sublist("Descent Method").get("Type","Quasi-Newton Method") );
262  econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") );
263  els_ = LINESEARCH_USERDEFINED;
264  useProjectedGrad_ = Glist.get("Projected Gradient Criticality Measure", false);
265  acceptLastAlpha_ = Llist.get("Accept Last Alpha", false);
266  // Inexactness Information
267  useInexact_.clear();
268  useInexact_.push_back(Glist.get("Inexact Objective Function", false));
269  useInexact_.push_back(Glist.get("Inexact Gradient", false));
270  useInexact_.push_back(Glist.get("Inexact Hessian-Times-A-Vector", false));
271  // Changing Objective Functions
272  softUp_ = Glist.get("Variable Objective Function",false);
273  // Initialize Krylov Object
274  ekv_ = StringToEKrylov(Glist.sublist("Krylov").get("Type","Conjugate Gradients"));
275  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
276  krylov_ = KrylovFactory<Real>(parlist);
277  }
278  // Initialize Secant Object
279  esec_ = StringToESecant(Glist.sublist("Secant").get("Type","Limited-Memory BFGS"));
280  useSecantHessVec_ = Glist.sublist("Secant").get("Use as Hessian", false);
281  useSecantHessVec_ = ((edesc_==DESCENT_SECANT) ? true : useSecantHessVec_);
282  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
283  if ( edesc_ == DESCENT_SECANT || (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
284  secant_ = SecantFactory<Real>(parlist);
285  }
286  // Initialize Nonlinear CG Object
287  enlcg_ = StringToENonlinearCG(Llist.sublist("Descent Method").get("Nonlinear CG Type","Oren-Luenberger"));
288  if ( edesc_ == DESCENT_NONLINEARCG ) {
289  nlcg_ = Teuchos::rcp( new NonlinearCG<Real>(enlcg_) );
290  }
291  }
292 
302  LineSearchStep( Teuchos::RCP<Secant<Real> > &secant, Teuchos::ParameterList &parlist )
303  : Step<Real>(),
304  secant_(secant), krylov_(Teuchos::null),
305  nlcg_(Teuchos::null), lineSearch_(Teuchos::null),
306  hessian_(Teuchos::null), precond_(Teuchos::null),
307  d_(Teuchos::null), gp_(Teuchos::null),
308  iterKrylov_(0), flagKrylov_(0),
311  econd_(CURVATURECONDITION_WOLFE),
312  edesc_(DESCENT_STEEPEST),
313  esec_(SECANT_USERDEFINED),
314  ekv_(KRYLOV_CG),
315  ls_nfval_(0), ls_ngrad_(0),
316  useSecantHessVec_(false), useSecantPrecond_(false),
317  useProjectedGrad_(false), softUp_(false) {
318  Teuchos::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
319  Teuchos::ParameterList& Glist = parlist.sublist("General");
320  // Initialize Linesearch Object
321  edesc_ = StringToEDescent(Llist.sublist("Descent Method").get("Type","Quasi-Newton Method"));
322  els_ = StringToELineSearch(Llist.sublist("Line-Search Method").get("Type","Cubic Interpolation") );
323  econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") );
324  useProjectedGrad_ = Glist.get("Projected Gradient Criticality Measure", false);
325  acceptLastAlpha_ = Llist.get("Accept Last Alpha", false);
326  lineSearch_ = LineSearchFactory<Real>(parlist);
327  // Inexactness Information
328  useInexact_.clear();
329  useInexact_.push_back(Glist.get("Inexact Objective Function", false));
330  useInexact_.push_back(Glist.get("Inexact Gradient", false));
331  useInexact_.push_back(Glist.get("Inexact Hessian-Times-A-Vector", false));
332  // Changing Objective Functions
333  softUp_ = Glist.get("Variable Objective Function",false);
334  // Initialize Krylov Object
335  ekv_ = StringToEKrylov(Glist.sublist("Krylov").get("Type","Conjugate Gradients"));
336  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
337  krylov_ = KrylovFactory<Real>(parlist);
338  }
339  // Initialize Secant Object
340  useSecantHessVec_ = Glist.sublist("Secant").get("Use as Hessian", false);
341  useSecantHessVec_ = ((edesc_==DESCENT_SECANT) ? true : useSecantHessVec_);
342  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
343  // Initialize Nonlinear CG Object
344  enlcg_ = StringToENonlinearCG(Llist.sublist("Descent Method").get("Nonlinear CG Type","Oren-Luenberger"));
345  if ( edesc_ == DESCENT_NONLINEARCG ) {
346  nlcg_ = Teuchos::rcp( new NonlinearCG<Real>(enlcg_) );
347  }
348  }
349 
358  LineSearchStep( Teuchos::RCP<Krylov<Real> > &krylov, Teuchos::ParameterList &parlist )
359  : Step<Real>(),
360  secant_(Teuchos::null), krylov_(krylov),
361  nlcg_(Teuchos::null), lineSearch_(Teuchos::null),
362  hessian_(Teuchos::null), precond_(Teuchos::null),
363  d_(Teuchos::null), gp_(Teuchos::null),
364  iterKrylov_(0), flagKrylov_(0),
367  econd_(CURVATURECONDITION_WOLFE),
368  edesc_(DESCENT_STEEPEST),
369  esec_(SECANT_LBFGS),
370  ekv_(KRYLOV_USERDEFINED),
371  ls_nfval_(0), ls_ngrad_(0),
372  useSecantHessVec_(false), useSecantPrecond_(false),
373  useProjectedGrad_(false), softUp_(false) {
374  Teuchos::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
375  Teuchos::ParameterList& Glist = parlist.sublist("General");
376  // Initialize Linesearch Object
377  edesc_ = StringToEDescent(Llist.sublist("Descent Method").get("Type","Quasi-Newton Method") );
378  els_ = StringToELineSearch(Llist.sublist("Line-Search Method").get("Type","Cubic Interpolation") );
379  econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") );
380  useProjectedGrad_ = Glist.get("Projected Gradient Criticality Measure", false);
381  acceptLastAlpha_ = Llist.get("Accept Last Alpha", false);
382  lineSearch_ = LineSearchFactory<Real>(parlist);
383  // Inexactness Information
384  useInexact_.clear();
385  useInexact_.push_back(Glist.get("Inexact Objective Function", false));
386  useInexact_.push_back(Glist.get("Inexact Gradient", false));
387  useInexact_.push_back(Glist.get("Inexact Hessian-Times-A-Vector", false));
388  // Changing Objective Functions
389  softUp_ = Glist.get("Variable Objective Function",false);
390  // Initialize Secant Object
391  esec_ = StringToESecant(Glist.sublist("Secant").get("Type","Limited-Memory BFGS"));
392  useSecantHessVec_ = Glist.sublist("Secant").get("Use as Hessian", false);
393  useSecantHessVec_ = ((edesc_==DESCENT_SECANT) ? true : useSecantHessVec_);
394  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
395  if ( edesc_ == DESCENT_SECANT || (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
396  secant_ = SecantFactory<Real>(parlist);
397  }
398  // Initialize Nonlinear CG Object
399  enlcg_ = StringToENonlinearCG(Llist.sublist("Descent Method").get("Nonlinear CG Type","Oren-Luenberger"));
400  if ( edesc_ == DESCENT_NONLINEARCG ) {
401  nlcg_ = Teuchos::rcp( new NonlinearCG<Real>(enlcg_) );
402  }
403  }
404 
415  LineSearchStep( Teuchos::RCP<LineSearch<Real> > &lineSearch, Teuchos::RCP<Secant<Real> > &secant,
416  Teuchos::ParameterList &parlist )
417  : Step<Real>(),
418  secant_(secant), krylov_(Teuchos::null),
419  nlcg_(Teuchos::null), lineSearch_(lineSearch),
420  hessian_(Teuchos::null), precond_(Teuchos::null),
421  d_(Teuchos::null), gp_(Teuchos::null),
422  iterKrylov_(0), flagKrylov_(0),
425  econd_(CURVATURECONDITION_WOLFE),
426  edesc_(DESCENT_STEEPEST),
427  esec_(SECANT_USERDEFINED),
428  ekv_(KRYLOV_CG),
429  ls_nfval_(0), ls_ngrad_(0),
430  useSecantHessVec_(false), useSecantPrecond_(false),
431  useProjectedGrad_(false), softUp_(false) {
432  Teuchos::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
433  Teuchos::ParameterList& Glist = parlist.sublist("General");
434  // Initialize Linesearch Object
435  edesc_ = StringToEDescent(Llist.sublist("Descent Method").get("Type","Quasi-Newton Method") );
436  econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") );
437  useProjectedGrad_ = Glist.get("Projected Gradient Criticality Measure", false);
438  acceptLastAlpha_ = Llist.get("Accept Last Alpha", false);
439  // Inexactness Information
440  useInexact_.clear();
441  useInexact_.push_back(Glist.get("Inexact Objective Function", false));
442  useInexact_.push_back(Glist.get("Inexact Gradient", false));
443  useInexact_.push_back(Glist.get("Inexact Hessian-Times-A-Vector", false));
444  // Changing Objective Functions
445  softUp_ = Glist.get("Variable Objective Function",false);
446  // Initialize Krylov Object
447  ekv_ = StringToEKrylov(Glist.sublist("Krylov").get("Type","Conjugate Gradients"));
448  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
449  krylov_ = KrylovFactory<Real>(parlist);
450  }
451  // Initialize Secant Object
452  useSecantHessVec_ = Glist.sublist("Secant").get("Use as Hessian", false);
453  useSecantHessVec_ = ((edesc_==DESCENT_SECANT) ? true : useSecantHessVec_);
454  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
455  // Initialize Nonlinear CG Object
456  enlcg_ = StringToENonlinearCG(Llist.sublist("Descent Method").get("Nonlinear CG Type","Oren-Luenberger"));
457  if ( edesc_ == DESCENT_NONLINEARCG ) {
458  nlcg_ = Teuchos::rcp( new NonlinearCG<Real>(enlcg_) );
459  }
460  }
461 
462  void initialize( Vector<Real> &x, const Vector<Real> &s, const Vector<Real> &g,
464  AlgorithmState<Real> &algo_state ) {
465  Step<Real>::initialize(x,s,g,obj,con,algo_state);
466  Teuchos::RCP<StepState<Real> > step_state = Step<Real>::getState();
467  lineSearch_->initialize(x, s, *(step_state->gradientVec),obj,con);
468  if ( edesc_ == DESCENT_NEWTONKRYLOV || edesc_ == DESCENT_NEWTON || edesc_ == DESCENT_SECANT ) {
469  Teuchos::RCP<Objective<Real> > obj_ptr = Teuchos::rcp(&obj, false);
470  Teuchos::RCP<BoundConstraint<Real> > con_ptr = Teuchos::rcp(&con, false);
471  hessian_ = Teuchos::rcp(
472  new ProjectedHessian<Real>(secant_,obj_ptr,con_ptr,algo_state.iterateVec,step_state->gradientVec,
473  useSecantHessVec_));
474  precond_ = Teuchos::rcp(
475  new ProjectedPreconditioner<Real>(secant_,obj_ptr,con_ptr,algo_state.iterateVec,
476  step_state->gradientVec,useSecantPrecond_));
477  }
478  if ( con.isActivated() ) {
479  d_ = s.clone();
480  }
481  if ( con.isActivated() || edesc_ == DESCENT_SECANT
482  || (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
483  gp_ = g.clone();
484  }
485  }
486 
487 
502  AlgorithmState<Real> &algo_state ) {
503  Teuchos::RCP<StepState<Real> > step_state = Step<Real>::getState();
504 
505  Real tol = std::sqrt(ROL_EPSILON);
506 
507  // Set active set parameter
508  Real eps = 0.0;
509  if ( con.isActivated() ) {
510  eps = algo_state.gnorm;
511  }
512  lineSearch_->setData(eps);
513  if ( hessian_ != Teuchos::null ) {
514  hessian_->setData(eps);
515  }
516  if ( precond_ != Teuchos::null ) {
517  precond_->setData(eps);
518  }
519 
520  // Compute step s
521  switch(edesc_) {
523  flagKrylov_ = 0;
524  krylov_->run(s,*hessian_,*(step_state->gradientVec),*precond_,iterKrylov_,flagKrylov_);
525  break;
526  case DESCENT_NEWTON:
527  case DESCENT_SECANT:
528  hessian_->applyInverse(s,*(step_state->gradientVec),tol);
529  break;
530  case DESCENT_NONLINEARCG:
531  nlcg_->run(s,*(step_state->gradientVec),x,obj);
532  break;
533  case DESCENT_STEEPEST:
534  s.set(step_state->gradientVec->dual());
535  break;
536  default: break;
537  }
538 
539  // Compute g.dot(s)
540  Real gs = 0.0;
541  if ( !con.isActivated() ) {
542  gs = -s.dot((step_state->gradientVec)->dual());
543  }
544  else {
545  if ( edesc_ == DESCENT_STEEPEST ) {
546  d_->set(x);
547  d_->axpy(-1.0,s);
548  con.project(*d_);
549  d_->scale(-1.0);
550  d_->plus(x);
551  //d->set(s);
552  //con.pruneActive(*d,s,x,eps);
553  //con.pruneActive(*d,*(step_state->gradientVec),x,eps);
554  gs = -d_->dot((step_state->gradientVec)->dual());
555  }
556  else {
557  d_->set(s);
558  con.pruneActive(*d_,*(step_state->gradientVec),x,eps);
559  gs = -d_->dot((step_state->gradientVec)->dual());
560  d_->set(x);
561  d_->axpy(-1.0,(step_state->gradientVec)->dual());
562  con.project(*d_);
563  d_->scale(-1.0);
564  d_->plus(x);
565  con.pruneInactive(*d_,*(step_state->gradientVec),x,eps);
566  gs -= d_->dot((step_state->gradientVec)->dual());
567  }
568  }
569 
570  // Check if s is a descent direction i.e., g.dot(s) < 0
571  if ( gs >= 0.0 || (flagKrylov_ == 2 && iterKrylov_ <= 1) ) {
572  s.set((step_state->gradientVec)->dual());
573  if ( con.isActivated() ) {
574  d_->set(s);
575  con.pruneActive(*d_,s,x);
576  gs = -d_->dot((step_state->gradientVec)->dual());
577  }
578  else {
579  gs = -s.dot((step_state->gradientVec)->dual());
580  }
581  }
582  s.scale(-1.0);
583 
584  // Perform line search
585  Real fnew = algo_state.value;
586  ls_nfval_ = 0;
587  ls_ngrad_ = 0;
588  lineSearch_->run(step_state->searchSize,fnew,ls_nfval_,ls_ngrad_,gs,s,x,obj,con);
589 
590  // Make correction if maximum function evaluations reached
591  if(!acceptLastAlpha_)
592  {
593  lineSearch_->setMaxitUpdate(step_state->searchSize,fnew,algo_state.value);
594  }
595 
596  algo_state.nfval += ls_nfval_;
597  algo_state.ngrad += ls_ngrad_;
598 
599  // Compute get scaled descent direction
600  s.scale(step_state->searchSize);
601  if ( con.isActivated() ) {
602  s.plus(x);
603  con.project(s);
604  s.axpy(-1.0,x);
605  }
606 
607  // Update step state information
608  (step_state->descentVec)->set(s);
609 
610  // Update algorithm state information
611  algo_state.snorm = s.norm();
612  algo_state.value = fnew;
613  }
614 
627  AlgorithmState<Real> &algo_state ) {
628  Real tol = std::sqrt(ROL_EPSILON);
629  Teuchos::RCP<StepState<Real> > step_state = Step<Real>::getState();
630 
631 
632 
633  // Update iterate
634  algo_state.iter++;
635  x.axpy(1.0, s);
636  if ( softUp_ ) {
637  obj.update(x,true,algo_state.iter);
638  algo_state.value = obj.value(x,tol);
639  algo_state.nfval++;
640  }
641 
642  // Compute new gradient
643  if ( edesc_ == DESCENT_SECANT ||
644  (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
645  gp_->set(*(step_state->gradientVec));
646  }
647  obj.gradient(*(step_state->gradientVec),x,tol);
648  algo_state.ngrad++;
649 
650  // Update Secant Information
651  if ( edesc_ == DESCENT_SECANT ||
652  (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
653  secant_->update(*(step_state->gradientVec),*gp_,s,algo_state.snorm,algo_state.iter+1);
654  }
655 
656  // Update algorithm state
657  (algo_state.iterateVec)->set(x);
658  if ( con.isActivated() ) {
659  if ( useProjectedGrad_ ) {
660  gp_->set(*(step_state->gradientVec));
661  con.computeProjectedGradient( *gp_, x );
662  algo_state.gnorm = gp_->norm();
663  }
664  else {
665  d_->set(x);
666  d_->axpy(-1.0,(step_state->gradientVec)->dual());
667  con.project(*d_);
668  d_->axpy(-1.0,x);
669  algo_state.gnorm = d_->norm();
670  }
671  }
672  else {
673  algo_state.gnorm = (step_state->gradientVec)->norm();
674  }
675  }
676 
681  std::string printHeader( void ) const {
682  std::stringstream hist;
683  hist << " ";
684  hist << std::setw(6) << std::left << "iter";
685  hist << std::setw(15) << std::left << "value";
686  hist << std::setw(15) << std::left << "gnorm";
687  hist << std::setw(15) << std::left << "snorm";
688  hist << std::setw(10) << std::left << "#fval";
689  hist << std::setw(10) << std::left << "#grad";
690  hist << std::setw(10) << std::left << "ls_#fval";
691  hist << std::setw(10) << std::left << "ls_#grad";
692  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
693  hist << std::setw(10) << std::left << "iterCG";
694  hist << std::setw(10) << std::left << "flagCG";
695  }
696  hist << "\n";
697  return hist.str();
698  }
699 
704  std::string printName( void ) const {
705  std::stringstream hist;
706  hist << "\n" << EDescentToString(edesc_)
707  << " with " << ELineSearchToString(els_)
708  << " Linesearch satisfying "
709  << ECurvatureConditionToString(econd_) << "\n";
710  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
711  hist << "Krylov Type: " << EKrylovToString(ekv_) << "\n";
712  }
713  if ( edesc_ == DESCENT_SECANT ||
714  (edesc_ == DESCENT_NEWTONKRYLOV && (useSecantPrecond_ || useSecantHessVec_)) ) {
715  hist << "Secant Type: " << ESecantToString(esec_) << "\n";
716  }
717  if ( edesc_ == DESCENT_NONLINEARCG ) {
718  hist << "Nonlinear CG Type: " << ENonlinearCGToString(enlcg_) << "\n";
719  }
720  return hist.str();
721  }
722 
730  std::string print( AlgorithmState<Real> & algo_state, bool print_header = false ) const {
731  std::stringstream hist;
732  hist << std::scientific << std::setprecision(6);
733  if ( algo_state.iter == 0 ) {
734  hist << printName();
735  }
736  if ( print_header ) {
737  hist << printHeader();
738  }
739  if ( algo_state.iter == 0 ) {
740  hist << " ";
741  hist << std::setw(6) << std::left << algo_state.iter;
742  hist << std::setw(15) << std::left << algo_state.value;
743  hist << std::setw(15) << std::left << algo_state.gnorm;
744  hist << "\n";
745  }
746  else {
747  hist << " ";
748  hist << std::setw(6) << std::left << algo_state.iter;
749  hist << std::setw(15) << std::left << algo_state.value;
750  hist << std::setw(15) << std::left << algo_state.gnorm;
751  hist << std::setw(15) << std::left << algo_state.snorm;
752  hist << std::setw(10) << std::left << algo_state.nfval;
753  hist << std::setw(10) << std::left << algo_state.ngrad;
754  hist << std::setw(10) << std::left << ls_nfval_;
755  hist << std::setw(10) << std::left << ls_ngrad_;
756  if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
757  hist << std::setw(10) << std::left << iterKrylov_;
758  hist << std::setw(10) << std::left << flagKrylov_;
759  }
760  hist << "\n";
761  }
762  return hist.str();
763  }
764 
765  // struct StepState (scalars, vectors) map?
766 
767  // getState
768 
769  // setState
770 
771 }; // class Step
772 
773 } // namespace ROL
774 
775 #endif
Provides the interface to evaluate objective functions.
int ls_nfval_
Number of function evaluations during line search.
virtual void scale(const Real alpha)=0
Compute where .
LineSearchStep(Teuchos::RCP< Krylov< Real > > &krylov, Teuchos::ParameterList &parlist)
Constructor.
virtual void plus(const Vector &x)=0
Compute , where .
bool acceptLastAlpha_
For backwards compatibility. When max function evaluations are reached take last step.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:143
ELineSearch StringToELineSearch(std::string s)
Definition: ROL_Types.hpp:691
std::string printName(void) const
Print step name.
EKrylov ekv_
enum determines type of Krylov solver
virtual Real value(const Vector< Real > &x, Real &tol)=0
Compute value.
Provides the interface to compute optimization steps.
Definition: ROL_Step.hpp:67
Teuchos::RCP< ProjectedPreconditioner< Real > > precond_
Teuchos::RCP< StepState< Real > > getState(void)
Definition: ROL_Step.hpp:72
Contains definitions of custom data types in ROL.
bool useSecantHessVec_
Whether or not a secant approximation is used for Hessian-times-a-vector.
virtual Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
ELineSearch
Enumeration of line-search types.
Definition: ROL_Types.hpp:625
LineSearchStep(Teuchos::RCP< Secant< Real > > &secant, Teuchos::ParameterList &parlist)
Constructor.
ESecant StringToESecant(std::string s)
Definition: ROL_Types.hpp:444
std::string EDescentToString(EDescent tr)
Definition: ROL_Types.hpp:321
Contains definitions for helper functions in ROL.
std::string printHeader(void) const
Print iterate header.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:74
std::vector< bool > useInexact_
Flags for inexact objective function, gradient, and Hessian evaluation.
virtual Real dot(const Vector &x) const =0
Compute where .
int iterKrylov_
Number of Krylov iterations (used for inexact Newton)
EKrylov
Enumeration of Krylov methods.
Definition: ROL_Types.hpp:460
EKrylov StringToEKrylov(std::string s)
Definition: ROL_Types.hpp:513
EDescent StringToEDescent(std::string s)
Definition: ROL_Types.hpp:369
State for algorithm class. Will be used for restarts.
Definition: ROL_Types.hpp:77
Provides the interface to compute optimization steps with line search.
Teuchos::RCP< Vector< Real > > gp_
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Teuchos::RCP< Krylov< Real > > krylov_
Krylov solver object (used for inexact Newton)
bool isActivated(void)
Check if bounds are on.
ENonlinearCG
Enumeration of nonlinear CG algorithms.
Definition: ROL_Types.hpp:536
std::string ECurvatureConditionToString(ECurvatureCondition ls)
Definition: ROL_Types.hpp:718
Provides interface for and implements line searches.
ESecant
Enumeration of secant update algorithms.
Definition: ROL_Types.hpp:387
ENonlinearCG enlcg_
enum determines type of nonlinear CG
bool useSecantPrecond_
Whether or not a secant approximation is used for preconditioning inexact Newton. ...
int ls_ngrad_
Number of gradient evaluations during line search.
Provides interface for and implements limited-memory secant operators.
Definition: ROL_Secant.hpp:68
std::string ENonlinearCGToString(ENonlinearCG tr)
Definition: ROL_Types.hpp:549
ENonlinearCG StringToENonlinearCG(std::string s)
Definition: ROL_Types.hpp:605
EDescent edesc_
enum determines type of descent step
std::string ELineSearchToString(ELineSearch ls)
Definition: ROL_Types.hpp:637
void pruneInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the -inactive set.
Teuchos::RCP< LineSearch< Real > > lineSearch_
Line-search object.
void initialize(Vector< Real > &x, const Vector< Real > &s, const Vector< Real > &g, Objective< Real > &obj, BoundConstraint< Real > &con, AlgorithmState< Real > &algo_state)
Initialize step with bound constraint.
int flagKrylov_
Termination flag for Krylov method (used for inexact Newton)
ELineSearch els_
enum determines type of line search
Teuchos::RCP< ProjectedHessian< Real > > hessian_
std::string print(AlgorithmState< Real > &algo_state, bool print_header=false) const
Print iterate status.
Provides definitions for Krylov solvers.
Definition: ROL_Krylov.hpp:57
Provides the interface to apply upper and lower bound constraints.
bool useProjectedGrad_
Whether or not to use to the projected gradient criticality measure.
void computeProjectedGradient(Vector< Real > &g, const Vector< Real > &x)
Compute projected gradient.
std::string EKrylovToString(EKrylov tr)
Definition: ROL_Types.hpp:468
ECurvatureCondition
Enumeration of line-search curvature conditions.
Definition: ROL_Types.hpp:708
Teuchos::RCP< NonlinearCG< Real > > nlcg_
Nonlinear CG object (used for nonlinear CG)
Teuchos::RCP< Vector< Real > > d_
virtual void initialize(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, BoundConstraint< Real > &con, AlgorithmState< Real > &algo_state)
Initialize step with bound constraint.
Definition: ROL_Step.hpp:87
void compute(Vector< Real > &s, const Vector< Real > &x, Objective< Real > &obj, BoundConstraint< Real > &con, AlgorithmState< Real > &algo_state)
Compute step.
Teuchos::RCP< Vector< Real > > iterateVec
Definition: ROL_Types.hpp:91
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:196
virtual void pruneActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the -active set.
ECurvatureCondition StringToECurvatureCondition(std::string s)
Definition: ROL_Types.hpp:768
virtual Real norm() const =0
Returns where .
virtual void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update objective function.
std::string ESecantToString(ESecant tr)
Definition: ROL_Types.hpp:396
EDescent
Enumeration of descent direction types.
Definition: ROL_Types.hpp:312
LineSearchStep(Teuchos::RCP< LineSearch< Real > > &lineSearch, Teuchos::RCP< Secant< Real > > &secant, Teuchos::ParameterList &parlist)
Constructor.
ECurvatureCondition econd_
enum determines type of curvature condition
Teuchos::RCP< Secant< Real > > secant_
Secant object (used for quasi-Newton)
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.
LineSearchStep(Teuchos::RCP< LineSearch< Real > > &lineSearch, Teuchos::ParameterList &parlist)
Constructor.
ESecant esec_
enum determines type of secant approximation
static const double ROL_EPSILON
Platform-dependent machine epsilon.
Definition: ROL_Types.hpp:118
void update(Vector< Real > &x, const Vector< Real > &s, Objective< Real > &obj, BoundConstraint< Real > &con, AlgorithmState< Real > &algo_state)
Update step, if successful.
LineSearchStep(Teuchos::ParameterList &parlist)
Constructor.