ROL
ROL_NewtonKrylov_U.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_NEWTONKRYLOV_U_H
11 #define ROL_NEWTONKRYLOV_U_H
12 
14 
15 #include "ROL_Types.hpp"
16 #include "ROL_Secant.hpp"
17 #include "ROL_KrylovFactory.hpp"
18 #include "ROL_LinearOperator.hpp"
19 
26 namespace ROL {
27 
28 template<typename Real>
29 class NewtonKrylov_U : public DescentDirection_U<Real> {
30 private:
31 
32  Ptr<Secant<Real>> secant_;
33  Ptr<Krylov<Real>> krylov_;
34  Ptr<LinearOperator<Real>> precond_;
35 
38 
40 
41  std::string krylovName_;
42  std::string secantName_;
43 
44  class HessianNK : public LinearOperator<Real> {
45  private:
46  const Ptr<Objective<Real>> obj_;
47  const Ptr<const Vector<Real>> x_;
48  public:
49  HessianNK(const Ptr<Objective<Real>> &obj,
50  const Ptr<const Vector<Real>> &x) : obj_(obj), x_(x) {}
51  void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
52  obj_->hessVec(Hv,v,*x_,tol);
53  }
54  };
55 
56  class PrecondNK : public LinearOperator<Real> {
57  private:
58  const Ptr<Objective<Real>> obj_;
59  const Ptr<const Vector<Real>> x_;
60  public:
61  PrecondNK(const Ptr<Objective<Real>> &obj,
62  const Ptr<const Vector<Real>> &x) : obj_(obj), x_(x) {}
63  void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
64  Hv.set(v.dual());
65  }
66  void applyInverse(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
67  obj_->precond(Hv,v,*x_,tol);
68  }
69  };
70 
71 public:
72 
80  NewtonKrylov_U(ParameterList &parlist)
81  : secant_(nullPtr), krylov_(nullPtr), useSecantPrecond_(false) {
82  // Parse ParameterList
83  ParameterList& Glist = parlist.sublist("General");
84  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
85  // Initialize Krylov object
86  krylovName_ = Glist.sublist("Krylov").get("Type","Conjugate Gradients");
88  krylov_ = KrylovFactory<Real>(parlist);
89  // Initialize secant object
90  secantName_ = Glist.sublist("Secant").get("Type","Limited-Memory BFGS");
91  esec_ = StringToESecant(secantName_);
92  if ( useSecantPrecond_ ) {
93  secant_ = SecantFactory<Real>(parlist);
94  precond_ = secant_;
95  }
96  }
97 
108  NewtonKrylov_U(ParameterList &parlist, const Ptr<Krylov<Real>> &krylov,
109  const Ptr<Secant<Real>> &secant, const bool computeObj = true)
110  : secant_(secant), krylov_(krylov),
112  useSecantPrecond_(false) {
113  // Parse ParameterList
114  ParameterList& Glist = parlist.sublist("General");
115  useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
116  // Initialize secant object
117  if ( useSecantPrecond_ ) {
118  if(secant_ == nullPtr ) {
119  secantName_ = Glist.sublist("Secant").get("Type","Limited-Memory BFGS");
121  secant_ = SecantFactory<Real>(parlist);
122  }
123  else {
124  secantName_ = Glist.sublist("Secant").get("User Defined Secant Name",
125  "Unspecified User Defined Secant Method");
126  }
127  precond_ = secant_;
128  }
129  // Initialize Krylov object
130  if ( krylov_ == nullPtr ) {
131  krylovName_ = Glist.sublist("Krylov").get("Type","Conjugate Gradients");
133  krylov_ = KrylovFactory<Real>(parlist);
134  }
135  else {
136  krylovName_ = Glist.sublist("Krylov").get("User Defined Krylov Name",
137  "Unspecified User Defined Krylov Method");
138  }
139  }
140 
141  void compute( Vector<Real> &s, Real &snorm, Real &sdotg, int &iter, int &flag,
142  const Vector<Real> &x, const Vector<Real> &g, Objective<Real> &obj) override {
143  // Build Hessian and Preconditioner object
144  Ptr<Objective<Real>> obj_ptr = makePtrFromRef(obj);
145  Ptr<const Vector<Real>> x_ptr = makePtrFromRef(x);
146  Ptr<LinearOperator<Real>> hessian
147  = makePtr<HessianNK>(obj_ptr,x_ptr);
148  Ptr<LinearOperator<Real>> precond;
149  if ( !useSecantPrecond_ ) {
150  precond = makePtr<PrecondNK>(obj_ptr,x_ptr);
151  }
152 
153  // Run Krylov method
154  flag = 0; iter = 0;
155  krylov_->run(s,*hessian,g,*precond,iter,flag);
156 
157  // Check Krylov flags
158  if ( flag == 2 && iter <= 1 ) {
159  s.set(g.dual());
160  }
161  s.scale(static_cast<Real>(-1));
162  snorm = s.norm();
163  //sdotg = s.dot(g.dual());
164  sdotg = s.apply(g);
165  }
166 
167  void update(const Vector<Real> &x, const Vector<Real> &s,
168  const Vector<Real> &gold, const Vector<Real> &gnew,
169  const Real snorm, const int iter) override {
170  // Update Secant Information
171  if ( useSecantPrecond_ ) {
172  secant_->updateStorage(x,gnew,gold,s,snorm,iter+1);
173  }
174  }
175 
176  std::string printName(void) const override {
177  std::stringstream name;
178  name << "Newton-Krylov Method using " << krylovName_;
179  if (useSecantPrecond_) {
180  name << " with " << secantName_ << " preconditioning";
181  }
182  return name.str();
183  }
184 }; // class NewtonKrylov_U
185 
186 } // namespace ROL
187 
188 #endif
Provides the interface to evaluate 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:192
virtual void scale(const Real alpha)=0
Compute where .
NewtonKrylov_U(ParameterList &parlist, const Ptr< Krylov< Real >> &krylov, const Ptr< Secant< Real >> &secant, const bool computeObj=true)
Constructor.
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Definition: ROL_Vector.hpp:204
const Ptr< Objective< Real > > obj_
Ptr< Secant< Real > > secant_
Secant object (used for quasi-Newton)
Contains definitions of custom data types in ROL.
NewtonKrylov_U(ParameterList &parlist)
Constructor.
const Ptr< const Vector< Real > > x_
bool useSecantPrecond_
Whether or not a secant approximation is used for preconditioning inexact Newton. ...
Provides the interface to compute optimization steps with projected inexact Newton&#39;s method using lin...
ESecant StringToESecant(std::string s)
Definition: ROL_Types.hpp:513
std::string printName(void) const override
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
HessianNK(const Ptr< Objective< Real >> &obj, const Ptr< const Vector< Real >> &x)
EKrylov
Enumeration of Krylov methods.
EKrylov StringToEKrylov(std::string s)
const Ptr< const Vector< Real > > x_
void applyInverse(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply inverse of linear operator.
ESecant
Enumeration of secant update algorithms.
Definition: ROL_Types.hpp:456
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
Provides interface for and implements limited-memory secant operators.
Definition: ROL_Secant.hpp:45
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
Ptr< LinearOperator< Real > > precond_
Provides definitions for Krylov solvers.
Definition: ROL_Krylov.hpp:24
Provides the interface to apply a linear operator.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
virtual Real norm() const =0
Returns where .
Provides the interface to compute unconstrained optimization steps for line search.
const Ptr< Objective< Real > > obj_
Ptr< Krylov< Real > > krylov_
Krylov solver object (used for inexact Newton)
PrecondNK(const Ptr< Objective< Real >> &obj, const Ptr< const Vector< Real >> &x)
void compute(Vector< Real > &s, Real &snorm, Real &sdotg, int &iter, int &flag, const Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj) override
void update(const Vector< Real > &x, const Vector< Real > &s, const Vector< Real > &gold, const Vector< Real > &gnew, const Real snorm, const int iter) override