44 #ifndef ROL_TYPEB_COLEMANLIALGORITHM_DEF_HPP
45 #define ROL_TYPEB_COLEMANLIALGORITHM_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>();
69 interpRad_ = trlist.get(
"Use Radius Interpolation",
false);
71 storageNM_ = trlist.get(
"Nonmonotone Storage Size", 0);
72 useNM_ = (storageNM_ <= 0 ?
false :
true);
74 maxit_ = list.sublist(
"General").sublist(
"Krylov").get(
"Iteration Limit", 20);
75 tol1_ = list.sublist(
"General").sublist(
"Krylov").get(
"Absolute Tolerance", 1e-4);
76 tol2_ = list.sublist(
"General").sublist(
"Krylov").get(
"Relative Tolerance", 1e-2);
78 ROL::ParameterList &lmlist = trlist.sublist(
"Coleman-Li");
79 mu0_ = lmlist.get(
"Sufficient Decrease Parameter", 1e-2);
80 spexp_ = lmlist.get(
"Relative Tolerance Exponent", 1.0);
81 spexp_ = std::max(static_cast<Real>(1),std::min(spexp_,static_cast<Real>(2)));
82 alphaMax_ = lmlist.get(
"Relaxation Safeguard", 0.999);
83 alphaMax_ = (alphaMax_ >=
static_cast<Real
>(1) ? static_cast<Real>(0.5) : alphaMax_);
85 verbosity_ = list.sublist(
"General").get(
"Output Level",0);
86 writeHeader_ = verbosity_ > 2;
88 useSecantPrecond_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Preconditioner",
false);
89 useSecantHessVec_ = list.sublist(
"General").sublist(
"Secant").get(
"Use as Hessian",
false);
94 model_ = makePtr<TrustRegionModel_U<Real>>(list,secant,mode);
95 if (secant == nullPtr) {
96 esec_ =
StringToESecant(list.sublist(
"General").sublist(
"Secant").get(
"Type",
"Limited-Memory BFGS"));
100 template<
typename Real>
105 std::ostream &outStream) {
108 if (proj_ == nullPtr) {
109 proj_ = makePtr<PolyhedralProjection<Real>>(makePtrFromRef(bnd));
116 Real ftol =
static_cast<Real
>(0.1)*ROL_OVERFLOW<Real>();
117 proj_->getBoundConstraint()->projectInterior(x); state_->nproj++;
118 state_->iterateVec->set(x);
120 state_->value = obj.
value(x,ftol);
122 obj.
gradient(*state_->gradientVec,x,ftol);
124 state_->stepVec->set(x);
125 state_->stepVec->axpy(-one,state_->gradientVec->dual());
126 proj_->project(*state_->stepVec,outStream); state_->nproj++;
127 state_->stepVec->axpy(-one,x);
128 state_->gnorm = state_->stepVec->norm();
129 state_->snorm = ROL_INF<Real>();
131 if ( state_->searchSize <= static_cast<Real>(0) ) {
132 state_->searchSize = state_->gradientVec->norm();
136 rcon_ = makePtr<ReducedLinearConstraint<Real>>(proj_->getLinearConstraint(),
139 ns_ = makePtr<NullSpaceOperator<Real>>(rcon_,x,
140 *proj_->getResidual());
144 template<
typename Real>
149 std::ostream &outStream ) {
150 const Real
zero(0), one(1), half(0.5);
151 Real tol0 = std::sqrt(ROL_EPSILON<Real>());
152 Real tol(0), stol(0), snorm(0);
153 Real ftrial(0), pRed(0), rho(1), alpha(1);
155 initialize(x,g,obj,bnd,outStream);
156 Ptr<Vector<Real>> pwa1 = x.
clone(), pwa2 = x.
clone(), pwa3 = x.
clone();
157 Ptr<Vector<Real>> pwa4 = x.
clone(), pwa5 = x.
clone();
158 Ptr<Vector<Real>> dwa1 = g.
clone(), dwa2 = g.
clone(), dwa3 = g.
clone();
160 Real rhoNM(0), sigmac(0), sigmar(0), sBs(0), gs(0);
161 Real fr(state_->value), fc(state_->value), fmin(state_->value);
166 if (verbosity_ > 0) writeOutput(outStream,
true);
168 while (status_->check(*state_)) {
170 model_->setData(obj,*state_->iterateVec,*state_->gradientVec,tol0);
177 tol = std::min(tol1_,tol2_*std::pow(state_->gnorm,spexp_));
179 pwa5->set(state_->gradientVec->dual());
180 snorm = dtrpcg(*state_->stepVec,SPflag_,SPiter_,*state_->gradientVec,x,*pwa5,
181 state_->searchSize,*model_,bnd,tol,stol,
182 *pwa1,*dwa1,*pwa2,*dwa2,*pwa3,*pwa4,*dwa3,outStream);
183 if (verbosity_ > 1) {
184 outStream <<
" Computation of CG step" << std::endl;
185 outStream <<
" CG step length: " << snorm << std::endl;
186 outStream <<
" Number of CG iterations: " << SPiter_ << std::endl;
187 outStream <<
" CG flag: " << SPflag_ << std::endl;
188 outStream << std::endl;
192 snorm = dgpstep(*pwa1,*state_->stepVec,x,one,outStream);
193 alpha = std::max(alphaMax_, one-snorm);
195 state_->stepVec->set(*pwa1);
196 state_->snorm = alpha * snorm;
197 x.
plus(*state_->stepVec);
200 model_->hessVec(*dwa1,*pwa1,x,tol); nhess_++;
201 gs = state_->gradientVec->apply(*state_->stepVec);
202 sBs = dwa1->apply(*state_->stepVec);
203 pRed = - half * sBs - gs;
207 ftrial = obj.
value(x,tol0);
212 TRUtils::analyzeRatio<Real>(rho,TRflag_,state_->value,ftrial,pRed,eps_,outStream,verbosity_>1);
214 TRUtils::analyzeRatio<Real>(rhoNM,TRflagNM,fr,ftrial,pRed+sigmar,eps_,outStream,verbosity_>1);
215 TRflag_ = (rho < rhoNM ? TRflagNM : TRflag_);
216 rho = (rho < rhoNM ? rhoNM : rho );
223 x.
set(*state_->iterateVec);
227 state_->searchSize = TRUtils::interpolateRadius<Real>(*state_->gradientVec,*state_->stepVec,
228 state_->snorm,pRed,state_->value,ftrial,state_->searchSize,gamma0_,gamma1_,eta2_,
229 outStream,verbosity_>1);
232 state_->searchSize = gamma1_*std::min(state_->snorm,state_->searchSize);
237 state_->value = ftrial;
240 sigmac += pRed; sigmar += pRed;
241 if (ftrial < fmin) { fmin = ftrial; fc = fmin; sigmac =
zero; L = 0; }
244 if (ftrial > fc) { fc = ftrial; sigmac =
zero; }
245 if (L == storageNM_) { fr = fc; sigmar = sigmac; }
249 if (rho >= eta2_) state_->searchSize = std::min(gamma2_*state_->searchSize, delMax_);
251 dwa1->set(*state_->gradientVec);
252 obj.
gradient(*state_->gradientVec,x,tol0);
255 state_->iterateVec->set(x);
257 model_->update(x,*state_->stepVec,*dwa1,*state_->gradientVec,
258 state_->snorm,state_->iter);
262 if (verbosity_ > 0) writeOutput(outStream,writeHeader_);
267 template<
typename Real>
270 std::ostream &outStream)
const {
272 proj_->getBoundConstraint()->projectInterior(s); state_->nproj++;
273 s.
axpy(static_cast<Real>(-1),x);
277 template<
typename Real>
281 const Real del)
const {
284 Real rad = ptx*ptx + ptp*(dsq-xtx);
285 rad = std::sqrt(std::max(rad,zero));
288 sigma = (dsq-xtx)/(ptx+rad);
290 else if (rad > zero) {
291 sigma = (rad-ptx)/ptp;
299 template<
typename Real>
305 const Real tol,
const Real stol,
309 std::ostream &outStream)
const {
314 Real tol0 = std::sqrt(ROL_EPSILON<Real>());
315 const Real
zero(0), one(1), two(2);
316 Real rho(0), kappa(0), beta(0), sigma(0), alpha(0);
317 Real rtr(0), tnorm(0), sMs(0), pMp(0), sMp(0);
324 applyPrecond(r,t,x,gdual,model,bnd,tol0,dwa,pwa1);
329 pMp = (!hasEcon_ ? rho : p.
dot(p));
331 for (iter = 0; iter < maxit_; ++iter) {
333 applyHessian(q,p,x,gdual,model,bnd,tol0,pwa1,pwa2);
337 alpha = (kappa>
zero) ? rho/kappa :
zero;
338 sigma = dtrqsol(sMs,pMp,sMp,del);
340 if (kappa <= zero || alpha >= sigma) {
343 iflag = (kappa<=
zero) ? 2 : 3;
349 applyPrecond(r,t,x,gdual,model,bnd,tol0,dwa,pwa1);
354 if (rtr <= stol*stol || tnorm <= tol) {
355 sMs = sMs + two*alpha*sMp + alpha*alpha*pMp;
367 sMs = sMs + two*alpha*sMp + alpha*alpha*pMp;
368 sMp = beta*(sMp + alpha*pMp);
369 pMp = (!hasEcon_ ? rho : p.
dot(p)) + beta*beta*pMp;
372 if (iter == maxit_) {
378 return std::sqrt(sMs);
381 template<
typename Real>
392 template<
typename Real>
402 model.
hessVec(hv,v,x,tol); nhess_++;
403 applyC(pwa2,v,x,g,bnd,pwa1);
407 template<
typename Real>
420 template<
typename Real>
422 std::ios_base::fmtflags osFlags(os.flags());
423 if (verbosity_ > 1) {
424 os << std::string(114,
'-') << std::endl;
425 os <<
" Coleman-Li affine-scaling trust-region method status output definitions" << std::endl << std::endl;
426 os <<
" iter - Number of iterates (steps taken)" << std::endl;
427 os <<
" value - Objective function value" << std::endl;
428 os <<
" gnorm - Norm of the gradient" << std::endl;
429 os <<
" snorm - Norm of the step (update to optimization vector)" << std::endl;
430 os <<
" delta - Trust-Region radius" << std::endl;
431 os <<
" #fval - Number of times the objective function was evaluated" << std::endl;
432 os <<
" #grad - Number of times the gradient was computed" << std::endl;
433 os <<
" #hess - Number of times the Hessian was applied" << std::endl;
434 os <<
" #proj - Number of times the projection was applied" << std::endl;
436 os <<
" tr_flag - Trust-Region flag" << std::endl;
442 os <<
" iterCG - Number of Truncated CG iterations" << std::endl << std::endl;
443 os <<
" flagGC - Trust-Region Truncated CG flag" << std::endl;
448 os << std::string(114,
'-') << std::endl;
451 os << std::setw(6) << std::left <<
"iter";
452 os << std::setw(15) << std::left <<
"value";
453 os << std::setw(15) << std::left <<
"gnorm";
454 os << std::setw(15) << std::left <<
"snorm";
455 os << std::setw(15) << std::left <<
"delta";
456 os << std::setw(10) << std::left <<
"#fval";
457 os << std::setw(10) << std::left <<
"#grad";
458 os << std::setw(10) << std::left <<
"#hess";
459 os << std::setw(10) << std::left <<
"#proj";
460 os << std::setw(10) << std::left <<
"tr_flag";
461 os << std::setw(10) << std::left <<
"iterCG";
462 os << std::setw(10) << std::left <<
"flagCG";
467 template<
typename Real>
469 std::ios_base::fmtflags osFlags(os.flags());
470 os << std::endl <<
"Coleman-Li Affine-Scaling Trust-Region Method (Type B, Bound Constraints)" << std::endl;
474 template<
typename Real>
476 std::ios_base::fmtflags osFlags(os.flags());
477 os << std::scientific << std::setprecision(6);
478 if ( state_->iter == 0 ) writeName(os);
479 if ( write_header ) writeHeader(os);
480 if ( state_->iter == 0 ) {
482 os << std::setw(6) << std::left << state_->iter;
483 os << std::setw(15) << std::left << state_->value;
484 os << std::setw(15) << std::left << state_->gnorm;
485 os << std::setw(15) << std::left <<
"---";
486 os << std::setw(15) << std::left << state_->searchSize;
487 os << std::setw(10) << std::left << state_->nfval;
488 os << std::setw(10) << std::left << state_->ngrad;
489 os << std::setw(10) << std::left << nhess_;
490 os << std::setw(10) << std::left << state_->nproj;
491 os << std::setw(10) << std::left <<
"---";
492 os << std::setw(10) << std::left <<
"---";
493 os << std::setw(10) << std::left <<
"---";
498 os << std::setw(6) << std::left << state_->iter;
499 os << std::setw(15) << std::left << state_->value;
500 os << std::setw(15) << std::left << state_->gnorm;
501 os << std::setw(15) << std::left << state_->snorm;
502 os << std::setw(15) << std::left << state_->searchSize;
503 os << std::setw(10) << std::left << state_->nfval;
504 os << std::setw(10) << std::left << state_->ngrad;
505 os << std::setw(10) << std::left << nhess_;
506 os << std::setw(10) << std::left << state_->nproj;
507 os << std::setw(10) << std::left << TRflag_;
508 os << std::setw(10) << std::left << SPiter_;
509 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.
Real dtrpcg(Vector< Real > &w, int &iflag, int &iter, const Vector< Real > &g, const Vector< Real > &x, const Vector< Real > &gdual, const Real del, TrustRegionModel_U< Real > &model, BoundConstraint< Real > &bnd, const Real tol, const Real stol, Vector< Real > &p, Vector< Real > &q, Vector< Real > &r, Vector< Real > &t, Vector< Real > &pwa1, Vector< Real > &pwa2, Vector< Real > &dwa, std::ostream &outStream=std::cout) const
void writeHeader(std::ostream &os) const override
Print iterate header.
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.
void writeName(std::ostream &os) const override
Print step name.
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()
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.
virtual void applyInverseScalingFunction(Vector< Real > &dv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g) const
Apply inverse scaling function.
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
std::string NumberToString(T Number)
void applyC(Vector< Real > &Cv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g, BoundConstraint< Real > &bnd, Vector< Real > &pwa) const
Provides the interface to evaluate trust-region model functions.
Real dgpstep(Vector< Real > &s, const Vector< Real > &w, const Vector< Real > &x, const Real alpha, std::ostream &outStream=std::cout) const
Provides interface for and implements limited-memory secant operators.
Real dtrqsol(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)
void writeOutput(std::ostream &os, const bool write_header=false) const override
Print iterate status.
Provides the interface to apply upper and lower bound constraints.
Real optimalityCriterion(const Vector< Real > &x, const Vector< Real > &g, Vector< Real > &primal, std::ostream &outStream=std::cout) const
void initialize(const Vector< Real > &x, const Vector< Real > &g)
virtual void applyScalingFunctionJacobian(Vector< Real > &dv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g) const
Apply scaling function Jacobian.
void applyHessian(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g, TrustRegionModel_U< Real > &model, BoundConstraint< Real > &bnd, Real &tol, Vector< Real > &pwa1, Vector< Real > &pwa2) const
virtual void set(const Vector &x)
Set where .
virtual Real norm() const =0
Returns where .
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...
ColemanLiAlgorithm(ParameterList &list, const Ptr< Secant< Real >> &secant=nullPtr)
void initialize(Vector< Real > &x, const Vector< Real > &g, Objective< Real > &obj, BoundConstraint< Real > &bnd, std::ostream &outStream=std::cout)
virtual void precond(Vector< Real > &Pv, const Vector< Real > &v, const Vector< Real > &s, Real &tol) override
Apply preconditioner to vector.
void applyPrecond(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g, TrustRegionModel_U< Real > &model, BoundConstraint< Real > &bnd, Real &tol, Vector< Real > &dwa, Vector< Real > &pwa) const