44 #ifndef ROL_TRUSTREGIONSTEP_H
45 #define ROL_TRUSTREGIONSTEP_H
128 template <
class Real>
186 ROL::ParameterList &slist = parlist.sublist(
"Step");
187 ROL::ParameterList &list = slist.sublist(
"Trust Region");
188 step_state->searchSize = list.get(
"Initial Radius",
static_cast<Real
>(-1));
189 delMax_ = list.get(
"Maximum Radius",
static_cast<Real
>(1.e8));
191 ROL::ParameterList &glist = parlist.sublist(
"General");
193 useInexact_.push_back(glist.get(
"Inexact Objective Function",
false));
194 useInexact_.push_back(glist.get(
"Inexact Gradient",
false));
195 useInexact_.push_back(glist.get(
"Inexact Hessian-Times-A-Vector",
false));
197 ROL::ParameterList &ilist = list.sublist(
"Inexact").sublist(
"Gradient");
198 scale0_ = ilist.get(
"Tolerance Scaling",
static_cast<Real
>(0.1));
199 scale1_ = ilist.get(
"Relative Tolerance",
static_cast<Real
>(2));
206 scaleEps_ = glist.get(
"Scale for Epsilon Active Sets",
static_cast<Real
>(1));
209 max_fval_ = list.sublist(
"Post-Smoothing").get(
"Function Evaluation Limit", 20);
210 alpha_init_ = list.sublist(
"Post-Smoothing").get(
"Initial Step Size",
static_cast<Real
>(1));
211 mu_ = list.sublist(
"Post-Smoothing").get(
"Tolerance",
static_cast<Real
>(0.9999));
212 beta_ = list.sublist(
"Post-Smoothing").get(
"Rate",
static_cast<Real
>(0.01));
214 stepBackMax_ = list.sublist(
"Coleman-Li").get(
"Maximum Step Back",
static_cast<Real
>(0.9999));
215 stepBackScale_ = list.sublist(
"Coleman-Li").get(
"Maximum Step Scale",
static_cast<Real
>(1));
216 singleReflect_ = list.sublist(
"Coleman-Li").get(
"Single Reflection",
true);
250 Real gtol1 =
scale0_*state->searchSize;
252 Real gtol0 = gtol1 + one;
253 while ( gtol0 > gtol1 ) {
254 obj.
gradient(*(state->gradientVec),x,gtol1);
257 gtol1 =
scale0_*std::min(algo_state.
gnorm,state->searchSize);
262 Real gtol = std::sqrt(ROL_EPSILON<Real>());
263 obj.
gradient(*(state->gradientVec),x,gtol);
290 return xnew_->norm();
330 ROL::ParameterList &glist = parlist.sublist(
"General");
334 secant_ = SecantFactory<Real>(parlist);
363 ROL::ParameterList &glist = parlist.sublist(
"General");
366 if ( ROL::is_nullPtr(
secant_) ) {
367 ROL::ParameterList Slist;
368 Slist.sublist(
"General").sublist(
"Secant").set(
"Type",
"Limited-Memory BFGS");
369 Slist.sublist(
"General").sublist(
"Secant").set(
"Maximum Storage",10);
370 secant_ = SecantFactory<Real>(Slist);
388 Real p1(0.1), oe10(1.e10),
zero(0), one(1), half(0.5), three(3), two(2), six(6);
394 Real htol = std::sqrt(ROL_EPSILON<Real>());
395 Real ftol = p1*ROL_OVERFLOW<Real>();
397 step_state->descentVec = s.
clone();
398 step_state->gradientVec = g.
clone();
415 algo_state.
snorm = oe10;
418 algo_state.
gnorm = ROL_INF<Real>();
425 Ptr<Vector<Real>> v = g.
clone();
426 Ptr<Vector<Real>> hv = x.
clone();
429 catch (std::exception &e) {
435 bool autoRad =
false;
436 if ( step_state->searchSize <=
zero ) {
438 Ptr<Vector<Real>> Bg = g.
clone();
440 secant_->applyB(*Bg,(step_state->gradientVec)->dual());
443 obj.
hessVec(*Bg,(step_state->gradientVec)->dual(),x,htol);
445 Real gBg = Bg->dot(*(step_state->gradientVec));
447 if ( gBg > ROL_EPSILON<Real>() ) {
448 alpha = algo_state.
gnorm*algo_state.
gnorm/gBg;
451 Ptr<Vector<Real>> cp = s.
clone();
452 cp->set((step_state->gradientVec)->dual());
454 Ptr<Vector<Real>> xcp = x.
clone();
461 Real fnew = obj.
value(*xcp,ftol);
464 Real gs = cp->dot((step_state->gradientVec)->dual());
465 Real a = fnew - algo_state.
value - gs - half*alpha*alpha*gBg;
466 if ( std::abs(a) < ROL_EPSILON<Real>() ) {
468 step_state->searchSize = std::min(alpha*algo_state.
gnorm,
delMax_);
471 Real b = half*alpha*alpha*gBg;
473 if ( b*b-three*a*c > ROL_EPSILON<Real>() ) {
475 Real t1 = (-b-std::sqrt(b*b-three*a*c))/(three*a);
476 Real t2 = (-b+std::sqrt(b*b-three*a*c))/(three*a);
477 if ( six*a*t1 + two*b >
zero ) {
479 step_state->searchSize = std::min(t1*alpha*algo_state.
gnorm,
delMax_);
483 step_state->searchSize = std::min(t2*alpha*algo_state.
gnorm,
delMax_);
487 step_state->searchSize = std::min(alpha*algo_state.
gnorm,
delMax_);
490 if (step_state->searchSize <= ROL_EPSILON<Real>()*algo_state.
gnorm && autoRad) {
491 step_state->searchSize = one;
497 model_ = makePtr<KelleySachsModel<Real>>(obj,
500 *(step_state->gradientVec),
506 model_ = makePtr<ColemanLiModel<Real>>(obj,
509 *(step_state->gradientVec),
518 model_ = makePtr<LinMoreModel<Real>>(obj,
521 *(step_state->gradientVec),
527 ROL_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
528 ">>> ERROR (TrustRegionStep): Invalid trust-region model!");
532 model_ = makePtr<TrustRegionModel<Real>>(obj,
535 *(step_state->gradientVec),
562 Real eps =
scaleEps_ * std::min(std::pow(algo_state.
gnorm,
static_cast<Real
>(0.75)),
563 static_cast<Real
>(0.001));
564 dynamicPtrCast<KelleySachsModel<Real>>(
model_)->setEpsilon(eps);
567 dynamicPtrCast<ColemanLiModel<Real>>(
model_)->setRadius(step_state->searchSize);
602 Real fold = algo_state.
value;
606 s,algo_state.
snorm,fold,*(state->gradientVec),algo_state.
iter,
608 algo_state.
nfval += state->nfval;
609 algo_state.
ngrad += state->ngrad;
610 state->flag =
static_cast<int>(
TRflag_);
619 Real tol = std::sqrt(ROL_EPSILON<Real>());
635 while ( (fnew-ftmp) <=
mu_*(fnew-fold) ) {
654 gp_->set(*(state->gradientVec));
679 algo_state.
value = fnew;
687 std::stringstream hist;
690 hist << std::string(114,
'-') <<
"\n";
692 hist <<
"Trust-Region status output definitions\n\n";
694 hist <<
" iter - Number of iterates (steps taken) \n";
695 hist <<
" value - Objective function value \n";
696 hist <<
" gnorm - Norm of the gradient\n";
697 hist <<
" snorm - Norm of the step (update to optimization vector)\n";
698 hist <<
" delta - Trust-Region radius\n";
699 hist <<
" #fval - Number of times the objective function was evaluated\n";
700 hist <<
" #grad - Number of times the gradient was computed\n";
705 hist <<
" tr_flag - Trust-Region flag" <<
"\n";
714 hist <<
" iterCG - Number of Truncated CG iterations\n\n";
715 hist <<
" flagGC - Trust-Region Truncated CG flag" <<
"\n";
722 hist << std::string(114,
'-') <<
"\n";
726 hist << std::setw(6) << std::left <<
"iter";
727 hist << std::setw(15) << std::left <<
"value";
728 hist << std::setw(15) << std::left <<
"gnorm";
729 hist << std::setw(15) << std::left <<
"snorm";
730 hist << std::setw(15) << std::left <<
"delta";
731 hist << std::setw(10) << std::left <<
"#fval";
732 hist << std::setw(10) << std::left <<
"#grad";
733 hist << std::setw(10) << std::left <<
"tr_flag";
735 hist << std::setw(10) << std::left <<
"iterCG";
736 hist << std::setw(10) << std::left <<
"flagCG";
747 std::stringstream hist;
779 std::stringstream hist;
780 hist << std::scientific << std::setprecision(6);
781 if ( algo_state.
iter == 0 ) {
784 if ( print_header ) {
787 if ( algo_state.
iter == 0 ) {
789 hist << std::setw(6) << std::left << algo_state.
iter;
790 hist << std::setw(15) << std::left << algo_state.
value;
791 hist << std::setw(15) << std::left << algo_state.
gnorm;
792 hist << std::setw(15) << std::left <<
" ";
793 hist << std::setw(15) << std::left << step_state->searchSize;
798 hist << std::setw(6) << std::left << algo_state.
iter;
799 hist << std::setw(15) << std::left << algo_state.
value;
800 hist << std::setw(15) << std::left << algo_state.
gnorm;
801 hist << std::setw(15) << std::left << algo_state.
snorm;
802 hist << std::setw(15) << std::left << step_state->searchSize;
803 hist << std::setw(10) << std::left << algo_state.
nfval;
804 hist << std::setw(10) << std::left << algo_state.
ngrad;
805 hist << std::setw(10) << std::left <<
TRflag_;
807 hist << std::setw(10) << std::left <<
SPiter_;
808 hist << std::setw(10) << std::left <<
SPflag_;