44#ifndef ROL_LINESEARCH_U_H
45#define ROL_LINESEARCH_U_H
52#include "ROL_ParameterList.hpp"
55#include "ROL_ScalarFunction.hpp"
60template<
typename Real>
85 const Vector<Real> &s,
88 Objective<Real> &obj) {
89 Real tol = std::sqrt(ROL_EPSILON<Real>());
91 xtst_->set(x); xtst_->axpy(alpha,s);
93 Real
snorm = s.norm();
94 if (
snorm >
static_cast<Real
>(0)) {
95 Real xnorm = xtst_->norm();
96 Real cbrteps = std::cbrt(ROL_EPSILON<Real>());
97 Real h = cbrteps*std::max(xnorm/
snorm,
static_cast<Real
>(1));
99 obj.update(*xtst_,UpdateType::Trial);
100 Real ftrial = obj.value(*xtst_,tol);
101 val = (ftrial - fnew) / h;
105 val = obj.dirDeriv(*xtst_,s,tol);
116 Real one(1), p9(0.9), p6(0.6), p4(0.4), oem4(1.e-4),
zero(0);
118 edesc_ = StringToEDescentU(parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Descent Method").get(
"Type",
"Quasi-Newton Method"));
119 econd_ = StringToECurvatureConditionU(parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Curvature Condition").get(
"Type",
"Strong Wolfe Conditions"));
121 alpha0_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Initial Step Size",one);
122 alpha0bnd_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Lower Bound for Initial Step Size",one);
123 useralpha_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"User Defined Initial Step Size",
false);
124 usePrevAlpha_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Use Previous Step Length as Initial Guess",
false);
125 acceptMin_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Accept Linesearch Minimizer",
false);
126 maxit_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Function Evaluation Limit",20);
127 c1_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Sufficient Decrease Tolerance",oem4);
128 c2_ = parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Curvature Condition").get(
"General Parameter",p9);
129 c3_ = parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Curvature Condition").get(
"Generalized Wolfe Parameter",p6);
131 fmin_ = std::numeric_limits<Real>::max();
134 FDdirDeriv_ = parlist.sublist(
"Step").sublist(
"Line Search").get(
"Finite Difference Directional Derivative",
false);
136 c1_ = ((c1_ <
zero) ? oem4 : c1_);
137 c2_ = ((c2_ <
zero) ? p9 : c2_);
138 c3_ = ((c3_ <
zero) ? p9 : c3_);
143 if ( edesc_ == DESCENT_U_NONLINEARCG ) {
145 c3_ = std::min(one-c2_,c3_);
149 virtual void initialize(
const Vector<Real> &x,
const Vector<Real> &g) {
153 virtual void run( Real &alpha, Real &fval,
int &ls_neval,
int &ls_ngrad,
154 const Real &gs,
const Vector<Real> &s,
const Vector<Real> &x,
155 Objective<Real> &obj ) = 0;
161 if( itcond_ && acceptMin_ ) {
166 else if(itcond_ && !acceptMin_) {
174 virtual bool status(
const ELineSearchU
type,
int &ls_neval,
int &ls_ngrad,
const Real alpha,
175 const Real fold,
const Real sgold,
const Real fnew,
176 const Vector<Real> &x,
const Vector<Real> &s,
177 Objective<Real> &obj ) {
178 const Real one(1), two(2);
182 if ( fnew <= fold + c1_*alpha*sgold ) {
188 if ( ls_neval >= maxit_ ) {
193 bool curvcond =
false;
194 if ( armijo && ((
type != LINESEARCH_U_BACKTRACKING &&
type != LINESEARCH_U_CUBICINTERP) ||
195 (edesc_ == DESCENT_U_NONLINEARCG)) ) {
196 if (econd_ == CURVATURECONDITION_U_GOLDSTEIN) {
197 if (fnew >= fold + (one-c1_)*alpha*sgold) {
201 else if (econd_ == CURVATURECONDITION_U_NULL) {
205 Real sgnew =
dirDeriv(x,s,alpha,fnew,obj);
206 if ( ((econd_ == CURVATURECONDITION_U_WOLFE)
207 && (sgnew >= c2_*sgold))
208 || ((econd_ == CURVATURECONDITION_U_STRONGWOLFE)
209 && (std::abs(sgnew) <= c2_*std::abs(sgold)))
210 || ((econd_ == CURVATURECONDITION_U_GENERALIZEDWOLFE)
211 && (c2_*sgold <= sgnew && sgnew <= -c3_*sgold))
212 || ((econd_ == CURVATURECONDITION_U_APPROXIMATEWOLFE)
213 && (c2_*sgold <= sgnew && sgnew <= (two*c1_ - one)*sgold)) ) {
224 if (
type == LINESEARCH_U_BACKTRACKING ||
type == LINESEARCH_U_CUBICINTERP) {
225 if (edesc_ == DESCENT_U_NONLINEARCG) {
226 return ((armijo && curvcond) || itcond_);
229 return (armijo || itcond_);
233 return ((armijo && curvcond) || itcond_);
237 virtual Real
getInitialAlpha(
int &ls_neval,
int &ls_ngrad,
const Real fval,
const Real gs,
238 const Vector<Real> &x,
const Vector<Real> &s,
239 Objective<Real> &obj) {
241 if (useralpha_ || usePrevAlpha_ ) {
245 const Real one(1), half(0.5);
246 if (edesc_ == DESCENT_U_STEEPEST || edesc_ == DESCENT_U_NONLINEARCG) {
247 Real tol = std::sqrt(ROL_EPSILON<Real>());
249 xtst_->set(x); xtst_->plus(s);
250 obj.update(*xtst_,UpdateType::Trial);
251 Real fnew = obj.value(*xtst_,tol);
254 Real denom = (fnew - fval - gs);
255 Real alpha = ((denom > ROL_EPSILON<Real>()) ? -half*gs/denom : one);
256 val = ((alpha > alpha0bnd_) ? alpha : one);
266 if( usePrevAlpha_ ) {
272 return itcond_ && acceptMin_;
276 return itcond_ && !acceptMin_;
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.
Real dirDeriv(const Vector< Real > &x, const Vector< Real > &s, const Real alpha, const Real fnew, Objective< Real > &obj)
virtual void initialize(const Vector< Real > &x, const Vector< Real > &g)
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
LineSearch_U(ParameterList &parlist)
Ptr< Vector< Real > > xtst_
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)
ECurvatureConditionU econd_
void setMaxitUpdate(Real &alpha, Real &fnew, const Real &fold)
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)
void setNextInitialAlpha(Real alpha)