44 #ifndef ROL_TYPEP_PROXGRADIENTALGORITHM_DEF_HPP
45 #define ROL_TYPEP_PROXGRADIENTALGORITHM_DEF_HPP
50 template<
typename Real>
57 ParameterList &lslist = list.sublist(
"Step").sublist(
"Line Search");
58 maxit_ = lslist.get(
"Function Evaluation Limit", 20);
59 alpha0_ = lslist.get(
"Initial Step Size", 1.0);
60 normAlpha_ = lslist.get(
"Normalize Initial Step Size",
false);
61 alpha0bnd_ = lslist.get(
"Lower Bound for Initial Step Size", 1e-4);
62 useralpha_ = lslist.get(
"User Defined Initial Step Size",
false);
63 usePrevAlpha_ = lslist.get(
"Use Previous Step Length as Initial Guess",
false);
64 c1_ = lslist.get(
"Sufficient Decrease Tolerance", 1e-4);
65 maxAlpha_ = lslist.get(
"Maximum Step Size", alpha0_);
66 useAdapt_ = lslist.get(
"Use Adaptive Step Size Selection",
true);
67 initProx_ = lslist.get(
"Apply Prox to Initial Guess",
false);
68 rhodec_ = lslist.sublist(
"Line-Search Method").get(
"Backtracking Rate", 0.5);
69 rhoinc_ = lslist.sublist(
"Line-Search Method").get(
"Increase Rate" , 2.0);
70 t0_ = list.sublist(
"Status Test").get(
"Gradient Scale" , 1.0);
71 verbosity_ = list.sublist(
"General").get(
"Output Level", 0);
72 writeHeader_ = verbosity_ > 2;
75 template<
typename Real>
82 std::ostream &outStream) {
87 Real ftol = std::sqrt(ROL_EPSILON<Real>());
89 nobj.
prox(*state_->iterateVec,x,state_->searchSize,ftol);
91 x.
set(*state_->iterateVec);
96 state_->svalue = sobj.
value(x,ftol); state_->nsval++;
97 state_->nvalue = nobj.
value(x,ftol); state_->nnval++;
98 state_->value = state_->svalue + state_->nvalue;
100 sobj.
gradient(*state_->gradientVec,x,ftol); state_->ngrad++;
101 dg.
set(state_->gradientVec->dual());
105 bool flag = maxAlpha_ == alpha0_;
107 pgstep(px, *state_->stepVec, nobj, x, dg, t0_, ftol);
108 state_->snorm = state_->stepVec->norm();
110 Real snew = sobj.
value(px,ftol);
113 Real gs = state_->gradientVec->apply(*state_->stepVec);
114 alpha0_ = (state_->snorm * state_->snorm) / std::abs(snew - state_->svalue - gs);
115 alpha0_ = ((alpha0_ > alpha0bnd_) ? alpha0_ : one);
116 if (flag) maxAlpha_ = alpha0_;
120 alpha0_ /= state_->gradientVec->norm();
121 state_->searchSize = alpha0_;
123 pgstep(*state_->iterateVec, *state_->stepVec, nobj, x, dg, state_->searchSize, ftol);
124 state_->snorm = state_->stepVec->norm();
125 state_->gnorm = state_->snorm / state_->searchSize;
128 template<
typename Real>
133 std::ostream &outStream ) {
135 Real tol(std::sqrt(ROL_EPSILON<Real>()));
138 initialize(x,g,sobj,nobj,*px,*dg,outStream);
139 Real strial(0), ntrial(0), Ftrial(0), Qk(0);
140 Real strialP(0), ntrialP(0), FtrialP(0), alphaP(0);
141 Real snorm(state_->snorm), searchSize(state_->searchSize);
143 bool incAlpha =
false, accept =
true;
146 if (verbosity_ > 0) writeOutput(outStream,
true);
149 while (status_->check(*state_)) {
152 state_->searchSize = searchSize;
155 strial = sobj.
value(*state_->iterateVec,tol);
157 ntrial = nobj.
value(*state_->iterateVec,tol);
158 Ftrial = strial + ntrial;
161 Qk = state_->gradientVec->apply(*state_->stepVec) + ntrial - state_->nvalue;
162 incAlpha = (Ftrial - state_->value <= c1_*Qk);
163 if (verbosity_ > 1) {
164 outStream <<
" In TypeP::GradientAlgorithm: Line Search" << std::endl;
165 outStream <<
" Step size: " << state_->searchSize << std::endl;
166 outStream <<
" Trial smooth value: " << strial << std::endl;
167 outStream <<
" Trial nonsmooth value: " << ntrial << std::endl;
168 outStream <<
" Computed reduction: " << state_->value-Ftrial << std::endl;
169 outStream <<
" Dot product of gradient and step: " << Qk << std::endl;
170 outStream <<
" Sufficient decrease bound: " << -Qk*c1_ << std::endl;
171 outStream <<
" Number of function evaluations: " << ls_nfval << std::endl;
172 outStream <<
" Increase alpha?: " << incAlpha << std::endl;
174 if (incAlpha && useAdapt_) {
175 ntrialP = ROL_INF<Real>();
176 strialP = ROL_INF<Real>();
177 FtrialP = ntrialP + strialP;
178 while ( Ftrial - state_->value <= c1_*Qk
180 && state_->searchSize < maxAlpha_
181 && ls_nfval < maxit_ ) {
186 pxP->set(*state_->iterateVec);
187 alphaP = state_->searchSize;
192 state_->searchSize *= rhoinc_;
193 state_->searchSize = std::min(state_->searchSize,maxAlpha_);
195 pgstep(*state_->iterateVec, *state_->stepVec, nobj, x, *dg, state_->searchSize, tol);
198 strial = sobj.
value(*state_->iterateVec,tol);
200 ntrial = nobj.
value(*state_->iterateVec,tol);
201 Ftrial = strial + ntrial;
204 Qk = state_->gradientVec->apply(*state_->stepVec) + ntrial - state_->nvalue;
205 if (verbosity_ > 1) {
206 outStream << std::endl;
207 outStream <<
" Step size: " << state_->searchSize << std::endl;
208 outStream <<
" Trial smooth value: " << strial << std::endl;
209 outStream <<
" Trial nonsmooth value: " << ntrial << std::endl;
210 outStream <<
" Computed reduction: " << state_->value-Ftrial << std::endl;
211 outStream <<
" Dot product of gradient and step: " << Qk << std::endl;
212 outStream <<
" Sufficient decrease bound: " << -Qk*c1_ << std::endl;
213 outStream <<
" Number of function evaluations: " << ls_nfval << std::endl;
216 if (Ftrial - state_->value > c1_*Qk || Ftrial > FtrialP) {
217 state_->iterateVec->set(*pxP);
221 state_->searchSize = alphaP;
222 state_->stepVec->set(*state_->iterateVec);
223 state_->stepVec->axpy(-one,x);
228 while ( Ftrial - state_->value > c1_*Qk && ls_nfval < maxit_ ) {
230 state_->searchSize *= rhodec_;
232 pgstep(*state_->iterateVec, *state_->stepVec, nobj, x, *dg, state_->searchSize, tol);
235 strial = sobj.
value(*state_->iterateVec,tol);
237 ntrial = nobj.
value(*state_->iterateVec,tol);
238 Ftrial = strial + ntrial;
241 Qk = state_->gradientVec->apply(*state_->stepVec) + ntrial - state_->nvalue;
242 if (verbosity_ > 1) {
243 outStream << std::endl;
244 outStream <<
" Step size: " << state_->searchSize << std::endl;
245 outStream <<
" Trial smooth value: " << strial << std::endl;
246 outStream <<
" Trial nonsmooth value: " << ntrial << std::endl;
247 outStream <<
" Computed reduction: " << state_->value-Ftrial << std::endl;
248 outStream <<
" Dot product of gradient and step: " << Qk << std::endl;
249 outStream <<
" Sufficient decrease bound: " << -Qk*c1_ << std::endl;
250 outStream <<
" Number of function evaluations: " << ls_nfval << std::endl;
254 state_->nsval += ls_nfval;
255 state_->nnval += ls_nfval;
258 state_->snorm = state_->stepVec->norm();
262 x.
set(*state_->iterateVec);
265 state_->svalue = strial;
266 state_->nvalue = ntrial;
267 state_->value = Ftrial;
276 sobj.
gradient(*state_->gradientVec,x,tol);
278 dg->set(state_->gradientVec->dual());
281 searchSize = state_->searchSize;
282 if (!usePrevAlpha_ && !useAdapt_) searchSize = alpha0_;
283 pgstep(*state_->iterateVec, *state_->stepVec, nobj, x, *dg, searchSize, tol);
284 snorm = state_->stepVec->norm();
285 state_->gnorm = snorm / searchSize;
288 if (verbosity_ > 0) writeOutput(outStream,writeHeader_);
293 template<
typename Real>
295 std::ios_base::fmtflags osFlags(os.flags());
296 if (verbosity_ > 1) {
297 os << std::string(109,
'-') << std::endl;
298 os <<
"Proximal gradient descent";
299 os <<
" status output definitions" << std::endl << std::endl;
300 os <<
" iter - Number of iterates (steps taken)" << std::endl;
301 os <<
" value - Objective function value" << std::endl;
302 os <<
" gnorm - Norm of the proximal gradient with parameter alpha" << std::endl;
303 os <<
" snorm - Norm of the step (update to optimization vector)" << std::endl;
304 os <<
" alpha - Line search step length" << std::endl;
305 os <<
" #sval - Cumulative number of times the smooth objective function was evaluated" << std::endl;
306 os <<
" #nval - Cumulative number of times the nonsmooth objective function was evaluated" << std::endl;
307 os <<
" #grad - Cumulative number of times the gradient was computed" << std::endl;
308 os <<
" #prox - Cumulative number of times the proximal operator was computed" << std::endl;
309 os << std::string(109,
'-') << std::endl;
313 os << std::setw(6) << std::left <<
"iter";
314 os << std::setw(15) << std::left <<
"value";
315 os << std::setw(15) << std::left <<
"gnorm";
316 os << std::setw(15) << std::left <<
"snorm";
317 os << std::setw(15) << std::left <<
"alpha";
318 os << std::setw(10) << std::left <<
"#sval";
319 os << std::setw(10) << std::left <<
"#nval";
320 os << std::setw(10) << std::left <<
"#grad";
321 os << std::setw(10) << std::left <<
"#nprox";
326 template<
typename Real>
328 std::ios_base::fmtflags osFlags(os.flags());
329 os << std::endl <<
"Proximal Gradient Descent with Bidirectional Line Search (Type P)" << std::endl;
333 template<
typename Real>
335 std::ios_base::fmtflags osFlags(os.flags());
336 os << std::scientific << std::setprecision(6);
337 if ( state_->iter == 0 ) writeName(os);
338 if ( write_header ) writeHeader(os);
339 if ( state_->iter == 0 ) {
341 os << std::setw(6) << std::left << state_->iter;
342 os << std::setw(15) << std::left << state_->value;
343 os << std::setw(15) << std::left << state_->gnorm;
344 os << std::setw(15) << std::left <<
"---";
345 os << std::setw(15) << std::left <<
"---";
346 os << std::setw(10) << std::left << state_->nsval;
347 os << std::setw(10) << std::left << state_->nnval;
348 os << std::setw(10) << std::left << state_->ngrad;
349 os << std::setw(10) << std::left << state_->nprox;
354 os << std::setw(6) << std::left << state_->iter;
355 os << std::setw(15) << std::left << state_->value;
356 os << std::setw(15) << std::left << state_->gnorm;
357 os << std::setw(15) << std::left << state_->snorm;
358 os << std::setw(15) << std::left << state_->searchSize;
359 os << std::setw(10) << std::left << state_->nsval;
360 os << std::setw(10) << std::left << state_->nnval;
361 os << std::setw(10) << std::left << state_->ngrad;
362 os << std::setw(10) << std::left << state_->nprox;
Provides the interface to evaluate objective functions.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
ProxGradientAlgorithm(ParameterList &list)
virtual Real value(const Vector< Real > &x, Real &tol)=0
Compute value.
virtual void prox(Vector< Real > &Pv, const Vector< Real > &v, Real t, Real &tol)
Defines the linear algebra or vector space interface.
virtual void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
void run(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &sobj, Objective< Real > &nobj, std::ostream &outStream=std::cout) override
Run algorithm on unconstrained problems (Type-U). This general interface supports the use of dual opt...
void initialize(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &sobj, Objective< Real > &nobj, Vector< Real > &px, Vector< Real > &dg, std::ostream &outStream=std::cout)
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Provides an interface to check status of optimization algorithms.
void writeOutput(std::ostream &os, bool write_header=false) const override
Print iterate status.
virtual void set(const Vector &x)
Set where .
void writeHeader(std::ostream &os) const override
Print iterate header.
void writeName(std::ostream &os) const override
Print step name.
virtual void writeExitStatus(std::ostream &os) const
void initialize(const Vector< Real > &x, const Vector< Real > &g)