void updateObj( Vector<Real> &x, int iter, ProjectedObjective<Real> &pObj ) { if ( !softUp_ ) { pObj.update(x,true,iter); } else { pObj.update(x); } }
void run( Vector<Real> &s, Real &snorm, Real &del, int &iflag, int &iter, const Vector<Real> &x, const Vector<Real> &grad, const Real &gnorm, ProjectedObjective<Real> &pObj ) { Real tol = std::sqrt(ROL_EPSILON<Real>()); // Compute quasi-Newton step pObj.reducedInvHessVec(*s_,grad,x,grad,x,tol); s_->scale(-1.0); Real sNnorm = s_->norm(); Real gsN = s_->dot(grad.dual()); bool negCurv = false; if ( gsN >= 0.0 ) { negCurv = true; } if ( negCurv ) { cpt_->run(s,snorm,del,iflag,iter,x,grad,gnorm,pObj); pRed_ = cpt_->getPredictedReduction(); iflag = 2; } else { // Approximately solve trust region subproblem using double dogleg curve if (sNnorm <= del) { // Use the quasi-Newton step s.set(*s_); snorm = sNnorm; pRed_ = -0.5*gsN; iflag = 0; } else { // quasi-Newton step is outside of trust region pObj.reducedHessVec(*Hp_,grad.dual(),x,grad,x,tol); Real alpha = 0.0; Real beta = 0.0; Real gnorm2 = gnorm*gnorm; Real gBg = grad.dot(*Hp_); Real gamma = gnorm2/gBg; if ( gamma*gnorm >= del || gBg <= 0.0 ) { alpha = 0.0; beta = del/gnorm; s.set(grad.dual()); s.scale(-beta); snorm = del; iflag = 2; } else { Real a = sNnorm*sNnorm + 2.0*gamma*gsN + gamma*gamma*gnorm2; Real b = -gamma*gsN - gamma*gamma*gnorm2; Real c = gamma*gamma*gnorm2 - del*del; alpha = (-b + sqrt(b*b - a*c))/a; beta = gamma*(1.0-alpha); s.set(grad.dual()); s.scale(-beta); s.axpy(alpha,*s_); snorm = del; iflag = 1; } pRed_ = (alpha*(0.5*alpha-1)*gsN - 0.5*beta*beta*gBg + beta*(1-alpha)*gnorm2); } } TrustRegion<Real>::setPredictedReduction(pRed_); }
void run( Vector<Real> &s, Real &snorm, Real &del, int &iflag, int &iter, const Vector<Real> &x, const Vector<Real> &grad, const Real &gnorm, ProjectedObjective<Real> &pObj ) { Real tol = std::sqrt(ROL_EPSILON); const Real gtol = std::min(tol1_,tol2_*gnorm); // Old and New Step Vectors s.zero(); snorm = 0.0; Real snorm2 = 0.0; s_->zero(); Real s1norm2 = 0.0; // Gradient Vector g_->set(grad); Real normg = gnorm; if ( pObj.isConActivated() ) { pObj.pruneActive(*g_,grad,x); normg = g_->norm(); } // Preconditioned Gradient Vector //pObj.precond(*v,*g,x,tol); pObj.reducedPrecond(*v_,*g_,x,grad,x,tol); // Basis Vector p_->set(*v_); p_->scale(-1.0); Real pnorm2 = v_->dot(g_->dual()); iter = 0; iflag = 0; Real kappa = 0.0; Real beta = 0.0; Real sigma = 0.0; Real alpha = 0.0; Real tmp = 0.0; Real gv = v_->dot(g_->dual()); Real sMp = 0.0; pRed_ = 0.0; for (iter = 0; iter < maxit_; iter++) { //pObj.hessVec(*Hp,*p,x,tol); pObj.reducedHessVec(*Hp_,*p_,x,grad,x,tol); kappa = p_->dot(Hp_->dual()); if (kappa <= 0.0) { sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2; s.axpy(sigma,*p_); iflag = 2; break; } alpha = gv/kappa; s_->set(s); s_->axpy(alpha,*p_); s1norm2 = snorm2 + 2.0*alpha*sMp + alpha*alpha*pnorm2; if (s1norm2 >= del*del) { sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2; s.axpy(sigma,*p_); iflag = 3; break; } pRed_ += 0.5*alpha*gv; s.set(*s_); snorm2 = s1norm2; g_->axpy(alpha,*Hp_); normg = g_->norm(); if (normg < gtol) { break; } //pObj.precond(*v,*g,x,tol); pObj.reducedPrecond(*v_,*g_,x,grad,x,tol); tmp = gv; gv = v_->dot(g_->dual()); beta = gv/tmp; p_->scale(beta); p_->axpy(-1.0,*v_); sMp = beta*(sMp+alpha*pnorm2); pnorm2 = gv + beta*beta*pnorm2; } if (iflag > 0) { pRed_ += sigma*(gv-0.5*sigma*kappa); } if (iter == maxit_) { iflag = 1; } if (iflag != 1) { iter++; } snorm = s.norm(); TrustRegion<Real>::setPredictedReduction(pRed_); }
void truncatedCG_proj( Vector<Real> &s, Real &snorm, Real &del, int &iflag, int &iter, const Vector<Real> &x, const Vector<Real> &grad, const Real &gnorm, ProjectedObjective<Real> &pObj ) { Real tol = std::sqrt(ROL_EPSILON); const Real gtol = std::min(tol1_,tol2_*gnorm); // Compute Cauchy Point Real scnorm = 0.0; Teuchos::RCP<Vector<Real> > sc = x.clone(); cauchypoint(*sc,scnorm,del,iflag,iter,x,grad,gnorm,pObj); Teuchos::RCP<Vector<Real> > xc = x.clone(); xc->set(x); xc->plus(*sc); // Old and New Step Vectors s.set(*sc); snorm = s.norm(); Real snorm2 = snorm*snorm; Teuchos::RCP<Vector<Real> > s1 = x.clone(); s1->zero(); Real s1norm2 = 0.0; // Gradient Vector Teuchos::RCP<Vector<Real> > g = x.clone(); g->set(grad); Teuchos::RCP<Vector<Real> > Hs = x.clone(); pObj.reducedHessVec(*Hs,s,*xc,x,tol); g->plus(*Hs); Real normg = g->norm(); // Preconditioned Gradient Vector Teuchos::RCP<Vector<Real> > v = x.clone(); pObj.reducedPrecond(*v,*g,*xc,x,tol); // Basis Vector Teuchos::RCP<Vector<Real> > p = x.clone(); p->set(*v); p->scale(-1.0); Real pnorm2 = v->dot(*g); // Hessian Times Basis Vector Teuchos::RCP<Vector<Real> > Hp = x.clone(); iter = 0; iflag = 0; Real kappa = 0.0; Real beta = 0.0; Real sigma = 0.0; Real alpha = 0.0; Real tmp = 0.0; Real gv = v->dot(*g); Real sMp = 0.0; pRed_ = 0.0; for (iter = 0; iter < maxit_; iter++) { pObj.reducedHessVec(*Hp,*p,*xc,x,tol); kappa = p->dot(*Hp); if (kappa <= 0) { sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2; s.axpy(sigma,*p); iflag = 2; break; } alpha = gv/kappa; s1->set(s); s1->axpy(alpha,*p); s1norm2 = snorm2 + 2.0*alpha*sMp + alpha*alpha*pnorm2; if (s1norm2 >= del*del) { sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2; s.axpy(sigma,*p); iflag = 3; break; } pRed_ += 0.5*alpha*gv; s.set(*s1); snorm2 = s1norm2; g->axpy(alpha,*Hp); normg = g->norm(); if (normg < gtol) { break; } pObj.reducedPrecond(*v,*g,*xc,x,tol); tmp = gv; gv = v->dot(*g); beta = gv/tmp; p->scale(beta); p->axpy(-1.0,*v); sMp = beta*(sMp+alpha*pnorm2); pnorm2 = gv + beta*beta*pnorm2; } if (iflag > 0) { pRed_ += sigma*(gv-0.5*sigma*kappa); } if (iter == maxit_) { iflag = 1; } if (iflag != 1) { iter++; } snorm = s.norm(); }