44 #ifndef ROL_TYPEB_KELLEYSACHSALGORITHM_DEF_HPP
45 #define ROL_TYPEB_KELLEYSACHSALGORITHM_DEF_HPP
50 template<
typename Real>
57 ParameterList &trlist = list.sublist(
"Step").sublist(
"Trust Region");
59 state_->searchSize = trlist.get(
"Initial Radius", -1.0);
60 delMax_ = trlist.get(
"Maximum Radius", ROL_INF<Real>());
61 eta0_ = trlist.get(
"Step Acceptance Threshold", 0.05);
62 eta1_ = trlist.get(
"Radius Shrinking Threshold", 0.05);
63 eta2_ = trlist.get(
"Radius Growing Threshold", 0.9);
64 gamma0_ = trlist.get(
"Radius Shrinking Rate (Negative rho)", 0.0625);
65 gamma1_ = trlist.get(
"Radius Shrinking Rate (Positive rho)", 0.25);
66 gamma2_ = trlist.get(
"Radius Growing Rate", 2.5);
67 TRsafe_ = trlist.get(
"Safeguard Size", 100.0);
68 eps_ = TRsafe_*ROL_EPSILON<Real>();
70 maxit_ = list.sublist(
"General").sublist(
"Krylov").get(
"Iteration Limit", 20);
71 tol1_ = list.sublist(
"General").sublist(
"Krylov").get(
"Absolute Tolerance", 1e-4);
72 tol2_ = list.sublist(
"General").sublist(
"Krylov").get(
"Relative Tolerance", 1e-2);
74 minit_ = trlist.sublist(
"Kelley-Sachs").get(
"Maximum Number of Smoothing Iterations", 20);
75 mu0_ = trlist.sublist(
"Kelley-Sachs").get(
"Sufficient Decrease Parameter", 1e-4);
76 mu1_ = trlist.sublist(
"Kelley-Sachs").get(
"Post-Smoothing Decrease Parameter", 0.9999);
77 eps0_ = trlist.sublist(
"Kelley-Sachs").get(
"Binding Set Tolerance", 1e-3);
78 beta_ = trlist.sublist(
"Kelley-Sachs").get(
"Post-Smoothing Backtracking Rate", 1e-2);
79 alpha0_ = trlist.sublist(
"Kelley-Sachs").get(
"Initial Post-Smoothing Step Size", 1.0);
81 verbosity_ = list.sublist(
"General").get(
"Output Level",0);
82 writeHeader_ = verbosity_ > 2;
84 useSecantPrecond_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Preconditioner",
false);
85 useSecantHessVec_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Hessian",
false);
87 model_ = makePtr<TrustRegionModel_U<Real>>(list,secant);
88 useSecantPrecond_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Preconditioner",
false);
89 useSecantHessVec_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Hessian",
false);
90 if (secant == nullPtr) {
91 esec_ =
StringToESecant(list.sublist(
"General").sublist(
"Secant").get(
"Type",
"Limited-Memory BFGS"));
95 template<
typename Real>
100 std::ostream &outStream) {
106 Real ftol =
static_cast<Real
>(0.1)*ROL_OVERFLOW<Real>();
108 state_->iterateVec->set(x);
110 state_->value = obj.
value(x,ftol);
112 obj.
gradient(*state_->gradientVec,x,ftol);
114 state_->stepVec->set(x);
115 state_->stepVec->axpy(-one,state_->gradientVec->dual());
117 state_->stepVec->axpy(-one,x);
118 state_->gnorm = state_->stepVec->norm();
119 state_->snorm = ROL_INF<Real>();
121 if ( state_->searchSize <= static_cast<Real>(0) ) {
122 state_->searchSize = state_->gradientVec->norm();
126 template<
typename Real>
131 std::ostream &outStream ) {
132 const Real one(1), xeps(ROL_EPSILON<Real>());
133 Real ftol = std::sqrt(ROL_EPSILON<Real>());
134 Real gfnorm(0), gfnormf(0), tol(0), stol(0), eps(0);
135 Real ftrial(0), fnew(0), pRed(0), rho(1), alpha(1), lambda(1);
138 initialize(x,g,obj,bnd,outStream);
139 Ptr<Vector<Real>> s = x.
clone(), gfree = g.
clone();
140 Ptr<Vector<Real>> pwa1 = x.
clone(), pwa2 = x.
clone(), pwa3 = x.
clone();
141 Ptr<Vector<Real>> dwa1 = g.
clone(), dwa2 = g.
clone(), dwa3 = g.
clone();
144 if (verbosity_ > 0) writeOutput(outStream,
true);
147 gfree->set(*state_->gradientVec);
150 pwa1->set(gfree->dual());
151 bnd.
pruneActive(*pwa1,state_->gradientVec->dual(),x,xeps,eps);
152 gfree->set(pwa1->dual());
153 gfnorm = gfree->norm();
156 eps = std::min(eps0_,std::sqrt(state_->gnorm));
157 tol = tol2_*std::sqrt(state_->gnorm);
158 stol = std::min(tol1_,tol*gfnorm);
160 while (status_->check(*state_)) {
162 model_->setData(obj,*state_->iterateVec,*state_->gradientVec,ftol);
165 pRed = trpcg(*s,SPflag_,SPiter_,*gfree,x,*state_->gradientVec,
166 state_->searchSize,*model_,bnd,eps,stol,maxit_,
167 *pwa1,*dwa1,*pwa2,*dwa2,*pwa3,*dwa3,outStream);
173 ftrial = obj.
value(x,ftol); state_->nfval++;
177 TRUtils::analyzeRatio<Real>(rho,TRflag_,state_->value,ftrial,pRed,eps_,outStream,verbosity_>1);
180 if ( rho >= eta0_ ) {
181 lambda = std::min(one, state_->searchSize/gfnorm);
183 pwa1->set(*state_->iterateVec);
184 pwa1->axpy(-lambda,gfree->dual());
186 pwa1->axpy(-one,*state_->iterateVec);
187 gfnormf = pwa1->norm();
189 if (state_->value-ftrial < mu0_*gfnormf*state_->gnorm) {
192 if ( verbosity_ > 1 ) {
193 outStream <<
" Norm of projected free gradient: " << gfnormf << std::endl;
194 outStream <<
" Decrease lower bound (constraints): " << mu0_*gfnormf*state_->gnorm << std::endl;
195 outStream <<
" Trust-region flag (constraints): " << TRflag_ << std::endl;
196 outStream << std::endl;
204 state_->stepVec->set(x);
205 state_->stepVec->axpy(-one,*state_->iterateVec);
206 state_->snorm = state_->stepVec->norm();
207 x.
set(*state_->iterateVec);
210 state_->searchSize = gamma1_*std::min(state_->snorm,state_->searchSize);
214 if (rho >= eta0_ && rho < eta1_) {
216 state_->searchSize = gamma1_*std::min(state_->snorm,state_->searchSize);
218 else if (rho >= eta2_) {
220 state_->searchSize = std::min(delMax_,gamma2_*state_->searchSize);
225 obj.
gradient(*dwa1,x,ftol); state_->ngrad++;
226 pwa2->set(dwa1->dual());
227 pwa1->set(x); pwa1->axpy(-alpha/alpha0_,*pwa2);
230 fnew = obj.
value(*pwa1,ftol); state_->nfval++;
231 while ((fnew-ftrial) >= mu1_*(state_->value-ftrial)) {
233 pwa1->set(x); pwa1->axpy(-alpha/alpha0_,*pwa2);
236 fnew = obj.
value(*pwa1,ftol); state_->nfval++;
237 if ( cnt >= minit_ )
break;
240 state_->stepVec->set(*pwa1);
241 state_->stepVec->axpy(-one,*state_->iterateVec);
242 state_->snorm = state_->stepVec->norm();
244 if (std::isnan(fnew)) {
247 x.
set(*state_->iterateVec);
250 state_->searchSize = gamma1_*std::min(state_->snorm,state_->searchSize);
255 state_->iterateVec->set(x);
256 state_->value = fnew;
257 dwa1->set(*state_->gradientVec);
259 obj.
gradient(*state_->gradientVec,x,ftol); state_->ngrad++;
261 gfree->set(*state_->gradientVec);
264 pwa1->set(gfree->dual());
265 bnd.
pruneActive(*pwa1,state_->gradientVec->dual(),x,xeps,eps);
266 gfree->set(pwa1->dual());
267 gfnorm = gfree->norm();
270 pwa1->axpy(-one,state_->gradientVec->dual());
273 state_->gnorm = pwa1->norm();
275 model_->update(x,*state_->stepVec,*dwa1,*state_->gradientVec,
276 state_->snorm,state_->iter);
278 eps = std::min(eps0_,std::sqrt(state_->gnorm));
279 tol = tol2_*std::sqrt(state_->gnorm);
280 stol = std::min(tol1_,tol*gfnorm);
285 if (verbosity_ > 0) writeOutput(outStream,writeHeader_);
290 template<
typename Real>
292 std::ostream &outStream ) {
297 throw Exception::NotImplemented(
">>> TypeB::KelleySachsAlgorithm::run : This algorithm cannot solve problems with linear equality constraints!");
301 template<
typename Real>
309 std::ostream &outStream ) {
310 throw Exception::NotImplemented(
">>> TypeB::KelleySachsAlgorithm::run : This algorithm cannot solve problems with linear equality constraints!");
313 template<
typename Real>
317 const Real del)
const {
320 Real rad = ptx*ptx + ptp*(dsq-xtx);
321 rad = std::sqrt(std::max(rad,zero));
324 sigma = (dsq-xtx)/(ptx+rad);
326 else if (rad > zero) {
327 sigma = (rad-ptx)/ptp;
335 template<
typename Real>
341 const Real tol,
const int itermax,
344 std::ostream &outStream)
const {
349 Real ftol = std::sqrt(ROL_EPSILON<Real>());
350 const Real
zero(0), half(0.5), one(1), two(2);
351 Real rho(0), kappa(0), beta(0), sigma(0), alpha(0), pRed(0);
352 Real rtr(0), tnorm(0), rnorm0(0), sMs(0), pMp(0), sMp(0);
359 applyFreePrecond(r,t,x,g0,eps,model,bnd,ftol,pwa,dwa);
362 rnorm0 = std::sqrt(rho);
363 if ( rnorm0 ==
zero ) {
370 for (iter = 0; iter < itermax; ++iter) {
372 applyFreeHessian(q,p,x,g0,eps,model,bnd,ftol,pwa,dwa);
376 alpha = (kappa>
zero) ? rho/kappa :
zero;
377 sigma = trqsol(sMs,pMp,sMp,del);
379 if (kappa <= zero || alpha >= sigma) {
382 iflag = (kappa<=
zero) ? 2 : 3;
385 pRed += half*alpha*rho;
389 applyFreePrecond(r,t,x,g0,eps,model,bnd,ftol,pwa,dwa);
394 if (rtr <= tol*tol || tnorm <= tol) {
395 sMs = sMs + two*alpha*sMp + alpha*alpha*pMp;
407 sMs = sMs + two*alpha*sMp + alpha*alpha*pMp;
408 sMp = beta*(sMp + alpha*pMp);
409 pMp = rho + beta*beta*pMp;
412 if (iter == itermax) {
416 pRed += sigma*(rho-half*sigma*kappa);
424 template<
typename Real>
435 const Real xeps(ROL_EPSILON<Real>());
438 model.
hessVec(hv,pwa,x,tol); nhess_++;
456 template<
typename Real>
467 const Real xeps(ROL_EPSILON<Real>());
487 template<
typename Real>
489 std::ios_base::fmtflags osFlags(os.flags());
490 if (verbosity_ > 1) {
491 os << std::string(114,
'-') << std::endl;
492 os <<
" Kelley-Sachs trust-region method status output definitions" << std::endl << std::endl;
493 os <<
" iter - Number of iterates (steps taken)" << std::endl;
494 os <<
" value - Objective function value" << std::endl;
495 os <<
" gnorm - Norm of the gradient" << std::endl;
496 os <<
" snorm - Norm of the step (update to optimization vector)" << std::endl;
497 os <<
" delta - Trust-Region radius" << std::endl;
498 os <<
" #fval - Number of times the objective function was evaluated" << std::endl;
499 os <<
" #grad - Number of times the gradient was computed" << std::endl;
500 os <<
" #hess - Number of times the Hessian was applied" << std::endl;
502 os <<
" tr_flag - Trust-Region flag" << std::endl;
508 os <<
" iterCG - Number of Truncated CG iterations" << std::endl << std::endl;
509 os <<
" flagGC - Trust-Region Truncated CG flag" << std::endl;
514 os << std::string(114,
'-') << std::endl;
517 os << std::setw(6) << std::left <<
"iter";
518 os << std::setw(15) << std::left <<
"value";
519 os << std::setw(15) << std::left <<
"gnorm";
520 os << std::setw(15) << std::left <<
"snorm";
521 os << std::setw(15) << std::left <<
"delta";
522 os << std::setw(10) << std::left <<
"#fval";
523 os << std::setw(10) << std::left <<
"#grad";
524 os << std::setw(10) << std::left <<
"#hess";
525 os << std::setw(10) << std::left <<
"tr_flag";
526 os << std::setw(10) << std::left <<
"iterCG";
527 os << std::setw(10) << std::left <<
"flagCG";
532 template<
typename Real>
534 std::ios_base::fmtflags osFlags(os.flags());
535 os << std::endl <<
"Kelley-Sachs Trust-Region Method (Type B, Bound Constraints)" << std::endl;
539 template<
typename Real>
541 std::ios_base::fmtflags osFlags(os.flags());
542 os << std::scientific << std::setprecision(6);
543 if ( state_->iter == 0 ) writeName(os);
544 if ( write_header ) writeHeader(os);
545 if ( state_->iter == 0 ) {
547 os << std::setw(6) << std::left << state_->iter;
548 os << std::setw(15) << std::left << state_->value;
549 os << std::setw(15) << std::left << state_->gnorm;
550 os << std::setw(15) << std::left <<
"---";
551 os << std::setw(15) << std::left << state_->searchSize;
552 os << std::setw(10) << std::left << state_->nfval;
553 os << std::setw(10) << std::left << state_->ngrad;
554 os << std::setw(10) << std::left << nhess_;
555 os << std::setw(10) << std::left <<
"---";
556 os << std::setw(10) << std::left <<
"---";
557 os << std::setw(10) << std::left <<
"---";
562 os << std::setw(6) << std::left << state_->iter;
563 os << std::setw(15) << std::left << state_->value;
564 os << std::setw(15) << std::left << state_->gnorm;
565 os << std::setw(15) << std::left << state_->snorm;
566 os << std::setw(15) << std::left << state_->searchSize;
567 os << std::setw(10) << std::left << state_->nfval;
568 os << std::setw(10) << std::left << state_->ngrad;
569 os << std::setw(10) << std::left << nhess_;
570 os << std::setw(10) << std::left << TRflag_;
571 os << std::setw(10) << std::left << SPiter_;
572 os << std::setw(10) << std::left << SPflag_;
std::string ECGFlagToString(ECGFlag cgf)
Provides the interface to evaluate objective functions.
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
virtual void scale(const Real alpha)=0
Compute where .
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 .
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
virtual Real value(const Vector< Real > &x, Real &tol)=0
Compute value.
void writeOutput(std::ostream &os, const bool write_header=false) const override
Print iterate status.
virtual void writeExitStatus(std::ostream &os) const
ESecant StringToESecant(std::string s)
virtual void zero()
Set to zero vector.
Defines the linear algebra or vector space interface.
virtual void update(const Vector< Real > &x, UpdateType type, int iter=-1)
Update objective function.
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
KelleySachsAlgorithm(ParameterList &list, const Ptr< Secant< Real >> &secant=nullPtr)
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &s, Real &tol) override
Apply Hessian approximation to vector.
void run(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, BoundConstraint< Real > &bnd, std::ostream &outStream=std::cout) override
Run algorithm on bound constrained problems (Type-B). This general interface supports the use of dual...
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
std::string NumberToString(T Number)
void initialize(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, BoundConstraint< Real > &bnd, std::ostream &outStream=std::cout)
Provides the interface to evaluate trust-region model functions.
void applyFreePrecond(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g, Real eps, TrustRegionModel_U< Real > &model, BoundConstraint< Real > &bnd, Real &tol, Vector< Real > &pwa, Vector< Real > &dwa) const
void applyFreeHessian(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g, Real eps, TrustRegionModel_U< Real > &model, BoundConstraint< Real > &bnd, Real &tol, Vector< Real > &pwa, Vector< Real > &dwa) const
Provides interface for and implements limited-memory secant operators.
Real trqsol(const Real xtx, const Real ptp, const Real ptx, const Real del) const
Provides an interface to check status of optimization algorithms.
std::string ETRFlagToString(ETRFlag trf)
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.
void writeHeader(std::ostream &os) const override
Print iterate header.
void pruneInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=Real(0))
Set variables to zero if they correspond to the -inactive set.
void pruneActive(Vector< Real > &v, const Vector< Real > &x, Real eps=Real(0))
Set variables to zero if they correspond to the -active set.
void writeName(std::ostream &os) const override
Print step name.
Provides the interface to apply upper and lower bound constraints.
const Ptr< PolyhedralProjection< Real > > & getPolyhedralProjection()
Get the polyhedral projection object. This is a null pointer if no linear constraints and/or bounds a...
void initialize(const Vector< Real > &x, const Vector< Real > &g)
virtual void run(Problem< Real > &problem, std::ostream &outStream=std::cout)
Run algorithm on bound constrained problems (Type-B). This is the primary Type-B interface.
virtual void set(const Vector &x)
Set where .
virtual Real norm() const =0
Returns where .
Real trpcg(Vector< Real > &w, int &iflag, int &iter, const Vector< Real > &g, const Vector< Real > &x, const Vector< Real > &g0, const Real del, TrustRegionModel_U< Real > &model, BoundConstraint< Real > &bnd, Real eps, const Real tol, const int itermax, Vector< Real > &p, Vector< Real > &q, Vector< Real > &r, Vector< Real > &t, Vector< Real > &pwa, Vector< Real > &dwa, std::ostream &outStream=std::cout) const
Defines the general constraint operator interface.
virtual void precond(Vector< Real > &Pv, const Vector< Real > &v, const Vector< Real > &s, Real &tol) override
Apply preconditioner to vector.