ROL
ROL_LineSearch_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_LINESEARCH_U_H
11#define ROL_LINESEARCH_U_H
12
17#include "ROL_Ptr.hpp"
18#include "ROL_ParameterList.hpp"
19#include "ROL_Types.hpp"
20#include "ROL_Objective.hpp"
21#include "ROL_ScalarFunction.hpp"
23
24namespace ROL {
25
26template<typename Real>
28private:
29
32
34 bool usePrevAlpha_; // Use the previous step's accepted alpha as an initial guess
35 Real alpha0_;
36 Real alpha0bnd_; // Lower bound for initial alpha...if below, set initial alpha to one
37 int maxit_;
38 Real c1_;
39 Real c2_;
40 Real c3_;
41 Real eps_;
42 Real fmin_; // smallest fval encountered
43 Real alphaMin_; // Alpha that yields the smallest fval encountered
44 bool acceptMin_; // Use smallest fval if sufficient decrease not satisfied
45 bool itcond_; // true if maximum function evaluations reached
47
48 Ptr<Vector<Real>> xtst_;
49
50 Real dirDeriv(const Vector<Real> &x, // current iterate
51 const Vector<Real> &s, // current trial step
52 const Real alpha, // current step length
53 const Real fnew, // f(x+alpha*s)
54 Objective<Real> &obj) {
55 Real tol = std::sqrt(ROL_EPSILON<Real>());
56 Real val(0);
57 xtst_->set(x); xtst_->axpy(alpha,s);
58 if (FDdirDeriv_) {
59 Real snorm = s.norm();
60 if (snorm > static_cast<Real>(0)) {
61 Real xnorm = xtst_->norm();
62 Real cbrteps = std::cbrt(ROL_EPSILON<Real>());
63 Real h = cbrteps*std::max(xnorm/snorm,static_cast<Real>(1));
64 xtst_->axpy(h,s);
66 Real ftrial = obj.value(*xtst_,tol);
67 val = (ftrial - fnew) / h;
68 }
69 }
70 else {
71 val = obj.dirDeriv(*xtst_,s,tol);
72 }
73 return val;
74 }
75
76public:
77
78 virtual ~LineSearch_U() {}
79
80 // Constructor
81 LineSearch_U( ParameterList &parlist ) {
82 Real one(1), p9(0.9), p6(0.6), p4(0.4), oem4(1.e-4), zero(0);
83 // Enumerations
84 std::string descentType = parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Quasi-Newton Method");
85 edesc_ = StringToEDescentU(descentType);
86 std::string condType = parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("Type","Strong Wolfe Conditions");
88 // Linesearch Parameters
89 alpha0_ = parlist.sublist("Step").sublist("Line Search").get("Initial Step Size",one);
90 alpha0bnd_ = parlist.sublist("Step").sublist("Line Search").get("Lower Bound for Initial Step Size",one);
91 useralpha_ = parlist.sublist("Step").sublist("Line Search").get("User Defined Initial Step Size",false);
92 usePrevAlpha_ = parlist.sublist("Step").sublist("Line Search").get("Use Previous Step Length as Initial Guess",false);
93 acceptMin_ = parlist.sublist("Step").sublist("Line Search").get("Accept Linesearch Minimizer",false);
94 maxit_ = parlist.sublist("Step").sublist("Line Search").get("Function Evaluation Limit",20);
95 c1_ = parlist.sublist("Step").sublist("Line Search").get("Sufficient Decrease Tolerance",oem4);
96 c2_ = parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("General Parameter",p9);
97 c3_ = parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("Generalized Wolfe Parameter",p6);
98
99 fmin_ = std::numeric_limits<Real>::max();
100 alphaMin_ = 0;
101 itcond_ = false;
102 FDdirDeriv_ = parlist.sublist("Step").sublist("Line Search").get("Finite Difference Directional Derivative",false);
103
104 c1_ = ((c1_ < zero) ? oem4 : c1_);
105 c2_ = ((c2_ < zero) ? p9 : c2_);
106 c3_ = ((c3_ < zero) ? p9 : c3_);
107 if ( c2_ <= c1_ ) {
108 c1_ = oem4;
109 c2_ = p9;
110 }
111 if ( edesc_ == DESCENT_U_NONLINEARCG ) {
112 c2_ = p4;
113 c3_ = std::min(one-c2_,c3_);
114 }
115 }
116
117 virtual void initialize(const Vector<Real> &x, const Vector<Real> &g) {
118 xtst_ = x.clone();
119 }
120
121 virtual void run( Real &alpha, Real &fval, int &ls_neval, int &ls_ngrad,
122 const Real &gs, const Vector<Real> &s, const Vector<Real> &x,
123 Objective<Real> &obj ) = 0;
124
125 // use this function to modify alpha and fval if the maximum number of iterations
126 // are reached
127 void setMaxitUpdate(Real &alpha, Real &fnew, const Real &fold) {
128 // Use local minimizer
129 if( itcond_ && acceptMin_ ) {
130 alpha = alphaMin_;
131 fnew = fmin_;
132 }
133 // Take no step
134 else if(itcond_ && !acceptMin_) {
135 alpha = 0;
136 fnew = fold;
137 }
138 setNextInitialAlpha(alpha);
139 }
140
141protected:
142 virtual bool status( const ELineSearchU type, int &ls_neval, int &ls_ngrad, const Real alpha,
143 const Real fold, const Real sgold, const Real fnew,
144 const Vector<Real> &x, const Vector<Real> &s,
145 Objective<Real> &obj ) {
146 const Real one(1), two(2);
147
148 // Check Armijo Condition
149 bool armijo = false;
150 if ( fnew <= fold + c1_*alpha*sgold ) {
151 armijo = true;
152 }
153
154 // Check Maximum Iteration
155 itcond_ = false;
156 if ( ls_neval >= maxit_ ) {
157 itcond_ = true;
158 }
159
160 // Check Curvature Condition
161 bool curvcond = false;
162 if ( armijo && ((type != LINESEARCH_U_BACKTRACKING && type != LINESEARCH_U_CUBICINTERP) ||
165 if (fnew >= fold + (one-c1_)*alpha*sgold) {
166 curvcond = true;
167 }
168 }
169 else if (econd_ == CURVATURECONDITION_U_NULL) {
170 curvcond = true;
171 }
172 else {
173 Real sgnew = dirDeriv(x,s,alpha,fnew,obj); //ls_ngrad++;
175 && (sgnew >= c2_*sgold))
177 && (std::abs(sgnew) <= c2_*std::abs(sgold)))
179 && (c2_*sgold <= sgnew && sgnew <= -c3_*sgold))
181 && (c2_*sgold <= sgnew && sgnew <= (two*c1_ - one)*sgold)) ) {
182 curvcond = true;
183 }
184 }
185 }
186
187 if(fnew<fmin_) {
188 fmin_ = fnew;
189 alphaMin_ = alpha;
190 }
191
194 return ((armijo && curvcond) || itcond_);
195 }
196 else {
197 return (armijo || itcond_);
198 }
199 }
200 else {
201 return ((armijo && curvcond) || itcond_);
202 }
203 }
204
205 virtual Real getInitialAlpha(int &ls_neval, int &ls_ngrad, const Real fval, const Real gs,
206 const Vector<Real> &x, const Vector<Real> &s,
207 Objective<Real> &obj) {
208 Real val(1);
209 if (useralpha_ || usePrevAlpha_ ) {
210 val = alpha0_;
211 }
212 else {
213 const Real one(1), half(0.5);
215 Real tol = std::sqrt(ROL_EPSILON<Real>());
216 // Evaluate objective at x + s
217 xtst_->set(x); xtst_->plus(s);
219 Real fnew = obj.value(*xtst_,tol);
220 ls_neval++;
221 // Minimize quadratic interpolate to compute new alpha
222 Real denom = (fnew - fval - gs);
223 Real alpha = ((denom > ROL_EPSILON<Real>()) ? -half*gs/denom : one);
224 val = ((alpha > alpha0bnd_) ? alpha : one);
225 }
226 else {
227 val = one;
228 }
229 }
230 return val;
231 }
232
233 void setNextInitialAlpha( Real alpha ) {
234 if( usePrevAlpha_ ) {
235 alpha0_ = alpha;
236 }
237 }
238
240 return itcond_ && acceptMin_;
241 }
242
243 bool takeNoStep() {
244 return itcond_ && !acceptMin_;
245 }
246}; // class ROL::LineSearch_U
247
248} // namespace ROL
249
250#endif
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Contains definitions of custom data types in ROL.
Provides interface for and implements line searches.
void setMaxitUpdate(Real &alpha, Real &fnew, const Real &fold)
Real dirDeriv(const Vector< Real > &x, const Vector< Real > &s, const Real alpha, const Real fnew, Objective< Real > &obj)
virtual bool status(const ELineSearchU type, int &ls_neval, int &ls_ngrad, const Real alpha, const Real fold, const Real sgold, const Real fnew, const Vector< Real > &x, const Vector< Real > &s, Objective< Real > &obj)
virtual Real getInitialAlpha(int &ls_neval, int &ls_ngrad, const Real fval, const Real gs, const Vector< Real > &x, const Vector< Real > &s, Objective< Real > &obj)
virtual void initialize(const Vector< Real > &x, const Vector< Real > &g)
Ptr< Vector< Real > > xtst_
ECurvatureConditionU econd_
virtual void run(Real &alpha, Real &fval, int &ls_neval, int &ls_ngrad, const Real &gs, const Vector< Real > &s, const Vector< Real > &x, Objective< Real > &obj)=0
void setNextInitialAlpha(Real alpha)
LineSearch_U(ParameterList &parlist)
Provides the interface to evaluate objective functions.
virtual Real dirDeriv(const Vector< Real > &x, const Vector< Real > &d, Real &tol)
Compute directional derivative.
virtual Real value(const Vector< Real > &x, Real &tol)=0
Compute value.
virtual void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
Defines the linear algebra or vector space interface.
virtual Real norm() const =0
Returns where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
@ CURVATURECONDITION_U_APPROXIMATEWOLFE
@ CURVATURECONDITION_U_GENERALIZEDWOLFE
@ CURVATURECONDITION_U_STRONGWOLFE
ECurvatureConditionU StringToECurvatureConditionU(std::string s)
EDescentU StringToEDescentU(std::string s)