ROL
ROL_NewtonKrylov_U.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_NEWTONKRYLOV_U_H
45#define ROL_NEWTONKRYLOV_U_H
46
48
49#include "ROL_Types.hpp"
50#include "ROL_Secant.hpp"
51#include "ROL_KrylovFactory.hpp"
53
60namespace ROL {
61
62template<typename Real>
63class NewtonKrylov_U : public DescentDirection_U<Real> {
64private:
65
66 Ptr<Secant<Real>> secant_;
67 Ptr<Krylov<Real>> krylov_;
68 Ptr<LinearOperator<Real>> precond_;
69
72
74
75 std::string krylovName_;
76 std::string secantName_;
77
78 class HessianNK : public LinearOperator<Real> {
79 private:
80 const Ptr<Objective<Real>> obj_;
81 const Ptr<const Vector<Real>> x_;
82 public:
83 HessianNK(const Ptr<Objective<Real>> &obj,
84 const Ptr<const Vector<Real>> &x) : obj_(obj), x_(x) {}
85 void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
86 obj_->hessVec(Hv,v,*x_,tol);
87 }
88 };
89
90 class PrecondNK : public LinearOperator<Real> {
91 private:
92 const Ptr<Objective<Real>> obj_;
93 const Ptr<const Vector<Real>> x_;
94 public:
95 PrecondNK(const Ptr<Objective<Real>> &obj,
96 const Ptr<const Vector<Real>> &x) : obj_(obj), x_(x) {}
97 void apply(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
98 Hv.set(v.dual());
99 }
100 void applyInverse(Vector<Real> &Hv, const Vector<Real> &v, Real &tol) const {
101 obj_->precond(Hv,v,*x_,tol);
102 }
103 };
104
105public:
106
114 NewtonKrylov_U(ParameterList &parlist)
115 : secant_(nullPtr), krylov_(nullPtr), useSecantPrecond_(false) {
116 // Parse ParameterList
117 ParameterList& Glist = parlist.sublist("General");
118 useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
119 // Initialize Krylov object
120 krylovName_ = Glist.sublist("Krylov").get("Type","Conjugate Gradients");
122 krylov_ = KrylovFactory<Real>(parlist);
123 // Initialize secant object
124 secantName_ = Glist.sublist("Secant").get("Type","Limited-Memory BFGS");
126 if ( useSecantPrecond_ ) {
127 secant_ = SecantFactory<Real>(parlist);
129 }
130 }
131
142 NewtonKrylov_U(ParameterList &parlist, const Ptr<Krylov<Real>> &krylov,
143 Ptr<Secant<Real>> &secant, const bool computeObj = true)
144 : secant_(secant), krylov_(krylov),
146 useSecantPrecond_(false) {
147 // Parse ParameterList
148 ParameterList& Glist = parlist.sublist("General");
149 useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
150 // Initialize secant object
151 if ( useSecantPrecond_ ) {
152 if(secant_ == nullPtr ) {
153 secantName_ = Glist.sublist("Secant").get("Type","Limited-Memory BFGS");
155 secant_ = SecantFactory<Real>(parlist);
156 }
157 else {
158 secantName_ = Glist.sublist("Secant").get("User Defined Secant Name",
159 "Unspecified User Defined Secant Method");
160 }
162 }
163 // Initialize Krylov object
164 if ( krylov_ == nullPtr ) {
165 krylovName_ = Glist.sublist("Krylov").get("Type","Conjugate Gradients");
167 krylov_ = KrylovFactory<Real>(parlist);
168 }
169 else {
170 krylovName_ = Glist.sublist("Krylov").get("User Defined Krylov Name",
171 "Unspecified User Defined Krylov Method");
172 }
173 }
174
175 void compute( Vector<Real> &s, Real &snorm, Real &sdotg, int &iter, int &flag,
176 const Vector<Real> &x, const Vector<Real> &g, Objective<Real> &obj) override {
177 // Build Hessian and Preconditioner object
178 Ptr<Objective<Real>> obj_ptr = makePtrFromRef(obj);
179 Ptr<const Vector<Real>> x_ptr = makePtrFromRef(x);
180 Ptr<LinearOperator<Real>> hessian
181 = makePtr<HessianNK>(obj_ptr,x_ptr);
182 Ptr<LinearOperator<Real>> precond;
183 if ( !useSecantPrecond_ ) {
184 precond = makePtr<PrecondNK>(obj_ptr,x_ptr);
185 }
186
187 // Run Krylov method
188 flag = 0; iter = 0;
189 krylov_->run(s,*hessian,g,*precond,iter,flag);
190
191 // Check Krylov flags
192 if ( flag == 2 && iter <= 1 ) {
193 s.set(g.dual());
194 }
195 s.scale(static_cast<Real>(-1));
196 snorm = s.norm();
197 //sdotg = s.dot(g.dual());
198 sdotg = s.apply(g);
199 }
200
201 void update(const Vector<Real> &x, const Vector<Real> &s,
202 const Vector<Real> &gold, const Vector<Real> &gnew,
203 const Real snorm, const int iter) override {
204 // Update Secant Information
205 if ( useSecantPrecond_ ) {
206 secant_->updateStorage(x,gnew,gold,s,snorm,iter+1);
207 }
208 }
209
210 std::string printName(void) const override {
211 std::stringstream name;
212 name << "Newton-Krylov Method using " << krylovName_;
213 if (useSecantPrecond_) {
214 name << " with " << secantName_ << " preconditioning";
215 }
216 return name.str();
217 }
218}; // class NewtonKrylov_U
219
220} // namespace ROL
221
222#endif
int iter
Contains definitions of custom data types in ROL.
Real snorm
bool flag
Provides the interface to compute unconstrained optimization steps for line search.
Provides definitions for Krylov solvers.
Provides the interface to apply a linear operator.
const Ptr< const Vector< Real > > x_
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
const Ptr< Objective< Real > > obj_
HessianNK(const Ptr< Objective< Real > > &obj, const Ptr< const Vector< Real > > &x)
const Ptr< Objective< Real > > obj_
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
PrecondNK(const Ptr< Objective< Real > > &obj, const Ptr< const Vector< Real > > &x)
const Ptr< const Vector< Real > > x_
void applyInverse(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Provides the interface to compute optimization steps with projected inexact Newton's method using lin...
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
bool useSecantPrecond_
Whether or not a secant approximation is used for preconditioning inexact Newton.
std::string printName(void) const override
NewtonKrylov_U(ParameterList &parlist, const Ptr< Krylov< Real > > &krylov, Ptr< Secant< Real > > &secant, const bool computeObj=true)
Constructor.
Ptr< LinearOperator< Real > > precond_
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
Ptr< Secant< Real > > secant_
Secant object (used for quasi-Newton)
NewtonKrylov_U(ParameterList &parlist)
Constructor.
Ptr< Krylov< Real > > krylov_
Krylov solver object (used for inexact Newton)
Provides the interface to evaluate objective functions.
Provides interface for and implements limited-memory secant operators.
Defines the linear algebra or vector space interface.
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
virtual Real norm() const =0
Returns where .
virtual void set(const Vector &x)
Set where .
virtual void scale(const Real alpha)=0
Compute where .
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
EKrylov StringToEKrylov(std::string s)
ESecant StringToESecant(std::string s)
Ptr< Krylov< Real > > KrylovFactory(ParameterList &parlist)
@ SECANT_USERDEFINED
ROL::Ptr< Secant< Real > > SecantFactory(ROL::ParameterList &parlist, ESecantMode mode=SECANTMODE_BOTH)