ROL
ROL_TypeU_LineSearchAlgorithm_Def.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_TYPEU_LINESEARCHALGORITHM_DEF_H
11#define ROL_TYPEU_LINESEARCHALGORITHM_DEF_H
12
15
16namespace ROL {
17namespace TypeU {
18
19template<typename Real>
21 const Ptr<Secant<Real>> &secant,
22 const Ptr<DescentDirection_U<Real>> &descent,
23 const Ptr<LineSearch_U<Real>> &lineSearch )
24 : Algorithm<Real>(), desc_(descent), lineSearch_(lineSearch),
27 // Set status test
28 status_->reset();
29 status_->add(makePtr<StatusTest<Real>>(parlist));
30
31 // Parse parameter list
32 ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
33 ParameterList& Glist = parlist.sublist("General");
34 std::string condType = Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions");
36 acceptLastAlpha_ = Llist.get("Accept Last Alpha", false);
37 verbosity_ = Glist.get("Output Level",0);
39 // Initialize Line Search
40 if (lineSearch_ == nullPtr) {
41 lineSearchName_ = Llist.sublist("Line-Search Method").get("Type","Cubic Interpolation");
44 }
45 else { // User-defined linesearch provided
46 lineSearchName_ = Llist.sublist("Line-Search Method").get("User Defined Line Search Name","Unspecified User Defined Line Search");
47 }
48 if (desc_ == nullPtr) {
49 ParameterList& dlist = Llist.sublist("Descent Method");
50 descentName_ = dlist.get("Type","Quasi-Newton Method");
52 desc_ = DescentDirectionUFactory<Real>(parlist,secant);
53 }
54 else {
55 descentName_ = Llist.sublist("Descent Method").get("User Defined Descent Direction Name","Unspecified User Defined Descent Direction");
56 }
57}
58
59template<typename Real>
61 const Vector<Real> &g,
62 Objective<Real> &obj,
63 std::ostream &outStream) {
64 // Initialize data
66 lineSearch_->initialize(x,g);
67 desc_->initialize(x,g);
68 // Update approximate gradient and approximate objective function.
69 Real ftol = std::sqrt(ROL_EPSILON<Real>());
70 obj.update(x,UpdateType::Initial,state_->iter);
71 state_->value = obj.value(x,ftol);
72 state_->nfval++;
73 obj.gradient(*state_->gradientVec,x,ftol);
74 state_->ngrad++;
75 state_->gnorm = state_->gradientVec->norm();
76 state_->snorm = ROL_INF<Real>();
77}
78
79template<typename Real>
81 const Vector<Real> &g,
82 Objective<Real> &obj,
83 std::ostream &outStream ) {
84 const Real one(1);
85 // Initialize trust-region data
86 Real ftrial(0), gs(0), tol(std::sqrt(ROL_EPSILON<Real>()));
87 initialize(x,g,obj,outStream);
88 state_->searchSize = one;
89 Ptr<Vector<Real>> gprev = g.clone();
90
91 // Output
92 if (verbosity_ > 0) writeOutput(outStream, true);
93
94 while (status_->check(*state_)) {
95 // Compute descent direction
96 desc_->compute(*state_->stepVec,state_->snorm,gs,SPiter_,SPflag_,x,
97 *state_->gradientVec,obj);
98
99 // Perform line search
100 ftrial = state_->value;
101 ls_nfval_ = 0; ls_ngrad_ = 0;
102 lineSearch_->run(state_->searchSize,ftrial,ls_nfval_,ls_ngrad_,gs,*state_->stepVec,x,obj);
103
104 // Make correction if maximum function evaluations reached
105 if(!acceptLastAlpha_) {
106 lineSearch_->setMaxitUpdate(state_->searchSize,ftrial,state_->value);
107 }
108
109 // Compute scaled descent direction
110 state_->stepVec->scale(state_->searchSize);
111 state_->snorm *= state_->searchSize;
112
113 // Update iterate
114 x.plus(*state_->stepVec);
115
116 // Compute new value and gradient
117 obj.update(x,UpdateType::Accept,state_->iter);
118 state_->value = obj.value(x,tol);
119 state_->nfval++;
120 gprev->set(*state_->gradientVec);
121 obj.gradient(*state_->gradientVec,x,tol);
122 state_->ngrad++;
123 state_->gnorm = state_->gradientVec->norm();
124
125 // Update algorithm state
126 state_->iterateVec->set(x);
127 state_->nfval += ls_nfval_;
128 state_->ngrad += ls_ngrad_;
129 desc_->update(x,*state_->stepVec,*gprev,*state_->gradientVec,state_->snorm,state_->iter);
130 state_->iter++;
131
132 // Update Output
133 if (verbosity_ > 0) writeOutput(outStream,printHeader_);
134 }
136}
137
138template<typename Real>
139void LineSearchAlgorithm<Real>::writeHeader( std::ostream& os ) const {
140 std::ios_base::fmtflags osFlags(os.flags());
141 if (verbosity_ > 1) {
142 os << std::string(109,'-') << std::endl;
143 os << descentName_;
144 os << " status output definitions" << std::endl << std::endl;
145 os << " iter - Number of iterates (steps taken)" << std::endl;
146 os << " value - Objective function value" << std::endl;
147 os << " gnorm - Norm of the gradient" << std::endl;
148 os << " snorm - Norm of the step (update to optimization vector)" << std::endl;
149 os << " alpha - Line search step length" << std::endl;
150 os << " #fval - Cumulative number of times the objective function was evaluated" << std::endl;
151 os << " #grad - Cumulative number of times the gradient was computed" << std::endl;
152 os << " ls_#fval - Number of the times the objective function was evaluated during the line search" << std::endl;
153 os << " ls_#grad - Number of the times the gradient was evaluated during the line search" << std::endl;
155 os << " iterCG - Number of Krylov iterations used to compute search direction" << std::endl;
156 os << " flagCG - Krylov solver flag" << std::endl;
157 }
158 os << std::string(109,'-') << std::endl;
159 }
160
161 os << " ";
162 os << std::setw(6) << std::left << "iter";
163 os << std::setw(15) << std::left << "value";
164 os << std::setw(15) << std::left << "gnorm";
165 os << std::setw(15) << std::left << "snorm";
166 os << std::setw(15) << std::left << "alpha";
167 os << std::setw(10) << std::left << "#fval";
168 os << std::setw(10) << std::left << "#grad";
169 os << std::setw(10) << std::left << "ls_#fval";
170 os << std::setw(10) << std::left << "ls_#grad";
172 os << std::setw(10) << std::left << "iterCG";
173 os << std::setw(10) << std::left << "flagCG";
174 }
175 os << std::endl;
176 os.flags(osFlags);
177}
178
179template<typename Real>
180void LineSearchAlgorithm<Real>::writeName( std::ostream& os ) const {
181 std::ios_base::fmtflags osFlags(os.flags());
182 os << std::endl << desc_->printName();
183 os << std::endl;
184 os << "Line Search: " << lineSearchName_;
185 os << " satisfying " << ECurvatureConditionUToString(econd_) << std::endl;
186 os.flags(osFlags);
187}
188
189template<typename Real>
190void LineSearchAlgorithm<Real>::writeOutput( std::ostream& os, bool print_header) const {
191 std::ios_base::fmtflags osFlags(os.flags());
192 os << std::scientific << std::setprecision(6);
193 if ( state_->iter == 0 ) {
194 writeName(os);
195 }
196 if ( print_header ) {
197 writeHeader(os);
198 }
199 if ( state_->iter == 0 ) {
200 os << " ";
201 os << std::setw(6) << std::left << state_->iter;
202 os << std::setw(15) << std::left << state_->value;
203 os << std::setw(15) << std::left << state_->gnorm;
204 os << std::setw(15) << std::left << "---";
205 os << std::setw(15) << std::left << "---";
206 os << std::setw(10) << std::left << state_->nfval;
207 os << std::setw(10) << std::left << state_->ngrad;
208 os << std::setw(10) << std::left << "---";
209 os << std::setw(10) << std::left << "---";
211 os << std::setw(10) << std::left << "---";
212 os << std::setw(10) << std::left << "---";
213 }
214 os << std::endl;
215 }
216 else {
217 os << " ";
218 os << std::setw(6) << std::left << state_->iter;
219 os << std::setw(15) << std::left << state_->value;
220 os << std::setw(15) << std::left << state_->gnorm;
221 os << std::setw(15) << std::left << state_->snorm;
222 os << std::setw(15) << std::left << state_->searchSize;
223 os << std::setw(10) << std::left << state_->nfval;
224 os << std::setw(10) << std::left << state_->ngrad;
225 os << std::setw(10) << std::left << ls_nfval_;
226 os << std::setw(10) << std::left << ls_ngrad_;
228 os << std::setw(10) << std::left << SPiter_;
229 os << std::setw(10) << std::left << SPflag_;
230 }
231 os << std::endl;
232 }
233 os.flags(osFlags);
234}
235} // namespace TypeU
236} // namespace ROL
237
238#endif
virtual void initialize(const Vector< Real > &x)
Initialize temporary variables.
Provides the interface to compute unconstrained optimization steps for line search.
Provides interface for and implements line searches.
Provides the interface to evaluate objective functions.
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
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.
Algorithm()
Constructor, given a step and a status test.
const Ptr< CombinedStatusTest< Real > > status_
const Ptr< AlgorithmState< Real > > state_
Provides interface for and implements limited-memory secant operators.
Provides an interface to check status of optimization algorithms.
void initialize(const Vector< Real > &x, const Vector< Real > &g)
virtual void writeExitStatus(std::ostream &os) const
Ptr< DescentDirection_U< Real > > desc_
Unglobalized step object.
LineSearchAlgorithm(ParameterList &parlist, const Ptr< Secant< Real > > &secant=nullPtr, const Ptr< DescentDirection_U< Real > > &descent=nullPtr, const Ptr< LineSearch_U< Real > > &lineSearch=nullPtr)
Constructor.
bool acceptLastAlpha_
For backwards compatibility. When max function evaluations are reached take last step.
void writeHeader(std::ostream &os) const override
Print iterate header.
Ptr< LineSearch_U< Real > > lineSearch_
Line-search object.
void writeName(std::ostream &os) const override
Print step name.
EDescentU edesc_
enum determines type of descent direction
void run(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, std::ostream &outStream=std::cout) override
ELineSearchU els_
enum determines type of line search
void initialize(const Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, std::ostream &outStream=std::cout)
void writeOutput(std::ostream &os, const bool print_header=false) const override
Print iterate status.
ECurvatureConditionU econd_
enum determines type of curvature condition
Defines the linear algebra or vector space interface.
virtual void plus(const Vector &x)=0
Compute , where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Ptr< LineSearch_U< Real > > LineSearchUFactory(ParameterList &parlist)
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition ROL_Types.hpp:57
std::string ECurvatureConditionUToString(ECurvatureConditionU ls)
ECurvatureConditionU StringToECurvatureConditionU(std::string s)
ELineSearchU StringToELineSearchU(std::string s)
Real ROL_INF(void)
Definition ROL_Types.hpp:71
EDescentU StringToEDescentU(std::string s)
Ptr< DescentDirection_U< Real > > DescentDirectionUFactory(ParameterList &parlist, const Ptr< Secant< Real > > &secant=nullPtr)