ROL
ROL_TypeP_TrustRegionAlgorithm_Def.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_TYPEP_TRUSTREGIONALGORITHM_DEF_HPP
45#define ROL_TYPEP_TRUSTREGIONALGORITHM_DEF_HPP
46
47#include <deque>
48
49namespace ROL {
50namespace TypeP {
51
52
53template<typename Real>
55 const Ptr<Secant<Real>> &secant) {
56 // Set status test
57 status_->reset();
58 status_->add(makePtr<StatusTest<Real>>(list));
59
60 ParameterList &trlist = list.sublist("Step").sublist("Trust Region");
61 // Trust-Region Parameters
62 state_->searchSize = trlist.get("Initial Radius", -1.0);
63 delMax_ = trlist.get("Maximum Radius", ROL_INF<Real>());
64 eta0_ = trlist.get("Step Acceptance Threshold", 0.05);
65 eta1_ = trlist.get("Radius Shrinking Threshold", 0.05);
66 eta2_ = trlist.get("Radius Growing Threshold", 0.9);
67 gamma0_ = trlist.get("Radius Shrinking Rate (Negative rho)", 0.0625);
68 gamma1_ = trlist.get("Radius Shrinking Rate (Positive rho)", 0.25);
69 gamma2_ = trlist.get("Radius Growing Rate", 2.5);
70 TRsafe_ = trlist.get("Safeguard Size", 100.0);
72 interpRad_ = trlist.get("Use Radius Interpolation", false);
73 verbosity_ = trlist.sublist("General").get("Output Level", 0);
74 initProx_ = trlist.get("Apply Prox to Initial Guess", false);
75 t0_ = list.sublist("Status Test").get("Proximal Gradient Parameter", 1.0);
76 // Nonmonotone Parameters
77 storageNM_ = trlist.get("Nonmonotone Storage Size", 0);
78 useNM_ = (storageNM_ <= 0 ? false : true);
79 // Algorithm-Specific Parameters
80 ROL::ParameterList &lmlist = trlist.sublist("TRN");
81 mu0_ = lmlist.get("Sufficient Decrease Parameter", 1e-2);
82 spexp_ = lmlist.get("Relative Tolerance Exponent", 1.0);
83 spexp_ = std::max(static_cast<Real>(1),std::min(spexp_,static_cast<Real>(2)));
84 redlim_ = lmlist.sublist("Cauchy Point").get("Maximum Number of Reduction Steps", 10);
85 explim_ = lmlist.sublist("Cauchy Point").get("Maximum Number of Expansion Steps", 10);
86 alpha_ = lmlist.sublist("Cauchy Point").get("Initial Step Size", 1.0);
87 normAlpha_ = lmlist.sublist("Cauchy Point").get("Normalize Initial Step Size", false);
88 interpf_ = lmlist.sublist("Cauchy Point").get("Reduction Rate", 0.1);
89 extrapf_ = lmlist.sublist("Cauchy Point").get("Expansion Rate", 10.0);
90 qtol_ = lmlist.sublist("Cauchy Point").get("Decrease Tolerance", 1e-8);
91 // Subsolver (general) parameters
92 lambdaMin_ = lmlist.sublist("Solver").get("Minimum Spectral Step Size", 1e-8);
93 lambdaMax_ = lmlist.sublist("Solver").get("Maximum Spectral Step Size", 1e8);
94 gamma_ = lmlist.sublist("Solver").get("Sufficient Decrease Tolerance", 1e-4);
95 maxSize_ = lmlist.sublist("Solver").get("Maximum Storage Size", 10);
96 maxit_ = lmlist.sublist("Solver").get("Iteration Limit", 25);
97 tol1_ = lmlist.sublist("Solver").get("Absolute Tolerance", 1e-4);
98 tol2_ = lmlist.sublist("Solver").get("Relative Tolerance", 1e-2);
99 // Subsolver (spectral projected gradient) parameters
100 useMin_ = lmlist.sublist("Solver").get("Use Smallest Model Iterate", true);
101 useNMSP_ = lmlist.sublist("Solver").get("Use Nonmonotone Search", false);
102 std::string ssname = lmlist.sublist("Solver").get("Subproblem Solver", "SPG");
104 // Subsolver (nonlinear conjugate gradient) parameters)
105 ncgType_ = lmlist.sublist("Solver").sublist("NCG").get("Nonlinear CG Type", 4);
106 etaNCG_ = lmlist.sublist("Solver").sublist("NCG").get("Truncation Parameter for HZ CG", 1e-2);
107 desPar_ = lmlist.sublist("Solver").sublist("NCG").get("Descent parameter for Nonlinear CG", 1.0);
108 // Inexactness Information
109 ParameterList &glist = list.sublist("General");
110 useInexact_.clear();
111 useInexact_.push_back(glist.get("Inexact Objective Function", false));
112 useInexact_.push_back(glist.get("Inexact Gradient", false));
113 useInexact_.push_back(glist.get("Inexact Hessian-Times-A-Vector", false));
114 // Trust-Region Inexactness Parameters
115 ParameterList &ilist = trlist.sublist("Inexact").sublist("Gradient");
116 scale0_ = ilist.get("Tolerance Scaling", static_cast<Real>(0.1));
117 scale1_ = ilist.get("Relative Tolerance", static_cast<Real>(2));
118 // Inexact Function Evaluation Information
119 ParameterList &vlist = trlist.sublist("Inexact").sublist("Value");
120 scale_ = vlist.get("Tolerance Scaling", static_cast<Real>(1.e-1));
121 omega_ = vlist.get("Exponent", static_cast<Real>(0.9));
122 force_ = vlist.get("Forcing Sequence Initial Value", static_cast<Real>(1.0));
123 updateIter_ = vlist.get("Forcing Sequence Update Frequency", static_cast<int>(10));
124 forceFactor_ = vlist.get("Forcing Sequence Reduction Factor", static_cast<Real>(0.1));
125 // Output Parameters
126 verbosity_ = list.sublist("General").get("Output Level",0);
128 // Secant Information
129 useSecantPrecond_ = list.sublist("General").sublist("Secant").get("Use as Preconditioner", false);
130 useSecantHessVec_ = list.sublist("General").sublist("Secant").get("Use as Hessian", false);
134 // Initialize trust region model
135 model_ = makePtr<TrustRegionModel_U<Real>>(list,secant,mode);
136 if (secant == nullPtr) {
137 esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"));
138 }
139}
140
141template<typename Real>
143 const Vector<Real> &g,
144 Real ftol,
145 Objective<Real> &sobj,
146 Objective<Real> &nobj,
147 Vector<Real> &px,
148 Vector<Real> &dg,
149 std::ostream &outStream) {
150 // Initialize data
152 nhess_ = 0;
153 // Update approximate gradient and approximate objective function.
154 if (initProx_){
155 nobj.prox(*state_->iterateVec,x,t0_, ftol); state_->nprox++;
156 x.set(*state_->iterateVec);
157 }
158 sobj.update(x,UpdateType::Initial,state_->iter);
159 state_->svalue = sobj.value(x,ftol); state_->nsval++;
160 nobj.update(x, UpdateType::Initial,state_->iter);
161 state_->nvalue = nobj.value(x,ftol); state_->nnval++;
162 state_->value = state_->svalue + state_->nvalue;
163 state_->gnorm = computeGradient(x,*state_->gradientVec,px,dg,*state_->stepVec,state_->searchSize,sobj,nobj,outStream);
164
165 state_->snorm = ROL_INF<Real>();
166 // Normalize initial CP step length
167 if (normAlpha_) alpha_ /= state_->gradientVec->norm();//change here?
168 // Compute initial trust region radius if desired.
169 if ( state_->searchSize <= static_cast<Real>(0) )
170 state_->searchSize = state_->gradientVec->norm();
171 SPiter_ = 0;
172 SPflag_ = 0;
173}
174
175template<typename Real>
177 Real &outTol,
178 Real pRed,
179 Real &fold,
180 int iter,
181 const Vector<Real> &x,
182 const Vector<Real> &xold,
183 Objective<Real> &sobj) {
184 outTol = std::sqrt(ROL_EPSILON<Real>());
185 if ( useInexact_[0] ) {
186 if (!(iter%updateIter_) && (iter!=0)) force_ *= forceFactor_;
187 const Real one(1);
188 Real eta = static_cast<Real>(0.999)*std::min(eta1_,one-eta2_);
189 outTol = scale_*std::pow(eta*std::min(pRed,force_),one/omega_);
190 if (inTol > outTol) {
191 fold = sobj.value(xold,outTol); state_->nsval++;
192 }
193 }
194 // Evaluate objective function at new iterate
196 Real fval = sobj.value(x,outTol); state_->nsval++;
197 return fval;
198}
199
200template<typename Real>
202 Vector<Real> &g,
203 Vector<Real> &px,
204 Vector<Real> &dg,
205 Vector<Real> &step,
206 Real del,
207 Objective<Real> &sobj,
208 Objective<Real> &nobj,
209 std::ostream &outStream) const {
210 Real gnorm(0);
211 if ( useInexact_[1] ) {
212 const Real one(1);
213 Real gtol1 = scale0_*del;
214 Real gtol0 = gtol1 + one;
215 while ( gtol0 > gtol1 ) {
216 sobj.gradient(g,x,gtol1); state_->ngrad++;
217 dg.set(g.dual());
218 pgstep(px, step, nobj, x, dg, t0_, gtol1); // change gtol? one or ocScale?
219 gnorm = step.norm() / t0_;
220 gtol0 = gtol1;
221 gtol1 = scale0_*std::min(gnorm,del);
222 }
223 }
224 else {
225 Real gtol = std::sqrt(ROL_EPSILON<Real>());
226 sobj.gradient(g,x,gtol); state_->ngrad++;
227 dg.set(g.dual());
228 pgstep(px, step, nobj, x, dg, t0_, gtol);
229 gnorm = step.norm() / t0_;
230 }
231 return gnorm;
232}
233
234template<typename Real>
236 const Vector<Real> &g,
237 Objective<Real> &sobj,
238 Objective<Real> &nobj,
239 std::ostream &outStream ) {
240 const Real zero(0), one(1);
241 //Real tol0 = std::sqrt(ROL_EPSILON<Real>());
242 Real inTol = static_cast<Real>(0.1)*ROL_OVERFLOW<Real>(), outTol(inTol);
243 Real strial(0), ntrial(0), smodel(0), Ftrial(0), pRed(0), rho(1);
244 // Initialize trust-region data
245 std::vector<std::string> output;
246 Ptr<Vector<Real>> gmod = g.clone();
247 Ptr<Vector<Real>> px = x.clone();
248 Ptr<Vector<Real>> dg = x.clone();
249 // Initialize Algorithm
250 initialize(x,g,inTol,sobj,nobj, *px, *dg, outStream);
251 // Initialize storage vectors
252 Ptr<Vector<Real>> pwa1 = x.clone(), pwa2 = x.clone();
253 Ptr<Vector<Real>> pwa3 = x.clone(), pwa4 = x.clone();
254 Ptr<Vector<Real>> pwa5 = x.clone(), pwa6 = x.clone();
255 Ptr<Vector<Real>> pwa7 = x.clone();
256 Ptr<Vector<Real>> dwa1 = g.clone(), dwa2 = g.clone();
257 // Initialize nonmonotone data
258 Real rhoNM(0), sigmac(0), sigmar(0);
259 Real fr(state_->value), fc(state_->value), fmin(state_->value);
260 TRUtils::ETRFlag TRflagNM;
261 int L(0);
262 // Output
263 if (verbosity_ > 0) writeOutput(outStream,true);
264
265 while (status_->check(*state_)) {
266 // Build trust-region model
267 model_->setData(sobj,*state_->iterateVec,*state_->gradientVec);
268
269 /**** SOLVE TRUST-REGION SUBPROBLEM ****/
270 //q = state_->svalue + state_->nvalue;//q is no longer used
271 gmod->set(*state_->gradientVec);
272 smodel = state_->svalue;
273 ntrial = state_->nvalue;
274 switch (algSelect_) {
276 default:
277 // Compute Cauchy point (TRON notation: x = x[1])
278 dcauchy(*state_->stepVec,alpha_, smodel, ntrial,
279 *state_->iterateVec, *dg, state_->searchSize,
280 *model_, nobj, *px, *dwa1, *dwa2, outStream); // Solve 1D optimization problem for alpha
281 x.plus(*state_->stepVec); // Set x = x[0] + alpha*g
282 // Model gradient at s = x[1] - x[0]
283 gmod->plus(*dwa1); // hessVec from Cauchy point computation
284
285 // Apply SPG starting from the Cauchy point->change input
286 dspg(x,smodel,ntrial,*gmod,*state_->iterateVec,state_->searchSize,
287 *model_,nobj,*pwa1,*pwa2,*pwa3,*pwa4,*pwa5,*pwa6,*pwa7,*dwa1,
288 outStream);
289 pRed = state_->value - (smodel+ntrial);
290 break;
292 dspg2(x,smodel, ntrial, pRed, *gmod, *state_->iterateVec,
293 state_->searchSize, *model_, nobj,
294 *pwa1, *pwa2, *px, *dwa1, outStream);
295 break;
297 dncg(x,smodel,ntrial,*gmod,*state_->iterateVec,state_->searchSize,
298 *model_,nobj,*pwa1,*pwa2,*pwa3,*pwa4,*pwa5,*pwa6,*dwa1,
299 outStream);
300 pRed = state_->value - (smodel+ntrial);
301 break;
302 }
303
304 // Update storage and compute predicted reduction
305 //pRed = -q; // now updated in dcauchy/dspg
306 state_->stepVec->set(x); state_->stepVec->axpy(-one,*state_->iterateVec);
307 state_->snorm = state_->stepVec->norm();
308
309 // Compute trial objective value
310 strial = computeValue(inTol,outTol,pRed,state_->svalue,state_->iter,x,*state_->iterateVec,sobj);
311 Ftrial = strial + ntrial;
312
313 // Compute ratio of actual and predicted reduction
315 TRUtils::analyzeRatio<Real>(rho,TRflag_,state_->value,Ftrial,pRed,eps_,outStream,verbosity_>1);
316 if (useNM_) {
317 TRUtils::analyzeRatio<Real>(rhoNM,TRflagNM,fr,Ftrial,pRed+sigmar,eps_,outStream,verbosity_>1);
318 TRflag_ = (rho < rhoNM ? TRflagNM : TRflag_);
319 rho = (rho < rhoNM ? rhoNM : rho );
320 }
321
322 // Update algorithm state
323 state_->iter++;
324 // Accept/reject step and update trust region radius
325 if ((rho < eta0_ && TRflag_ == TRUtils::SUCCESS) || (TRflag_ >= 2)) { // Step Rejected
326 x.set(*state_->iterateVec);
327 sobj.update(x,UpdateType::Revert,state_->iter);
328 nobj.update(x,UpdateType::Revert,state_->iter);
329 if (interpRad_ && (rho < zero && TRflag_ != TRUtils::TRNAN)) {
330 // Negative reduction, interpolate to find new trust-region radius
331 state_->searchSize = TRUtils::interpolateRadius<Real>(*state_->gradientVec,*state_->stepVec,
332 state_->snorm,pRed,state_->value,Ftrial,state_->searchSize,gamma0_,gamma1_,eta2_,
333 outStream,verbosity_>1);
334 }
335 else { // Shrink trust-region radius
336 state_->searchSize = gamma1_*std::min(state_->snorm,state_->searchSize);
337 }
338 }
339 else if ((rho >= eta0_ && TRflag_ != TRUtils::NPOSPREDNEG)
340 || (TRflag_ == TRUtils::POSPREDNEG)) { // Step Accepted
341 state_->value = Ftrial;
342 state_->svalue = strial;
343 state_->nvalue = ntrial;
344 sobj.update(x,UpdateType::Accept,state_->iter);
345 nobj.update(x,UpdateType::Accept,state_->iter);
346 inTol = outTol;
347 if (useNM_) {
348 sigmac += pRed; sigmar += pRed;
349 if (Ftrial < fmin) { fmin = Ftrial; fc = fmin; sigmac = zero; L = 0; }
350 else {
351 L++;
352 if (Ftrial > fc) { fc = Ftrial; sigmac = zero; }
353 if (L == storageNM_) { fr = fc; sigmar = sigmac; }
354 }
355 }
356 // Increase trust-region radius
357 if (rho >= eta2_) state_->searchSize = std::min(gamma2_*state_->searchSize, delMax_);
358 // Compute gradient at new iterate
359 dwa1->set(*state_->gradientVec);
360 state_->gnorm = computeGradient(x,*state_->gradientVec,*px,*dg,*pwa1,state_->searchSize,sobj,nobj,outStream);
361 state_->iterateVec->set(x);
362 // Update secant information in trust-region model
363 model_->update(x,*state_->stepVec,*dwa1,*state_->gradientVec,
364 state_->snorm,state_->iter);
365 }
366
367 // Update Output
368 if (verbosity_ > 0) writeOutput(outStream,writeHeader_);
369 }
371}
372
373template<typename Real>
375 Real &alpha,
376 Real &sval,
377 Real &nval,
378 const Vector<Real> &x,
379 const Vector<Real> &g,
380 const Real del,
382 Objective<Real> &nobj,
383 Vector<Real> &px,
384 Vector<Real> &dwa,
385 Vector<Real> &dwa1,
386 std::ostream &outStream) {
387 const Real half(0.5), sold(sval), nold(nval);
388 Real tol = std::sqrt(ROL_EPSILON<Real>());
389 bool interp = false;
390 Real gs(0), snorm(0), Qk(0), pRed(0);
391 // Compute s = P(x[0] - alpha g[0]) - x[0]
392 pgstep(px, s, nobj, x, g, alpha, tol);
393 snorm = s.norm();
394 if (snorm > del) {
395 interp = true;
396 }
397 else {
398 model.hessVec(dwa,s,x,tol); nhess_++;
399 nobj.update(px, UpdateType::Trial);
400 nval = nobj.value(px, tol); state_->nnval++;
401 gs = s.dot(g);
402 sval = sold + gs + half * s.apply(dwa);
403 pRed = (sold + nold) - (sval + nval);
404 Qk = gs + nval - nold;
405 interp = (pRed < -mu0_*Qk);
406 }
407 // Either increase or decrease alpha to find approximate Cauchy point
408 int cnt = 0;
409 if (interp) {//decrease loop
410 bool search = true;
411 while (search) {
412 alpha *= interpf_;
413 pgstep(px, s, nobj, x, g, alpha, tol);
414 snorm = s.norm();
415 if (snorm <= del) {
416 model.hessVec(dwa,s,x,tol); nhess_++;
417 nobj.update(px, UpdateType::Trial);
418 nval = nobj.value(px, tol); state_->nnval++;
419 gs = s.dot(g);
420 sval = sold + gs + half * s.apply(dwa);
421 pRed = (sold + nold) - (sval + nval);
422 Qk = gs + nval - nold;
423 search = ((pRed < -mu0_*Qk) && (cnt < redlim_)) ;
424 }
425 cnt++;
426 }
427 }
428 else {
429 bool search = true;
430 Real alphas = alpha;
431 Real mvals = pRed;
432 Real svals = sval;
433 dwa1.set(dwa);
434 while (search) {
435 alpha *= extrapf_;
436 pgstep(px, s, nobj, x, g, alpha, tol);
437 snorm = s.norm();
438 if (snorm <= del && cnt < explim_){// && mnew < mold + mu0_*Qk) {
439 model.hessVec(dwa,s,x,tol); nhess_++;
440 nobj.update(px, UpdateType::Trial);
441 nval = nobj.value(px, tol); state_->nnval++;
442 gs = s.dot(g);
443 sval = sold + gs + half * s.apply(dwa);
444 pRed = (sold + nold) - (sval + nval);
445 Qk = gs + nval - nold;
446 if (pRed >= -mu0_*Qk && std::abs(pRed-mvals) > qtol_*std::abs(mvals)) {
447 dwa1.set(dwa);
448 alphas = alpha;
449 mvals = pRed;
450 svals = sval;
451 search = true;
452 }
453 else {
454 dwa.set(dwa1);
455 pRed = mvals;
456 sval = svals;
457 search = false;
458 }
459 }
460 else {
461 search = false;
462 }
463 cnt++;
464 }
465 alpha = alphas;
466 pgstep(px, s, nobj, x, g, alpha, tol);
467 snorm = s.norm();
468 }
469 if (verbosity_ > 1) {
470 outStream << " Cauchy point" << std::endl;
471 outStream << " Step length (alpha): " << alpha << std::endl;
472 outStream << " Step length (alpha*g): " << snorm << std::endl;
473 outStream << " Model decrease (pRed): " << pRed << std::endl;
474 if (!interp)
475 outStream << " Number of extrapolation steps: " << cnt << std::endl;
476 }
477 return snorm;
478}
479
480template<typename Real>
482 Real &sval,
483 Real &nval,
484 Real &pRed,
485 Vector<Real> &gmod,
486 const Vector<Real> &x,
487 Real del,
489 Objective<Real> &nobj,
490 Vector<Real> &pwa,
491 Vector<Real> &pwa1,
492 Vector<Real> &pwa2,
493 Vector<Real> &dwa,
494 std::ostream &outStream) {
495 // Use SPG to approximately solve TR subproblem:
496 // min 1/2 <H(y-x), (y-x)> + <g, (y-x)> subject to y\in C, ||y|| \le del
497 //
498 // Inpute:
499 // y = Primal vector
500 // x = Current iterate
501 // g = Current gradient
502 const Real half(0.5), one(1), safeguard(1e2*ROL_EPSILON<Real>());
503 const Real mprev(sval+nval);
504 Real tol(std::sqrt(ROL_EPSILON<Real>()));
505 Real coeff(1), alpha(1), alphaMax(1), lambda(1), lambdaTmp(1);
506 Real gs(0), ss(0), gnorm(0), s0s0(0), ss0(0), sHs(0), snorm(0), nold(nval);
507 pwa1.zero();
508
509 // Set y = x
510 y.set(x);
511
512 // Compute initial step
513 coeff = one / gmod.norm();
514 lambda = std::max(lambdaMin_,std::min(coeff,lambdaMax_));
515 pgstep(pwa2, pwa, nobj, y, gmod.dual(), lambda, tol);
516 gs = gmod.apply(pwa); // gs = <step, model gradient>
517 ss = pwa.dot(pwa); // Norm squared of step
518 snorm = std::sqrt(ss); // norm(step)
519 gnorm = snorm / lambda; // norm(step) / lambda
520
521 // Compute initial projected gradient norm
522 const Real gtol = std::min(tol1_,tol2_*gnorm);
523
524 if (verbosity_ > 1)
525 outStream << " Spectral Projected Gradient" << std::endl;
526
527 SPiter_ = 0;
528 while (SPiter_ < maxit_) {
529 SPiter_++;
530
531 // Evaluate model Hessian
532 model.hessVec(dwa,pwa,x,tol); nhess_++; // dwa = H step
533 sHs = dwa.apply(pwa); // sHs = <step, H step>
534
535 // Evaluate nonsmooth term
536 nobj.update(pwa2,UpdateType::Trial);
537 nval = nobj.value(pwa2,tol); state_->nnval++;
538
539 // Perform line search
540 alphaMax = one;
541 if (snorm >= del-safeguard) { // Trust-region constraint is violated
542 ss0 = pwa1.dot(pwa);
543 alphaMax = std::min(one, (-ss0 + std::sqrt(ss0*ss0 - ss*(s0s0-del*del)))/ss);
544 }
545 alpha = (sHs <= safeguard) ? alphaMax : std::min(alphaMax, -(gs + nval - nold)/sHs);
546
547 // Update model quantities
548 if (alpha == one) {
549 y.set(pwa2);
550 sval += gs + half * sHs;
551 gmod.plus(dwa);
552 }
553 else {
554 y.axpy(alpha,pwa); // New iterate
556 nval = nobj.value(y, tol); state_->nnval++;
557 sval += alpha * (gs + half * alpha * sHs);
558 gmod.axpy(alpha,dwa);
559 }
560 nold = nval;
561 pRed = mprev - (sval+nval);
562
563 // Check trust-region constraint violation
564 pwa1.set(y); pwa1.axpy(-one,x);
565 s0s0 = pwa1.dot(pwa1);
566 snorm = std::sqrt(s0s0);
567
568 if (verbosity_ > 1) {
569 outStream << std::endl;
570 outStream << " Iterate: " << SPiter_ << std::endl;
571 outStream << " Spectral step length (lambda): " << lambda << std::endl;
572 outStream << " Step length (alpha): " << alpha << std::endl;
573 outStream << " Model decrease (pRed): " << pRed << std::endl;
574 outStream << " Optimality criterion: " << gnorm << std::endl;
575 outStream << " Step norm: " << snorm << std::endl;
576 outStream << std::endl;
577 }
578
579 if (snorm >= del - safeguard) { SPflag_ = 2; break; }
580
581 // Compute new spectral step
582 lambdaTmp = (sHs <= safeguard) ? one/gmod.norm() : ss/sHs;
583 lambda = std::max(lambdaMin_,std::min(lambdaTmp,lambdaMax_));
584
585 pgstep(pwa2, pwa, nobj, y, gmod.dual(), alpha, tol); // pass pwa by reference? *pwa?
586 gs = gmod.apply(pwa);
587 ss = pwa.dot(pwa);
588 gnorm = std::sqrt(ss) / lambda;
589
590 if (gnorm <= gtol) { SPflag_ = 0; break; }
591 }
592 SPflag_ = (SPiter_==maxit_) ? 1 : SPflag_;
593}
594
595template<typename Real>
597 Real &sval,
598 Real &nval,
599 Vector<Real> &gmod,
600 const Vector<Real> &x,
601 Real del,
603 Objective<Real> &nobj,
604 Vector<Real> &ymin,
605 Vector<Real> &pwa,
606 Vector<Real> &pwa1,
607 Vector<Real> &pwa2,
608 Vector<Real> &pwa3,
609 Vector<Real> &pwa4,
610 Vector<Real> &pwa5,
611 Vector<Real> &dwa,
612 std::ostream &outStream) {
613 // Use SPG to approximately solve TR subproblem:
614 // min 1/2 <H(y-x), (y-x)> + <g, (y-x)> + phi(y) subject to ||y|| \le del
615 //
616 // Inpute:
617 // y = Cauchy step
618 // x = Current iterate
619 // g = Current gradient
620 const Real half(0.5), one(1);
621 const Real mval(sval+nval);
622 Real tol(std::sqrt(ROL_EPSILON<Real>()));
623 Real mcomp(0), mval_min(0), sval_min(0), nval_min(0);
624 Real alpha(1), coeff(1), lambda(1), lambdaTmp(1);
625 Real snew(sval), nnew(nval), mnew(mval);
626 Real sold(sval), nold(nval), mold(mval);
627 Real sHs(0), ss(0), gs(0), Qk(0), gnorm(0);
628 std::deque<Real> mqueue; mqueue.push_back(mold);
629
630 if (useNMSP_ && useMin_) {
631 mval_min = mval; sval_min = sval; nval_min = nval; ymin.set(y);
632 }
633
634 // Compute initial proximal gradient norm
635 pwa1.set(gmod.dual());
636 pwa.set(y); pwa.axpy(-t0_,pwa1);
637 dprox(pwa,x,t0_,del,nobj,pwa2,pwa3,pwa4,pwa5,outStream);
638 pwa.axpy(-one,y);
639 gnorm = pwa.norm() / t0_;
640 const Real gtol = std::min(tol1_,tol2_*gnorm);
641
642 // Compute initial spectral step size
643 coeff = one / gmod.norm();
644 lambda = std::max(lambdaMin_,std::min(coeff,lambdaMax_));
645
646 if (verbosity_ > 1)
647 outStream << " Spectral Projected Gradient" << std::endl;
648
649 SPiter_ = 0;
650 while (SPiter_ < maxit_) {
651 SPiter_++;
652
653 // Compuate SPG step
654 alpha = one;
655 pwa.set(y); pwa.axpy(-lambda,pwa1); // pwa = y - lambda gmod.dual()
656 dprox(pwa,x,lambda,del,nobj,pwa2,pwa3,pwa4,pwa5,outStream); // pwa = P(y - lambda gmod.dual())
657 pwa.axpy(-one,y); // pwa = P(y - lambda gmod.dual()) - y = step
658 pwa2.set(y); pwa2.plus(pwa); // pwa2 = P(y - lambda gmod.dual())
659 ss = pwa.dot(pwa); // Norm squared of step
660
661 // Evaluate model Hessian
662 model.hessVec(dwa,pwa,x,tol); nhess_++; // dwa = H step
663 nobj.update(pwa2, UpdateType::Trial);
664 nnew = nobj.value(pwa2, tol); state_->nnval++;
665 sHs = dwa.apply(pwa); // sHs = <step, H step>
666 gs = gmod.apply(pwa); // gs = <step, model gradient>
667 snew = half * sHs + gs + sold;
668 mnew = snew + nnew;
669 Qk = gs + nnew - nold;
670
671 // Perform line search
672 mcomp = useNMSP_ ? *std::max_element(mqueue.begin(),mqueue.end()) : mold;
673 while( mnew > mcomp + mu0_*Qk) {
674 alpha *= interpf_;
675 pwa2.set(y); pwa2.axpy(alpha,pwa);
676 nobj.update(pwa2, UpdateType::Trial);
677 nnew = nobj.value(pwa2, tol); state_->nnval++;
678 snew = half * alpha * alpha * sHs + alpha * gs + sold;
679 mnew = nnew + snew;
680 Qk = alpha * gs + nnew - nold;
681 }
682
683 // Update model quantities
684 y.set(pwa2);
685 sold = snew;
686 nold = nnew;
687 mold = mnew;
688 gmod.axpy(alpha,dwa); // Update model gradient
689 nobj.update(y, UpdateType::Accept);
690
691 // Update nonmonotone line search information
692 if (useNMSP_) {
693 if (static_cast<int>(mqueue.size())==maxSize_) mqueue.pop_front();
694 mqueue.push_back(sval+nval);
695 if (useMin_ && mval <= mval_min) {
696 mval_min = mval; sval_min = sval; nval_min = nval; ymin.set(y);
697 }
698 }
699
700 // Compute projected gradient norm
701 pwa1.set(gmod.dual());
702 pwa.set(y); pwa.axpy(-t0_,pwa1);
703 dprox(pwa,x,t0_,del,nobj,pwa2,pwa3,pwa4,pwa5,outStream);
704 pwa.axpy(-one,y);
705 gnorm = pwa.norm() / t0_;
706
707 if (verbosity_ > 1) {
708 outStream << std::endl;
709 outStream << " Iterate: " << SPiter_ << std::endl;
710 outStream << " Spectral step length (lambda): " << lambda << std::endl;
711 outStream << " Step length (alpha): " << alpha << std::endl;
712 outStream << " Model decrease (pRed): " << mval-mold << std::endl;
713 outStream << " Optimality criterion: " << gnorm << std::endl;
714 outStream << std::endl;
715 }
716 if (gnorm < gtol) break;
717
718 // Compute new spectral step
719 lambdaTmp = (sHs == 0 ? coeff : ss / sHs);
720 lambda = std::max(lambdaMin_, std::min(lambdaTmp, lambdaMax_));
721 }
722 if (useNMSP_ && useMin_) {
723 sval = sval_min; nval = nval_min; y.set(ymin);
724 }
725 else {
726 sval = sold; nval = nold;
727 }
728 SPflag_ = (SPiter_==maxit_) ? 1 : 0;
729}
730
731template<typename Real>
733 const Vector<Real> &x0,
734 Real t,
735 Real del,
736 Objective<Real> &nobj,
737 Vector<Real> &y0,
738 Vector<Real> &y1,
739 Vector<Real> &yc,
740 Vector<Real> &pwa,
741 std::ostream &outStream) const {
742 // Solve ||P(t*x0 + (1-t)*(x-x0))-x0|| = del using Brent's method
743 const Real zero(0), half(0.5), one(1), two(2), three(3);
744 const Real eps(ROL_EPSILON<Real>()), tol0(1e1*eps), fudge(1.0-1e-2*sqrt(eps));
745 Real f0(0), f1(0), fc(0), t0(0), t1(1), tc(0), d1(1), d2(1), tol(1);
746 Real p(0), q(0), r(0), s(0), m(0);
747 int cnt(state_->nprox);
748 nobj.prox(y1, x, t, tol); state_->nprox++;
749 pwa.set(y1); pwa.axpy(-one,x0);
750 f1 = pwa.norm();
751 if (f1 <= del) {
752 x.set(y1);
753 return;
754 }
755 y0.set(x0);
756 tc = t0; fc = f0; yc.set(y0);
757 d1 = t1-t0; d2 = d1;
758 int code = 0;
759 while (true) {
760 if (std::abs(fc-del) < std::abs(f1-del)) {
761 t0 = t1; t1 = tc; tc = t0;
762 f0 = f1; f1 = fc; fc = f0;
763 y0.set(y1); y1.set(yc); yc.set(y0);
764 }
765 tol = two*eps*std::abs(t1) + half*tol0;
766 m = half*(tc - t1);
767 if (std::abs(m) <= tol) { code = 1; break; }
768 if ((f1 >= fudge*del && f1 <= del)) break;
769 if (std::abs(d1) < tol || std::abs(f0-del) <= std::abs(f1-del)) {
770 d1 = m; d2 = d1;
771 }
772 else {
773 s = (f1-del)/(f0-del);
774 if (t0 == tc) {
775 p = two*m*s;
776 q = one-s;
777 }
778 else {
779 q = (f0-del)/(fc-del);
780 r = (f1-del)/(fc-del);
781 p = s*(two*m*q*(q-r)-(t1-t0)*(r-one));
782 q = (q-one)*(r-one)*(s-one);
783 }
784 if (p > zero) q = -q;
785 else p = -p;
786 s = d1;
787 d1 = d2;
788 if (two*p < three*m*q-std::abs(tol*q) && p < std::abs(half*s*q)) {
789 d2 = p/q;
790 }
791 else {
792 d1 = m; d2 = d1;
793 }
794 }
795 t0 = t1; f0 = f1; y0.set(y1);
796 if (std::abs(d2) > tol) t1 += d2;
797 else if (m > zero) t1 += tol;
798 else t1 -= tol;
799 pwa.set(x); pwa.scale(t1); pwa.axpy(one-t1,x0);
800 nobj.prox(y1, pwa, t1*t, tol); state_->nprox++;
801 pwa.set(y1); pwa.axpy(-one,x0);
802 f1 = pwa.norm();
803 if ((f1 > del && fc > del) || (f1 <= del && fc <= del)) {
804 tc = t0; fc = f0; yc.set(y0);
805 d1 = t1-t0; d2 = d1;
806 }
807 }
808 if (code==1 && f1>del) x.set(yc);
809 else x.set(y1);
810 if (verbosity_ > 1) {
811 outStream << std::endl;
812 outStream << " Trust-Region Subproblem Proximity Operator" << std::endl;
813 outStream << " Number of proxes: " << state_->nprox-cnt << std::endl;
814 if (code == 1 && f1 > del) {
815 outStream << " Transformed Multiplier: " << tc << std::endl;
816 outStream << " Dual Residual: " << fc-del << std::endl;
817 }
818 else {
819 outStream << " Transformed Multiplier: " << t1 << std::endl;
820 outStream << " Dual Residual: " << f1-del << std::endl;
821 }
822 outStream << " Exit Code: " << code << std::endl;
823 outStream << std::endl;
824 }
825}
826
827// NCG Subsolver
828template<typename Real>
830 Real &sval,
831 Real &nval,
832 Vector<Real> &gmod,
833 const Vector<Real> &x,
834 Real del,
836 Objective<Real> &nobj,
837 Vector<Real> &s,
838 Vector<Real> &pwa1,
839 Vector<Real> &pwa2,
840 Vector<Real> &pwa3,
841 Vector<Real> &pwa4,
842 Vector<Real> &pwa5,
843 Vector<Real> &dwa,
844 std::ostream &outStream) {
845 // Use NCG to approximately solve TR subproblem:
846 // min 1/2 <H(y-x), (y-x)> + <g, (y-x)> + phi(y) subject to ||y-x|| \le del
847 //
848 // Inpute:
849 // y = computed iterate
850 // sval = smooth model value
851 // nval = nonsmooth value
852 // gmod = current gradient
853 // x = current iterate
854 // del = trust region radius
855 // model = trust region model
856 // nobj = nonsmooth objective function
857 // s = the current step
858 // pwa1 = the SPG iterate
859 // pwa2 = the "negative gradient"
860 // pwa3 = y - x
861 // pwa4 = the previous "negative gradient"
862 // pwa5 = temporary storage
863 // dwa = the Hessian applied to the step
864 const Real zero(0), half(0.5), one(1), two(2);
865 Real tol(std::sqrt(ROL_EPSILON<Real>())), safeguard(tol);
866 Real mold(sval+nval), nold(nval);
867 Real snorm(0), snorm0(0), gnorm(0), gnorm0(0), gnorm2(0);
868 Real alpha(1), beta(1), lambdaTmp(1), lambda(1), eta(etaNCG_), gamma(1), gammaMax(1);
869 Real sy(0), gg(0), sHs(0), gs(0), ds(0), ss(0);
870 bool reset(true);
871
872 // Set y = x
873 y.set(x);
874 pwa3.zero(); // Initially y - x = 0
875
876 // Compute initial spectral step length
877 lambdaTmp = t0_ / gmod.norm();
878 lambda = std::max(lambdaMin_,std::min(lambdaTmp,lambdaMax_));
879
880 // Compute Cauchy point via SPG
881 pgstep(pwa1, pwa2, nobj, y, gmod.dual(), lambda, tol); // pwa1 = prox(x-lambda g), pwa2 = pwa1 - x
882 pwa2.scale(one/lambda); // pwa2 = (pwa1 - x) / lambda (for smooth: pwa2 = negative gradient)
883 s.set(pwa2); // s = (pwa1 - x) / lambda
884 gs = gmod.apply(s); // gs = <g, prox(x-lambda g)-x> / lambda
885 gnorm = s.norm(); // hk = norm(prox(x-lambda g)-x) / lambda
886 snorm = lambda * gnorm; // snorm = norm(prox(x-lambda g)-x)
887 nobj.update(pwa1,UpdateType::Trial);
888 nval = nobj.value(pwa1, tol); state_->nnval++;
889
890 // Compute initial projected gradient norm
891 const Real gtol = std::min(tol1_,tol2_*gnorm);
892
893 if (verbosity_ > 1)
894 outStream << " Nonlinear Conjugate Gradient" << std::endl;
895
896 SPiter_ = 0;
897 SPflag_ = 1;
898 while (SPiter_ < maxit_) {
899 SPiter_++;
900
901 gammaMax = one;
902 ss = s.dot(s);
903 if (snorm >= (one - safeguard)*del){
904 ds = s.dot(pwa3);
905 gammaMax = std::min(one, (-ds + std::sqrt(ds*ds + ss*(del*del - snorm0*snorm0)))/(lambda * ss));
906 }
907
908 // Compute alpha as the minimizer of an upper quadratic model
909 model.hessVec(dwa,s,x,tol); nhess_++; // dwa = H step
910 sHs = dwa.apply(s); // sHs = <step, H step>
911 gamma = (sHs <= safeguard) ? gammaMax : std::min(gammaMax, -(lambda * gs + nval - nold)/(lambda * lambda * sHs));
912 alpha = gamma * lambda;
913
914 // Update quantities to evaluate quadratic model value and gradient
915 y.axpy(alpha, s);
916 gmod.axpy(alpha, dwa); // need dual here?
917 sval += alpha*gs + half*alpha*alpha*sHs;
919 nold = nobj.value(y,tol); state_->nnval++;
920
921 // Check step size
922 pwa3.set(y); pwa3.axpy(-one,x);
923 snorm0 = pwa3.norm();
924 if (snorm0 >= (one-safeguard)*del) { SPflag_ = 2; break; }
925
926 // Update spectral step length
927 lambdaTmp = (sHs <= safeguard) ? t0_/gmod.norm() : ss/sHs;
928 lambda = std::max(lambdaMin_, std::min(lambdaMax_, lambdaTmp));
929
930 // Compute SPG direction
931 pwa4.set(pwa2); // store previous "negative gradient"
932 pgstep(pwa1, pwa2, nobj, y, gmod.dual(), lambda, tol); // pwa1 = prox(x-lambda g), pwa2 = pwa1 - x
933 pwa2.scale(one/lambda); // pwa2 = (pwa1 - x) / lambda (for smooth: pwa2 = negative gradient)
934 gnorm0 = gnorm;
935 gnorm = pwa2.norm();
936
937 // Check stopping condition
938 if (gnorm <= gtol) { SPflag_ = 0; break; }
939
940 gnorm2 = gnorm * gnorm;
941 switch (ncgType_) {
942 case 0: // Fletcher-Reeves
943 beta = gnorm2/(gnorm0 * gnorm0);
944 break;
945 default:
946 case 1: // Polyak-Ribiere+
947 pwa5.set(pwa4); pwa5.axpy(-one,pwa2);
948 beta = std::max(zero, -pwa5.dot(pwa2)/(gnorm0*gnorm0));
949 break;
950 case 2: // Hager-Zhang
951 pwa5.set(pwa4); pwa5.axpy(-one,pwa2);
952 sy = s.dot(pwa5);
953 gg = pwa2.dot(pwa4);
954 eta = -one/(s.norm()*std::min(etaNCG_, gnorm0));
955 beta = std::max(eta, (gnorm2-gg-two*pwa2.dot(s)*(gnorm2-two*gg+(gnorm0*gnorm0))/sy)/sy);
956 break;
957 case 3: // Hestenes-Stiefel+
958 pwa5.set(pwa4); pwa5.axpy(-one,pwa2);
959 beta = std::max(zero, -pwa2.dot(pwa5)/s.dot(pwa5));
960 break;
961 case 4: // Dai-Yuan+
962 pwa5.set(pwa4); pwa5.axpy(-one,pwa2);
963 beta = std::max(zero, gnorm2/s.dot(pwa5));
964 break;
965 case 5: // Fletcher-Reeves-Polyak-Ribiere
966 pwa5.set(pwa4); pwa5.axpy(-one,pwa2);
967 beta = std::max(-gnorm2, std::min(gnorm2, -pwa5.dot(pwa2)))/(gnorm0*gnorm0);
968 break;
969 case 6: //Dai-Yuan-Hestenes-Stiefles
970 pwa5.set(pwa4); pwa5.axpy(-one,pwa2);
971 beta = std::max(zero, std::min(-pwa2.dot(pwa5), gnorm2)/s.dot(pwa5));
972 break;
973 }
974
975 reset = true;
976 if (beta != zero && beta < ROL_INF<Real>()){
977 pwa5.set(pwa2); // pwa5 = pwa2 (SPG step)
978 pwa5.axpy(beta, s); // pwa5 = pwa2 + beta*s
979 pwa4.set(y); // pwa4 = y
980 pwa4.axpy(lambda,pwa5); // pwa4 = y + lambda*pwa5
981 nobj.update(pwa4,UpdateType::Trial);
982 nval = nobj.value(pwa4,tol); state_->nnval++;
983 gs = gmod.apply(pwa5);
984 if (lambda * gs + nval - nold <= -(one - desPar_)*gnorm2*lambda){
985 pwa4.axpy(-one,x);
986 s.set(pwa5);
987 reset = false;
988 }
989 }
990 if (reset){ // Reset because either beta=0 or step does not produce descent
991 pwa4.set(pwa1); pwa4.axpy(-one,x);
992 s.set(pwa2);
993 nobj.update(pwa1,UpdateType::Trial);
994 nval = nobj.value(pwa1,tol); state_->nnval++;
995 gs = gmod.apply(s);
996 beta = zero;
997 }
998 snorm = pwa4.norm();
999
1000 if (verbosity_ > 1) {
1001 outStream << std::endl;
1002 outStream << " Iterate: " << SPiter_ << std::endl;
1003 outStream << " Spectral step length (lambda): " << lambda << std::endl;
1004 outStream << " Step length (alpha): " << alpha << std::endl;
1005 outStream << " NCG parameter (beta): " << beta << std::endl;
1006 outStream << " Model decrease (pRed): " << mold-(sval+nold) << std::endl;
1007 outStream << " Step size: " << snorm0 << std::endl;
1008 outStream << " Optimality criterion: " << gnorm << std::endl;
1009 outStream << " Optimality tolerance: " << gtol << std::endl;
1010 outStream << std::endl;
1011 }
1012 }
1013 nval = nold;
1014}
1015
1016template<typename Real>
1017void TrustRegionAlgorithm<Real>::writeHeader( std::ostream& os ) const {
1018 std::stringstream hist;
1019 if (verbosity_ > 1) {
1020 hist << std::string(114,'-') << std::endl;
1021 switch (algSelect_) {
1022 default:
1023 case TRUSTREGION_P_SPG: hist << " SPG "; break;
1024 case TRUSTREGION_P_SPG2: hist << " Simplified SPG "; break;
1025 case TRUSTREGION_P_NCG: hist << " NCG "; break;
1026 }
1027 hist << "trust-region method status output definitions" << std::endl << std::endl;
1028 hist << " iter - Number of iterates (steps taken)" << std::endl;
1029 hist << " value - Objective function value" << std::endl;
1030 hist << " gnorm - Norm of the gradient" << std::endl;
1031 hist << " snorm - Norm of the step (update to optimization vector)" << std::endl;
1032 hist << " delta - Trust-Region radius" << std::endl;
1033 hist << " #sval - Number of times the smooth objective function was evaluated" << std::endl;
1034 hist << " #nval - Number of times the nonsmooth objective function was evaluated" << std::endl;
1035 hist << " #grad - Number of times the gradient was computed" << std::endl;
1036 hist << " #hess - Number of times the Hessian was applied" << std::endl;
1037 hist << " #prox - Number of times the proximal operator was computed" << std::endl;
1038 hist << std::endl;
1039 hist << " tr_flag - Trust-Region flag" << std::endl;
1040 for( int flag = TRUtils::SUCCESS; flag != TRUtils::UNDEFINED; ++flag ) {
1041 hist << " " << NumberToString(flag) << " - "
1042 << TRUtils::ETRFlagToString(static_cast<TRUtils::ETRFlag>(flag)) << std::endl;
1043 }
1044 hist << std::endl;
1045 hist << " iterSP - Number of Spectral Projected Gradient iterations" << std::endl << std::endl;
1046 hist << " flagSP - Trust-Region Spectral Projected Gradient flag" << std::endl;
1047 hist << " 0 - Converged" << std::endl;
1048 hist << " 1 - Iteration Limit Exceeded" << std::endl;
1049 hist << std::string(114,'-') << std::endl;
1050 }
1051 hist << " ";
1052 hist << std::setw(6) << std::left << "iter";
1053 hist << std::setw(15) << std::left << "value";
1054 hist << std::setw(15) << std::left << "gnorm";
1055 hist << std::setw(15) << std::left << "snorm";
1056 hist << std::setw(15) << std::left << "delta";
1057 hist << std::setw(10) << std::left << "#sval";
1058 hist << std::setw(10) << std::left << "#nval";
1059 hist << std::setw(10) << std::left << "#grad";
1060 hist << std::setw(10) << std::left << "#hess";
1061 hist << std::setw(10) << std::left << "#prox";
1062 hist << std::setw(10) << std::left << "tr_flag";
1063 hist << std::setw(10) << std::left << "iterSP";
1064 hist << std::setw(10) << std::left << "flagSP";
1065 hist << std::endl;
1066 os << hist.str();
1067}
1068
1069template<typename Real>
1070void TrustRegionAlgorithm<Real>::writeName( std::ostream& os ) const {
1071 std::stringstream hist;
1072 hist << std::endl;
1073 switch (algSelect_) {
1074 default:
1075 case TRUSTREGION_P_SPG: hist << "SPG "; break;
1076 case TRUSTREGION_P_SPG2: hist << "Simplified SPG "; break;
1077 case TRUSTREGION_P_NCG: hist << "NCG "; break;
1078 }
1079 hist << "Trust-Region Method (Type P)" << std::endl;
1080 os << hist.str();
1081}
1082
1083template<typename Real>
1084void TrustRegionAlgorithm<Real>::writeOutput( std::ostream& os, bool write_header ) const {
1085 std::stringstream hist;
1086 hist << std::scientific << std::setprecision(6);
1087 if ( state_->iter == 0 ) writeName(os);
1088 if ( write_header ) writeHeader(os);
1089 if ( state_->iter == 0 ) {
1090 hist << " ";
1091 hist << std::setw(6) << std::left << state_->iter;
1092 hist << std::setw(15) << std::left << state_->value;
1093 hist << std::setw(15) << std::left << state_->gnorm;
1094 hist << std::setw(15) << std::left << "---";
1095 hist << std::setw(15) << std::left << state_->searchSize;
1096 hist << std::setw(10) << std::left << state_->nsval;
1097 hist << std::setw(10) << std::left << state_->nnval;
1098 hist << std::setw(10) << std::left << state_->ngrad;
1099 hist << std::setw(10) << std::left << nhess_;
1100 hist << std::setw(10) << std::left << state_->nprox;
1101 hist << std::setw(10) << std::left << "---";
1102 hist << std::setw(10) << std::left << "---";
1103 hist << std::setw(10) << std::left << "---";
1104 hist << std::endl;
1105 }
1106 else {
1107 hist << " ";
1108 hist << std::setw(6) << std::left << state_->iter;
1109 hist << std::setw(15) << std::left << state_->value;
1110 hist << std::setw(15) << std::left << state_->gnorm;
1111 hist << std::setw(15) << std::left << state_->snorm;
1112 hist << std::setw(15) << std::left << state_->searchSize;
1113 hist << std::setw(10) << std::left << state_->nsval;
1114 hist << std::setw(10) << std::left << state_->nnval;
1115 hist << std::setw(10) << std::left << state_->ngrad;
1116 hist << std::setw(10) << std::left << nhess_;
1117 hist << std::setw(10) << std::left << state_->nprox;
1118 hist << std::setw(10) << std::left << TRflag_;
1119 hist << std::setw(10) << std::left << SPiter_;
1120 hist << std::setw(10) << std::left << SPflag_;
1121 hist << std::endl;
1122 }
1123 os << hist.str();
1124}
1125
1126} // namespace TypeP
1127} // namespace ROL
1128
1129#endif
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0 zero)()
virtual void initialize(const Vector< Real > &x)
Initialize temporary variables.
Provides the interface to evaluate objective functions.
virtual void prox(Vector< Real > &Pv, const Vector< Real > &v, Real t, Real &tol)
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.
Provides interface for and implements limited-memory secant operators.
Provides an interface to check status of optimization algorithms.
Provides the interface to evaluate trust-region model functions.
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &s, Real &tol) override
void pgstep(Vector< Real > &pgiter, Vector< Real > &pgstep, Objective< Real > &nobj, const Vector< Real > &x, const Vector< Real > &dg, Real t, Real &tol) const
const Ptr< AlgorithmState< Real > > state_
virtual void writeExitStatus(std::ostream &os) const
const Ptr< CombinedStatusTest< Real > > status_
void initialize(const Vector< Real > &x, const Vector< Real > &g)
TRUtils::ETRFlag TRflag_
Trust-region exit flag.
void dncg(Vector< Real > &y, Real &sval, Real &nval, Vector< Real > &gmod, const Vector< Real > &x, Real del, TrustRegionModel_U< Real > &model, Objective< Real > &nobj, Vector< Real > &s, Vector< Real > &pwa1, Vector< Real > &pwa2, Vector< Real > &pwa3, Vector< Real > &pwa4, Vector< Real > &pwa5, Vector< Real > &dwa, std::ostream &outStream=std::cout)
unsigned verbosity_
Output level (default: 0).
TrustRegionAlgorithm(ParameterList &list, const Ptr< Secant< Real > > &secant=nullPtr)
ESecant esec_
Secant type (default: Limited-Memory BFGS).
Real gamma1_
Radius decrease rate (positive rho) (default: 0.25).
void dprox(Vector< Real > &x, const Vector< Real > &x0, Real t, Real del, Objective< Real > &nobj, Vector< Real > &y0, Vector< Real > &y1, Vector< Real > &yc, Vector< Real > &pwa, std::ostream &outStream=std::cout) const
void dspg(Vector< Real > &y, Real &sval, Real &nval, Vector< Real > &gmod, const Vector< Real > &x, Real del, TrustRegionModel_U< Real > &model, Objective< Real > &nobj, Vector< Real > &ymin, Vector< Real > &pwa, Vector< Real > &pwa1, Vector< Real > &pwa2, Vector< Real > &pwa3, Vector< Real > &pwa4, Vector< Real > &pwa5, Vector< Real > &dwa, std::ostream &outStream=std::cout)
void initialize(Vector< Real > &x, const Vector< Real > &g, Real ftol, Objective< Real > &sobj, Objective< Real > &nobj, Vector< Real > &px, Vector< Real > &dg, std::ostream &outStream=std::cout)
void writeName(std::ostream &os) const override
Print step name.
Real gamma0_
Radius decrease rate (negative rho) (default: 0.0625).
void writeOutput(std::ostream &os, bool write_header=false) const override
Print iterate status.
bool interpRad_
Interpolate the trust-region radius if ratio is negative (default: false).
int SPiter_
Subproblem solver iteration count.
int explim_
Maximum number of Cauchy point expansion steps (default: 10).
Real computeValue(Real inTol, Real &outTol, Real pRed, Real &fold, int iter, const Vector< Real > &x, const Vector< Real > &xold, Objective< Real > &obj)
Real tol1_
Absolute tolerance for truncated CG (default: 1e-4).
Real mu0_
Sufficient decrease parameter (default: 1e-2).
Real qtol_
Relative tolerance for computed decrease in Cauchy point computation (default: 1-8).
Real interpf_
Backtracking rate for Cauchy point computation (default: 1e-1).
Real delMax_
Maximum trust-region radius (default: ROL_INF).
Real alpha_
Initial Cauchy point step length (default: 1.0).
Real dcauchy(Vector< Real > &s, Real &alpha, Real &sval, Real &nval, const Vector< Real > &x, const Vector< Real > &g, Real del, TrustRegionModel_U< Real > &model, Objective< Real > &nobj, Vector< Real > &px, Vector< Real > &dwa, Vector< Real > &dwa1, std::ostream &outStream=std::cout)
Real computeGradient(const Vector< Real > &x, Vector< Real > &g, Vector< Real > &px, Vector< Real > &dg, Vector< Real > &pwa, Real del, Objective< Real > &sobj, Objective< Real > &nobj, std::ostream &outStream=std::cout) const
bool normAlpha_
Normalize initial Cauchy point step length (default: false).
Real TRsafe_
Safeguard size for numerically evaluating ratio (default: 1e2).
Real extrapf_
Extrapolation rate for Cauchy point computation (default: 1e1).
Real eta2_
Radius increase threshold (default: 0.9).
void writeHeader(std::ostream &os) const override
Print iterate header.
Ptr< TrustRegionModel_U< Real > > model_
Container for trust-region model.
Real eps_
Safeguard for numerically evaluating ratio.
int redlim_
Maximum number of Cauchy point reduction steps (default: 10).
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...
bool writeHeader_
Flag to write header at every iteration.
Real tol2_
Relative tolerance for truncated CG (default: 1e-2).
Real spexp_
Relative tolerance exponent for subproblem solve (default: 1, range: [1,2]).
Real eta1_
Radius decrease threshold (default: 0.05).
int SPflag_
Subproblem solver termination flag.
bool useSecantHessVec_
Flag to use secant as Hessian (default: false).
Real eta0_
Step acceptance threshold (default: 0.05).
int maxit_
Maximum number of CG iterations (default: 25).
bool useSecantPrecond_
Flag to use secant as a preconditioner (default: false).
Real gamma2_
Radius increase rate (default: 2.5).
int nhess_
Number of Hessian applications.
void dspg2(Vector< Real > &y, Real &sval, Real &nval, Real &pRed, Vector< Real > &gmod, const Vector< Real > &x, Real del, TrustRegionModel_U< Real > &model, Objective< Real > &nobj, Vector< Real > &pwa, Vector< Real > &pwa1, Vector< Real > &pwa2, Vector< Real > &dwa, std::ostream &outStream=std::cout)
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,...
virtual void plus(const Vector &x)=0
Compute , where .
virtual void zero()
Set to zero vector.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
virtual Real dot(const Vector &x) const =0
Compute where .
void analyzeRatio(Real &rho, ETRFlag &flag, const Real fold, const Real ftrial, const Real pRed, const Real epsi, std::ostream &outStream=std::cout, const bool print=false)
std::string ETRFlagToString(ETRFlag trf)
Real interpolateRadius(const Vector< Real > &g, const Vector< Real > &s, const Real snorm, const Real pRed, const Real fold, const Real ftrial, const Real del, const Real gamma0, const Real gamma1, const Real eta2, std::ostream &outStream=std::cout, const bool print=false)
ETrustRegionP StringToETrustRegionP(std::string s)
std::string NumberToString(T Number)
Definition ROL_Types.hpp:81
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition ROL_Types.hpp:91
ESecant StringToESecant(std::string s)
ESecantMode
@ SECANTMODE_FORWARD
@ SECANTMODE_INVERSE
@ SECANTMODE_BOTH
Real ROL_OVERFLOW(void)
Platform-dependent maximum double.
Real ROL_INF(void)