44 #ifndef ROL_TYPEP_TRUSTREGIONALGORITHM_DEF_HPP
45 #define ROL_TYPEP_TRUSTREGIONALGORITHM_DEF_HPP
53 template<
typename Real>
60 ParameterList &trlist = list.sublist(
"Step").sublist(
"Trust Region");
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);
71 eps_ = TRsafe_*ROL_EPSILON<Real>();
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);
77 storageNM_ = trlist.get(
"Nonmonotone Storage Size", 0);
78 useNM_ = (storageNM_ <= 0 ?
false :
true);
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);
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);
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");
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", 0.2);
109 ParameterList &glist = list.sublist(
"General");
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));
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));
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));
126 verbosity_ = list.sublist(
"General").get(
"Output Level",0);
127 writeHeader_ = verbosity_ > 2;
129 useSecantPrecond_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Preconditioner",
false);
130 useSecantHessVec_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Hessian",
false);
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"));
141 template<
typename Real>
149 std::ostream &outStream) {
155 nobj.
prox(*state_->iterateVec,x,t0_, ftol); state_->nprox++;
156 x.
set(*state_->iterateVec);
159 state_->svalue = sobj.
value(x,ftol); state_->nsval++;
161 state_->nvalue = nobj.
value(x,ftol); state_->nnval++;
162 state_->value = state_->svalue + state_->nvalue;
163 computeGradient(x,*state_->gradientVec,px,dg,*state_->stepVec,state_->searchSize,sobj,nobj,
true,gtol_,state_->gnorm,outStream);
165 state_->snorm = ROL_INF<Real>();
167 if (normAlpha_) alpha_ /= state_->gradientVec->norm();
169 if ( state_->searchSize <= static_cast<Real>(0) )
170 state_->searchSize = state_->gradientVec->norm();
175 template<
typename Real>
184 outTol = std::sqrt(ROL_EPSILON<Real>());
185 if ( useInexact_[0] ) {
186 if (!(iter%updateIter_) && (iter!=0)) force_ *= forceFactor_;
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++;
196 Real fval = sobj.
value(x,outTol); state_->nsval++;
200 template<
typename Real>
212 std::ostream &outStream)
const {
213 if ( useInexact_[1] ) {
214 Real gtol0 = scale0_*del;
215 if (accept) gtol = gtol0 +
static_cast<Real
>(1);
216 else gtol0 = scale0_*std::min(gnorm,del);
217 while ( gtol > gtol0 ) {
219 sobj.
gradient(g,x,gtol); state_->ngrad++;
221 pgstep(px, step, nobj, x, dg, t0_, gtol0);
222 gnorm = step.
norm() / t0_;
223 gtol0 = scale0_*std::min(gnorm,del);
228 gtol = std::sqrt(ROL_EPSILON<Real>());
229 sobj.
gradient(g,x,gtol); state_->ngrad++;
231 pgstep(px, step, nobj, x, dg, t0_, gtol);
232 gnorm = step.
norm() / t0_;
237 template<
typename Real>
242 std::ostream &outStream ) {
243 const Real
zero(0), one(1);
245 Real inTol =
static_cast<Real
>(0.1)*ROL_OVERFLOW<Real>(), outTol(inTol);
246 Real strial(0), ntrial(0), smodel(0), Ftrial(0), pRed(0), rho(1);
248 std::vector<std::string> output;
249 Ptr<Vector<Real>> gmod = g.
clone();
250 Ptr<Vector<Real>> px = x.
clone();
251 Ptr<Vector<Real>> dg = x.
clone();
253 initialize(x,g,inTol,sobj,nobj, *px, *dg, outStream);
255 Ptr<Vector<Real>> pwa1 = x.
clone(), pwa2 = x.
clone();
256 Ptr<Vector<Real>> pwa3 = x.
clone(), pwa4 = x.
clone();
257 Ptr<Vector<Real>> pwa5 = x.
clone(), pwa6 = x.
clone();
258 Ptr<Vector<Real>> pwa7 = x.
clone();
259 Ptr<Vector<Real>> dwa1 = g.
clone(), dwa2 = g.
clone();
261 Real rhoNM(0), sigmac(0), sigmar(0);
262 Real fr(state_->value), fc(state_->value), fmin(state_->value);
266 if (verbosity_ > 0) writeOutput(outStream,
true);
268 while (status_->check(*state_)) {
270 model_->setData(sobj,*state_->iterateVec,*state_->gradientVec,gtol_);
274 gmod->set(*state_->gradientVec);
275 smodel = state_->svalue;
276 ntrial = state_->nvalue;
277 switch (algSelect_) {
281 dcauchy(*state_->stepVec,alpha_, smodel, ntrial,
282 *state_->iterateVec, *dg, state_->searchSize,
283 *model_, nobj, *px, *dwa1, *dwa2, outStream);
284 x.
plus(*state_->stepVec);
289 dspg(x,smodel,ntrial,*gmod,*state_->iterateVec,state_->searchSize,
290 *model_,nobj,*pwa1,*pwa2,*pwa3,*pwa4,*pwa5,*pwa6,*pwa7,*dwa1,
292 pRed = state_->value - (smodel+ntrial);
295 dspg2(x,smodel, ntrial, pRed, *gmod, *state_->iterateVec,
296 state_->searchSize, *model_, nobj,
297 *pwa1, *pwa2, *px, *dwa1, outStream);
300 dncg(x,smodel,ntrial,*gmod,*state_->iterateVec,state_->searchSize,
301 *model_,nobj,*pwa1,*pwa2,*pwa3,*pwa4,*pwa5,*pwa6,*dwa1,
303 pRed = state_->value - (smodel+ntrial);
309 state_->stepVec->set(x); state_->stepVec->axpy(-one,*state_->iterateVec);
310 state_->snorm = state_->stepVec->norm();
313 strial = computeValue(inTol,outTol,pRed,state_->svalue,state_->iter,x,*state_->iterateVec,sobj);
314 Ftrial = strial + ntrial;
318 TRUtils::analyzeRatio<Real>(rho,TRflag_,state_->value,Ftrial,pRed,eps_,outStream,verbosity_>1);
320 TRUtils::analyzeRatio<Real>(rhoNM,TRflagNM,fr,Ftrial,pRed+sigmar,eps_,outStream,verbosity_>1);
321 TRflag_ = (rho < rhoNM ? TRflagNM : TRflag_);
322 rho = (rho < rhoNM ? rhoNM : rho );
329 x.
set(*state_->iterateVec);
334 state_->searchSize = TRUtils::interpolateRadius<Real>(*state_->gradientVec,*state_->stepVec,
335 state_->snorm,pRed,state_->value,Ftrial,state_->searchSize,gamma0_,gamma1_,eta2_,
336 outStream,verbosity_>1);
339 state_->searchSize = gamma1_*std::min(state_->snorm,state_->searchSize);
341 computeGradient(x,*state_->gradientVec,*px,*dg,*pwa1,state_->searchSize,sobj,nobj,
false,gtol_,state_->gnorm,outStream);
345 state_->value = Ftrial;
346 state_->svalue = strial;
347 state_->nvalue = ntrial;
352 sigmac += pRed; sigmar += pRed;
353 if (Ftrial < fmin) { fmin = Ftrial; fc = fmin; sigmac =
zero; L = 0; }
356 if (Ftrial > fc) { fc = Ftrial; sigmac =
zero; }
357 if (L == storageNM_) { fr = fc; sigmar = sigmac; }
361 if (rho >= eta2_) state_->searchSize = std::min(gamma2_*state_->searchSize, delMax_);
363 dwa1->set(*state_->gradientVec);
364 computeGradient(x,*state_->gradientVec,*px,*dg,*pwa1,state_->searchSize,sobj,nobj,
true,gtol_,state_->gnorm,outStream);
365 state_->iterateVec->set(x);
367 model_->update(x,*state_->stepVec,*dwa1,*state_->gradientVec,
368 state_->snorm,state_->iter);
372 if (verbosity_ > 0) writeOutput(outStream,writeHeader_);
377 template<
typename Real>
390 std::ostream &outStream) {
391 const Real half(0.5), sold(sval), nold(nval);
392 Real tol = std::sqrt(ROL_EPSILON<Real>());
394 Real gs(0), snorm(0), Qk(0), pRed(0);
396 pgstep(px, s, nobj, x, g, alpha, tol);
402 model.
hessVec(dwa,s,x,tol); nhess_++;
404 nval = nobj.
value(px, tol); state_->nnval++;
406 sval = sold + gs + half * s.
apply(dwa);
407 pRed = (sold + nold) - (sval + nval);
408 Qk = gs + nval - nold;
409 interp = (pRed < -mu0_*Qk);
417 pgstep(px, s, nobj, x, g, alpha, tol);
420 model.
hessVec(dwa,s,x,tol); nhess_++;
422 nval = nobj.
value(px, tol); state_->nnval++;
424 sval = sold + gs + half * s.
apply(dwa);
425 pRed = (sold + nold) - (sval + nval);
426 Qk = gs + nval - nold;
427 search = ((pRed < -mu0_*Qk) && (cnt < redlim_)) ;
440 pgstep(px, s, nobj, x, g, alpha, tol);
442 if (snorm <= del && cnt < explim_){
443 model.
hessVec(dwa,s,x,tol); nhess_++;
445 nval = nobj.
value(px, tol); state_->nnval++;
447 sval = sold + gs + half * s.
apply(dwa);
448 pRed = (sold + nold) - (sval + nval);
449 Qk = gs + nval - nold;
450 if (pRed >= -mu0_*Qk && std::abs(pRed-mvals) > qtol_*std::abs(mvals)) {
470 pgstep(px, s, nobj, x, g, alpha, tol);
473 if (verbosity_ > 1) {
474 outStream <<
" Cauchy point" << std::endl;
475 outStream <<
" Step length (alpha): " << alpha << std::endl;
476 outStream <<
" Step length (alpha*g): " << snorm << std::endl;
477 outStream <<
" Model decrease (pRed): " << pRed << std::endl;
479 outStream <<
" Number of extrapolation steps: " << cnt << std::endl;
484 template<
typename Real>
498 std::ostream &outStream) {
506 const Real half(0.5), one(1), safeguard(1e2*ROL_EPSILON<Real>());
507 const Real mprev(sval+nval);
508 Real tol(std::sqrt(ROL_EPSILON<Real>()));
509 Real coeff(1), alpha(1), alphaMax(1), lambda(1), lambdaTmp(1);
510 Real gs(0), ss(0), gnorm(0), s0s0(0), ss0(0), sHs(0), snorm(0), nold(nval);
517 coeff = one / gmod.
norm();
518 lambda = std::max(lambdaMin_,std::min(coeff,lambdaMax_));
519 pgstep(pwa2, pwa, nobj, y, gmod.
dual(), lambda, tol);
520 gs = gmod.
apply(pwa);
522 snorm = std::sqrt(ss);
523 gnorm = snorm / lambda;
526 const Real gtol = std::min(tol1_,tol2_*gnorm);
529 outStream <<
" Spectral Projected Gradient" << std::endl;
532 while (SPiter_ < maxit_) {
536 model.
hessVec(dwa,pwa,x,tol); nhess_++;
537 sHs = dwa.
apply(pwa);
541 nval = nobj.
value(pwa2,tol); state_->nnval++;
545 if (snorm >= del-safeguard) {
547 alphaMax = std::min(one, (-ss0 + std::sqrt(ss0*ss0 - ss*(s0s0-del*del)))/ss);
549 alpha = (sHs <= safeguard) ? alphaMax : std::min(alphaMax, -(gs + nval - nold)/sHs);
554 sval += gs + half * sHs;
560 nval = nobj.
value(y, tol); state_->nnval++;
561 sval += alpha * (gs + half * alpha * sHs);
562 gmod.
axpy(alpha,dwa);
565 pRed = mprev - (sval+nval);
568 pwa1.
set(y); pwa1.
axpy(-one,x);
569 s0s0 = pwa1.
dot(pwa1);
570 snorm = std::sqrt(s0s0);
572 if (verbosity_ > 1) {
573 outStream << std::endl;
574 outStream <<
" Iterate: " << SPiter_ << std::endl;
575 outStream <<
" Spectral step length (lambda): " << lambda << std::endl;
576 outStream <<
" Step length (alpha): " << alpha << std::endl;
577 outStream <<
" Model decrease (pRed): " << pRed << std::endl;
578 outStream <<
" Optimality criterion: " << gnorm << std::endl;
579 outStream <<
" Step norm: " << snorm << std::endl;
580 outStream << std::endl;
583 if (snorm >= del - safeguard) { SPflag_ = 2;
break; }
586 lambdaTmp = (sHs <= safeguard) ? one/gmod.
norm() : ss/sHs;
587 lambda = std::max(lambdaMin_,std::min(lambdaTmp,lambdaMax_));
589 pgstep(pwa2, pwa, nobj, y, gmod.
dual(), alpha, tol);
590 gs = gmod.
apply(pwa);
592 gnorm = std::sqrt(ss) / lambda;
594 if (gnorm <= gtol) { SPflag_ = 0;
break; }
596 SPflag_ = (SPiter_==maxit_) ? 1 : SPflag_;
599 template<
typename Real>
616 std::ostream &outStream) {
624 const Real half(0.5), one(1), safeguard(1e2*ROL_EPSILON<Real>());
625 const Real mval(sval+nval);
626 Real tol(std::sqrt(ROL_EPSILON<Real>()));
627 Real mcomp(0), mval_min(0), sval_min(0), nval_min(0);
628 Real alpha(1), coeff(1), lambda(1), lambdaTmp(1);
629 Real snew(sval), nnew(nval), mnew(mval);
630 Real sold(sval), nold(nval), mold(mval);
631 Real sHs(0), ss(0), gs(0), Qk(0), gnorm(0);
632 std::deque<Real> mqueue; mqueue.push_back(mold);
634 if (useNMSP_ && useMin_) {
635 mval_min = mval; sval_min = sval; nval_min = nval; ymin.
set(y);
640 pwa.
set(y); pwa.
axpy(-t0_,pwa1);
641 dprox(pwa,x,t0_,del,nobj,pwa2,pwa3,pwa4,pwa5,outStream);
643 gnorm = pwa.
norm() / t0_;
644 const Real gtol = std::min(tol1_,tol2_*gnorm);
647 coeff = one / gmod.
norm();
648 lambda = std::max(lambdaMin_,std::min(coeff,lambdaMax_));
651 outStream <<
" Spectral Projected Gradient" << std::endl;
654 while (SPiter_ < maxit_) {
659 pwa.
set(y); pwa.
axpy(-lambda,pwa1);
660 dprox(pwa,x,lambda,del,nobj,pwa2,pwa3,pwa4,pwa5,outStream);
666 model.
hessVec(dwa,pwa,x,tol); nhess_++;
668 nnew = nobj.
value(pwa2, tol); state_->nnval++;
669 sHs = dwa.
apply(pwa);
670 gs = gmod.
apply(pwa);
671 snew = half * sHs + gs + sold;
673 Qk = gs + nnew - nold;
687 mcomp = *std::max_element(mqueue.begin(),mqueue.end());
688 while( mnew > mcomp + mu0_*Qk ) {
690 pwa2.
set(y); pwa2.
axpy(alpha,pwa);
692 nnew = nobj.
value(pwa2, tol); state_->nnval++;
693 snew = half * alpha * alpha * sHs + alpha * gs + sold;
695 Qk = alpha * gs + nnew - nold;
699 alpha = (sHs <= safeguard) ? one : std::min(one,-(gs + nnew - nold)/sHs);
707 gmod.
axpy(alpha,dwa);
712 if (static_cast<int>(mqueue.size())==maxSize_) mqueue.pop_front();
713 mqueue.push_back(sval+nval);
714 if (useMin_ && mval <= mval_min) {
715 mval_min = mval; sval_min = sval; nval_min = nval; ymin.
set(y);
721 pwa.
set(y); pwa.
axpy(-t0_,pwa1);
722 dprox(pwa,x,t0_,del,nobj,pwa2,pwa3,pwa4,pwa5,outStream);
724 gnorm = pwa.
norm() / t0_;
726 if (verbosity_ > 1) {
727 outStream << std::endl;
728 outStream <<
" Iterate: " << SPiter_ << std::endl;
729 outStream <<
" Spectral step length (lambda): " << lambda << std::endl;
730 outStream <<
" Step length (alpha): " << alpha << std::endl;
731 outStream <<
" Model decrease (pRed): " << mval-mold << std::endl;
732 outStream <<
" Optimality criterion: " << gnorm << std::endl;
733 outStream << std::endl;
735 if (gnorm < gtol)
break;
738 lambdaTmp = (sHs == 0 ? coeff : ss / sHs);
739 lambda = std::max(lambdaMin_, std::min(lambdaTmp, lambdaMax_));
741 if (useNMSP_ && useMin_) {
742 sval = sval_min; nval = nval_min; y.
set(ymin);
745 sval = sold; nval = nold;
747 SPflag_ = (SPiter_==maxit_) ? 1 : 0;
750 template<
typename Real>
760 std::ostream &outStream)
const {
762 const Real
zero(0), half(0.5), one(1), two(2), three(3);
763 const Real eps(ROL_EPSILON<Real>()), tol0(1e1*eps), fudge(1.0-1e-2*sqrt(eps));
764 Real f0(0), f1(0), fc(0), t0(0), t1(1), tc(0), d1(1), d2(1), tol(1);
765 Real p(0), q(0), r(0), s(0), m(0);
766 int cnt(state_->nprox);
767 nobj.
prox(y1, x, t, tol); state_->nprox++;
768 pwa.
set(y1); pwa.
axpy(-one,x0);
775 tc = t0; fc = f0; yc.
set(y0);
779 if (std::abs(fc-del) < std::abs(f1-del)) {
780 t0 = t1; t1 = tc; tc = t0;
781 f0 = f1; f1 = fc; fc = f0;
784 tol = two*eps*std::abs(t1) + half*tol0;
786 if (std::abs(m) <= tol) { code = 1;
break; }
787 if ((f1 >= fudge*del && f1 <= del))
break;
788 if (std::abs(d1) < tol || std::abs(f0-del) <= std::abs(f1-del)) {
792 s = (f1-del)/(f0-del);
798 q = (f0-del)/(fc-del);
799 r = (f1-del)/(fc-del);
800 p = s*(two*m*q*(q-r)-(t1-t0)*(r-one));
801 q = (q-one)*(r-one)*(s-one);
803 if (p >
zero) q = -q;
807 if (two*p < three*m*q-std::abs(tol*q) && p < std::abs(half*s*q)) {
814 t0 = t1; f0 = f1; y0.
set(y1);
815 if (std::abs(d2) > tol) t1 += d2;
816 else if (m >
zero) t1 += tol;
819 nobj.
prox(y1, pwa, t1*t, tol); state_->nprox++;
820 pwa.
set(y1); pwa.
axpy(-one,x0);
822 if ((f1 > del && fc > del) || (f1 <= del && fc <= del)) {
823 tc = t0; fc = f0; yc.
set(y0);
827 if (code==1 && f1>del) x.
set(yc);
829 if (verbosity_ > 1) {
830 outStream << std::endl;
831 outStream <<
" Trust-Region Subproblem Proximity Operator" << std::endl;
832 outStream <<
" Number of proxes: " << state_->nprox-cnt << std::endl;
833 if (code == 1 && f1 > del) {
834 outStream <<
" Transformed Multiplier: " << tc << std::endl;
835 outStream <<
" Dual Residual: " << fc-del << std::endl;
838 outStream <<
" Transformed Multiplier: " << t1 << std::endl;
839 outStream <<
" Dual Residual: " << f1-del << std::endl;
841 outStream <<
" Exit Code: " << code << std::endl;
842 outStream << std::endl;
846 template<
typename Real>
850 Real lambda, Real tmax,
854 Real tol(std::sqrt(ROL_EPSILON<Real>()));
855 const Real eps(1e-2*std::sqrt(ROL_EPSILON<Real>())), tol0(1e4*tol);
856 const Real eps0(1e2*ROL_EPSILON<Real>());
857 const unsigned maxit(50);
858 const Real
zero(0), half(0.5), one(1), two(2);
859 const Real lam(0.5*(3.0-std::sqrt(5.0)));
860 const Real nold(nval);
869 Real nR = nobj.
value(pwa,tol); state_->nnval++;
870 Real pR = tR * (half * tR * kappa + gs) + nR - nold;
873 Real t0 = tR, n0 = nR;
878 n0 = nobj.
value(pwa,tol); state_->nnval++;
880 Real ts = (kappa > 0) ? std::min(tR,(((nold - n0) / kappa) / t0) - (gs / kappa)) : tR;
881 Real t = std::min(t0,ts);
884 t = (t0 < tR ? t0 : half*tR);
891 Real nt = nobj.
value(pwa,tol); state_->nnval++;
892 Real Qt = t * gs + nt - nold, Qu = Qt;
893 Real pt = half * t * t * kappa + Qt;
898 if (useOptT && nt == nold && nR == nold) {
900 pred = ts * (half * ts * kappa + gs);
907 if (pt >= std::max(pL, pR)) {
916 Real w = t, v = t, pw = pt, pv = pt, d(0), pu(0), nu(0);
917 Real u(0), p(0), q(0), r(0), etmp(0), e(0), dL(0), dR(0);
918 Real tm = half * (tL + tR);
919 Real tol1 = tol0 * std::abs(t)+eps;
920 Real tol2 = two * tol1;
922 for (
unsigned it = 0u; it < maxit; ++it) {
923 dL = tL-t; dR = tR-t;
924 if (std::abs(e) > tol1) {
929 if (q >
zero) p = -p;
933 if ( std::abs(p) >= std::abs(half*q*etmp) || p <= q*dL || p >= q*dR ) {
934 e = (t > tm ? dL : dR);
940 if (u-tL < tol2 || tR-u < tol2) d = (tm >= t ? tol1 : -tol1);
944 e = (t > tm ? dL : dR);
947 u = t + (std::abs(d) >= tol1 ? d : (d >=
zero ? tol1 : -tol1));
950 nu = nobj.
value(pwa,tol); state_->nnval++;
951 Qu = u * gs + nu - nold;
952 pu = half * u * u * kappa + Qu;
957 pv = pw; pw = pt; pt = pu;
963 if (pu <= pw || w == t) {
967 else if (pu <= pv || v == t || v == w) {
972 tol1 = tol0*std::abs(t)+eps;
974 tol3 = eps0 * std::max(std::abs(Qt),one);
975 if (pt <= (mu*std::min(
zero,Qt)+tol3) && std::abs(t-tm) <= (tol2-half*(tR-tL)))
break;
983 template<
typename Real>
999 std::ostream &outStream) {
1019 const Real
zero(0), half(0.5), one(1), two(2);
1020 const Real del2(del*del);
1021 Real tol(std::sqrt(ROL_EPSILON<Real>())), safeguard(tol);
1022 Real mold(sval+nval), nold(nval);
1023 Real snorm(0), snorm0(0), gnorm(0), gnorm0(0), gnorm2(0);
1024 Real alpha(1), beta(1), lambdaTmp(1), lambda(1), eta(etaNCG_);
1025 Real alphaMax(1), pred(0), lam1(1);
1026 Real sy(0), gg(0), sHs(0), gs(0), ds(0), ss(0), ss0(0);
1034 lambdaTmp = t0_ / gmod.
norm();
1035 lambda = std::max(lambdaMin_,std::min(lambdaTmp,lambdaMax_));
1039 pgstep(pwa1, pwa2, nobj, y, gmod.
dual(), lambda, tol);
1040 pwa2.
scale(one/lambda);
1045 const Real gtol = std::min(tol1_,tol2_*gnorm);
1047 if (verbosity_>1) outStream <<
" Nonlinear Conjugate Gradient" << std::endl;
1051 while (SPiter_ < maxit_) {
1055 model.
hessVec(dwa,s,x,tol); nhess_++;
1061 alphaMax = (-ds + std::sqrt(ds*ds + ss*(del2 - snorm0*snorm0)))/ss;
1062 dbls(alpha,nold,pred,y,s,lam1,alphaMax,sHs,gs,nobj,pwa5);
1075 gmod.
axpy(alpha, dwa);
1076 sval += alpha*(gs + half*alpha*sHs);
1079 pwa3.
set(y); pwa3.
axpy(-one,x);
1080 ss0 += alpha*(alpha*ss + two*ds);
1081 snorm0 = std::sqrt(ss0);
1083 if (snorm0 >= (one-safeguard)*del) { SPflag_ = 2;
break; }
1086 lambdaTmp = (sHs <= safeguard) ? t0_/gmod.
norm() : ss/sHs;
1087 lambda = std::max(lambdaMin_, std::min(lambdaMax_, lambdaTmp));
1091 pgstep(pwa1, pwa2, nobj, y, gmod.
dual(), lambda, tol);
1092 pwa2.
scale(one/lambda);
1094 gnorm = pwa2.
norm();
1095 if (gnorm <= gtol) { SPflag_ = 0;
break; }
1097 gnorm2 = gnorm * gnorm;
1100 beta = gnorm2/(gnorm0 * gnorm0);
1104 pwa5.
set(pwa4); pwa5.
axpy(-one,pwa2);
1105 beta = std::max(
zero, -pwa5.
dot(pwa2)/(gnorm0*gnorm0));
1108 pwa5.
set(pwa4); pwa5.
axpy(-one,pwa2);
1110 gg = pwa2.
dot(pwa4);
1111 eta = -one/(s.
norm()*std::min(etaNCG_, gnorm0));
1112 beta = std::max(eta, (gnorm2-gg-two*pwa2.
dot(s)*(gnorm2-two*gg+(gnorm0*gnorm0))/sy)/sy);
1115 pwa5.
set(pwa4); pwa5.
axpy(-one,pwa2);
1116 beta = std::max(
zero, -pwa2.
dot(pwa5)/s.
dot(pwa5));
1119 pwa5.
set(pwa4); pwa5.
axpy(-one,pwa2);
1120 beta = std::max(
zero, gnorm2/s.
dot(pwa5));
1123 pwa5.
set(pwa4); pwa5.
axpy(-one,pwa2);
1124 beta = std::max(-gnorm2, std::min(gnorm2, -pwa5.
dot(pwa2)))/(gnorm0*gnorm0);
1127 pwa5.
set(pwa4); pwa5.
axpy(-one,pwa2);
1128 beta = std::max(
zero, std::min(-pwa2.
dot(pwa5), gnorm2)/s.
dot(pwa5));
1133 if (beta !=
zero && beta < ROL_INF<Real>()){
1139 nval = nobj.
value(pwa4,tol); state_->nnval++;
1140 gs = gmod.
apply(pwa5);
1141 if (gs + nval - nold <= -(one - desPar_)*gnorm2) {
1155 if (verbosity_ > 1) {
1156 outStream << std::endl;
1157 outStream <<
" Iterate: " << SPiter_ << std::endl;
1158 outStream <<
" Spectral step length (lambda): " << lambda << std::endl;
1159 outStream <<
" Step length (alpha): " << alpha << std::endl;
1160 outStream <<
" NCG parameter (beta): " << beta << std::endl;
1161 outStream <<
" Model decrease (pRed): " << mold-(sval+nold) << std::endl;
1162 outStream <<
" Step size: " << snorm0 << std::endl;
1163 outStream <<
" Optimality criterion: " << gnorm << std::endl;
1164 outStream <<
" Optimality tolerance: " << gtol << std::endl;
1165 outStream << std::endl;
1171 template<
typename Real>
1173 std::ios_base::fmtflags osFlags(os.flags());
1174 if (verbosity_ > 1) {
1175 os << std::string(114,
'-') << std::endl;
1176 switch (algSelect_) {
1182 os <<
"trust-region method status output definitions" << std::endl << std::endl;
1183 os <<
" iter - Number of iterates (steps taken)" << std::endl;
1184 os <<
" value - Objective function value" << std::endl;
1185 os <<
" gnorm - Norm of the gradient" << std::endl;
1186 os <<
" snorm - Norm of the step (update to optimization vector)" << std::endl;
1187 os <<
" delta - Trust-Region radius" << std::endl;
1188 os <<
" #sval - Number of times the smooth objective function was evaluated" << std::endl;
1189 os <<
" #nval - Number of times the nonsmooth objective function was evaluated" << std::endl;
1190 os <<
" #grad - Number of times the gradient was computed" << std::endl;
1191 os <<
" #hess - Number of times the Hessian was applied" << std::endl;
1192 os <<
" #prox - Number of times the proximal operator was computed" << std::endl;
1194 os <<
" tr_flag - Trust-Region flag" << std::endl;
1200 os <<
" iterSP - Number of Spectral Projected Gradient iterations" << std::endl << std::endl;
1201 os <<
" flagSP - Trust-Region Spectral Projected Gradient flag" << std::endl;
1202 os <<
" 0 - Converged" << std::endl;
1203 os <<
" 1 - Iteration Limit Exceeded" << std::endl;
1204 os << std::string(114,
'-') << std::endl;
1207 os << std::setw(6) << std::left <<
"iter";
1208 os << std::setw(15) << std::left <<
"value";
1209 os << std::setw(15) << std::left <<
"gnorm";
1210 os << std::setw(15) << std::left <<
"snorm";
1211 os << std::setw(15) << std::left <<
"delta";
1212 os << std::setw(10) << std::left <<
"#sval";
1213 os << std::setw(10) << std::left <<
"#nval";
1214 os << std::setw(10) << std::left <<
"#grad";
1215 os << std::setw(10) << std::left <<
"#hess";
1216 os << std::setw(10) << std::left <<
"#prox";
1217 os << std::setw(10) << std::left <<
"tr_flag";
1218 os << std::setw(10) << std::left <<
"iterSP";
1219 os << std::setw(10) << std::left <<
"flagSP";
1224 template<
typename Real>
1226 std::ios_base::fmtflags osFlags(os.flags());
1228 switch (algSelect_) {
1234 os <<
"Trust-Region Method (Type P)" << std::endl;
1238 template<
typename Real>
1240 std::ios_base::fmtflags osFlags(os.flags());
1241 os << std::scientific << std::setprecision(6);
1242 if ( state_->iter == 0 ) writeName(os);
1243 if ( write_header ) writeHeader(os);
1244 if ( state_->iter == 0 ) {
1246 os << std::setw(6) << std::left << state_->iter;
1247 os << std::setw(15) << std::left << state_->value;
1248 os << std::setw(15) << std::left << state_->gnorm;
1249 os << std::setw(15) << std::left <<
"---";
1250 os << std::setw(15) << std::left << state_->searchSize;
1251 os << std::setw(10) << std::left << state_->nsval;
1252 os << std::setw(10) << std::left << state_->nnval;
1253 os << std::setw(10) << std::left << state_->ngrad;
1254 os << std::setw(10) << std::left << nhess_;
1255 os << std::setw(10) << std::left << state_->nprox;
1256 os << std::setw(10) << std::left <<
"---";
1257 os << std::setw(10) << std::left <<
"---";
1258 os << std::setw(10) << std::left <<
"---";
1263 os << std::setw(6) << std::left << state_->iter;
1264 os << std::setw(15) << std::left << state_->value;
1265 os << std::setw(15) << std::left << state_->gnorm;
1266 os << std::setw(15) << std::left << state_->snorm;
1267 os << std::setw(15) << std::left << state_->searchSize;
1268 os << std::setw(10) << std::left << state_->nsval;
1269 os << std::setw(10) << std::left << state_->nnval;
1270 os << std::setw(10) << std::left << state_->ngrad;
1271 os << std::setw(10) << std::left << nhess_;
1272 os << std::setw(10) << std::left << state_->nprox;
1273 os << std::setw(10) << std::left << TRflag_;
1274 os << std::setw(10) << std::left << SPiter_;
1275 os << std::setw(10) << std::left << SPflag_;
Provides the interface to evaluate objective functions.
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)
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Real computeValue(Real inTol, Real &outTol, Real pRed, Real &fold, int iter, const Vector< Real > &x, const Vector< Real > &xold, Objective< Real > &obj)
virtual void scale(const Real alpha)=0
Compute where .
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)
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
TrustRegionAlgorithm(ParameterList &list, const Ptr< Secant< Real >> &secant=nullPtr)
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
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)
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)
ESecant StringToESecant(std::string s)
virtual void zero()
Set to zero vector.
Defines the linear algebra or vector space interface.
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)
virtual void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
virtual Real dot(const Vector &x) const =0
Compute where .
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
void dbls(Real &alpha, Real &nval, Real &pred, const Vector< Real > &y, const Vector< Real > &s, Real lambda, Real tmax, Real kappa, Real gs, Objective< Real > &nobj, Vector< Real > &pwa)
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &s, Real &tol) override
Apply Hessian approximation to vector.
ETRFlag
Enumation of flags used by trust-region solvers.
ETrustRegionP StringToETrustRegionP(std::string s)
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
std::string NumberToString(T Number)
Provides the interface to evaluate trust-region model functions.
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...
Provides interface for and implements limited-memory secant operators.
Provides an interface to check status of optimization algorithms.
std::string ETRFlagToString(ETRFlag trf)
void writeOutput(std::ostream &os, bool write_header=false) const override
Print iterate status.
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 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)
virtual void set(const Vector &x)
Set where .
virtual Real norm() const =0
Returns where .
virtual void writeExitStatus(std::ostream &os) const
void initialize(const Vector< Real > &x, const Vector< Real > &g)
void writeName(std::ostream &os) const override
Print step name.
void 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, bool accept, Real >ol, Real &gnorm, std::ostream &outStream=std::cout) const
void writeHeader(std::ostream &os) const override
Print iterate header.