57 std::ostream &outStream) {
59 if (proj_ == nullPtr) {
60 proj_ = makePtr<PolyhedralProjection<Real>>(makePtrFromRef(bnd));
66 list.sublist(
"General").sublist(
"Krylov").set(
"Absolute Tolerance", atolKrylov_);
67 list.sublist(
"General").sublist(
"Krylov").set(
"Relative Tolerance", rtolKrylov_);
68 list.sublist(
"General").sublist(
"Krylov").set(
"Iteration Limit", maxitKrylov_);
69 krylovName_ =
"GMRES";
70 krylov_ = makePtr<GMRES<Real>>(list);
74 krylov_ = makePtr<ConjugateResiduals<Real>>(atolKrylov_,rtolKrylov_,maxitKrylov_);
81 Real ftol = std::sqrt(ROL_EPSILON<Real>());
82 proj_->project(x,outStream);
83 state_->iterateVec->set(x);
85 state_->value = obj.
value(x,ftol); state_->nfval++;
86 obj.
gradient(*state_->gradientVec,x,ftol); state_->ngrad++;
87 state_->stepVec->set(x);
88 state_->stepVec->axpy(-one,state_->gradientVec->dual());
89 proj_->project(*state_->stepVec,outStream);
90 state_->stepVec->axpy(-one,x);
91 state_->gnorm = state_->stepVec->norm();
92 state_->snorm = ROL_INF<Real>();
100 std::ostream &outStream ) {
101 const Real
zero(0), one(1);
103 initialize(x,g,obj,bnd,outStream);
105 Ptr<Vector<Real>> lambda = x.
clone(), gtmp = g.
clone();
106 Ptr<Vector<Real>> pwa = x.
clone(), dwa = g.
clone();
107 Ptr<Vector<Real>> mu, b, r;
109 mu = proj_->getMultiplier()->clone(); mu->zero();
110 b = proj_->getResidual()->clone();
111 r = proj_->getResidual()->clone();
113 lambda->set(state_->gradientVec->dual());
115 Real xnorm(0), snorm(0), rnorm(0), tol(std::sqrt(ROL_EPSILON<Real>()));
117 Ptr<LinearOperator<Real>> hessian, precond;
120 if (verbosity_ > 0) writeOutput(outStream,
true);
122 while (status_->check(*state_)) {
124 state_->stepVec->zero();
127 proj_->getLinearConstraint()->value(*r,x,tol);
129 for ( iter_ = 0; iter_ < maxit_; iter_++ ) {
134 xlam->axpy(scale_,*lambda);
141 xtmp->axpy(-one,*state_->iterateVec);
146 xtmp->axpy(-one,*state_->iterateVec);
152 if ( useSecantHessVec_ && secant_ != nullPtr ) {
153 secant_->applyB(*gtmp,*As);
156 obj.
hessVec(*gtmp,*As,*state_->iterateVec,itol_);
159 proj_->getLinearConstraint()->applyJacobian(*b,*As,*state_->iterateVec,tol);
163 gtmp->plus(*state_->gradientVec);
170 rnorm = std::sqrt(gtmp->dot(*gtmp)+b->dot(*b));
173 rnorm = gtmp->norm();
175 if ( rnorm >
zero ) {
178 hessian = makePtr<HessianPDAS_Poly>(makePtrFromRef(obj),makePtrFromRef(bnd),
179 proj_->getLinearConstraint(),state_->iterateVec,xlam,neps_,secant_,
180 useSecantHessVec_,pwa,dwa);
181 precond = makePtr<PrecondPDAS_Poly>(makePtrFromRef(obj),makePtrFromRef(bnd),
182 state_->iterateVec,xlam,neps_,secant_,useSecantPrecond_,dwa);
185 krylov_->run(sol,*hessian,rhs,*precond,iterKrylov_,flagKrylov_);
189 hessian = makePtr<HessianPDAS>(makePtrFromRef(obj),makePtrFromRef(bnd),
190 state_->iterateVec,xlam,neps_,secant_,useSecantHessVec_,pwa);
191 precond = makePtr<PrecondPDAS>(makePtrFromRef(obj),makePtrFromRef(bnd),
192 state_->iterateVec,xlam,neps_,secant_,useSecantPrecond_,dwa);
193 krylov_->run(*state_->stepVec,*hessian,*gtmp,*precond,iterKrylov_,flagKrylov_);
195 totalKrylov_ += iterKrylov_;
198 state_->stepVec->plus(*As);
202 x.
set(*state_->iterateVec);
203 x.
plus(*state_->stepVec);
204 snorm = state_->stepVec->norm();
206 if ( useSecantHessVec_ && secant_ != nullPtr ) {
207 secant_->applyB(*gtmp,*state_->stepVec);
210 obj.
hessVec(*gtmp,*state_->stepVec,*state_->iterateVec,itol_);
213 proj_->getLinearConstraint()->applyAdjointJacobian(*dwa,*mu,*state_->iterateVec,tol);
216 gtmp->plus(*state_->gradientVec);
218 lambda->set(gtmp->dual());
227 if ( xtmp->norm() < gtol_*state_->gnorm ) {
231 if ( snorm < stol_*xnorm ) {
236 if ( iter_ == maxit_ ) {
245 state_->iterateVec->set(x);
247 state_->snorm = snorm;
249 state_->value = obj.
value(x,tol); state_->nfval++;
251 if ( secant_ != nullPtr ) {
252 gtmp->set(*state_->gradientVec);
254 obj.
gradient(*state_->gradientVec,x,tol); state_->ngrad++;
255 xtmp->set(x); xtmp->axpy(-one,state_->gradientVec->dual());
256 proj_->project(*xtmp,outStream);
258 state_->gnorm = xtmp->norm();
259 if ( secant_ != nullPtr ) {
260 secant_->updateStorage(x,*state_->gradientVec,*gtmp,*state_->stepVec,state_->snorm,state_->iter+1);
264 if (verbosity_ > 0) writeOutput(outStream,writeHeader_);
271 std::ios_base::fmtflags osFlags(os.flags());
272 if (verbosity_ > 1) {
273 os << std::string(114,
'-') << std::endl;
274 if (!useSecantHessVec_) {
275 os <<
"Primal Dual Active Set Newton's Method";
278 os <<
"Primal Dual Active Set Quasi-Newton Method with " << secantName_ <<
" Hessian approximation";
280 os <<
" status output definitions" << std::endl << std::endl;
281 os <<
" iter - Number of iterates (steps taken)" << std::endl;
282 os <<
" value - Objective function value" << std::endl;
283 os <<
" gnorm - Norm of the gradient" << std::endl;
284 os <<
" snorm - Norm of the step (update to optimization vector)" << std::endl;
285 os <<
" #fval - Cumulative number of times the objective function was evaluated" << std::endl;
286 os <<
" #grad - Cumulative number of times the gradient was computed" << std::endl;
288 os <<
" iterPDAS - Number of Primal Dual Active Set iterations" << std::endl << std::endl;
289 os <<
" flagPDAS - Primal Dual Active Set flag" << std::endl;
290 os <<
" iterK - Number of Krylov iterations" << std::endl << std::endl;
293 os <<
" iterK - Number of Krylov iterations" << std::endl << std::endl;
294 os <<
" flagK - Krylov flag" << std::endl;
300 os <<
" feasible - Is iterate feasible?" << std::endl;
301 os << std::string(114,
'-') << std::endl;
305 os << std::setw(6) << std::left <<
"iter";
306 os << std::setw(15) << std::left <<
"value";
307 os << std::setw(15) << std::left <<
"gnorm";
308 os << std::setw(15) << std::left <<
"snorm";
309 os << std::setw(10) << std::left <<
"#fval";
310 os << std::setw(10) << std::left <<
"#grad";
312 os << std::setw(10) << std::left <<
"iterPDAS";
313 os << std::setw(10) << std::left <<
"flagPDAS";
314 os << std::setw(10) << std::left <<
"iterK";
317 os << std::setw(10) << std::left <<
"iterK";
318 os << std::setw(10) << std::left <<
"flagK";
320 os << std::setw(10) << std::left <<
"feasible";
340 std::ios_base::fmtflags osFlags(os.flags());
341 os << std::scientific << std::setprecision(6);
342 if ( state_->iter == 0 ) writeName(os);
343 if ( write_header ) writeHeader(os);
344 if ( state_->iter == 0 ) {
346 os << std::setw(6) << std::left << state_->iter;
347 os << std::setw(15) << std::left << state_->value;
348 os << std::setw(15) << std::left << state_->gnorm;
349 os << std::setw(15) << std::left <<
"---";
350 os << std::setw(10) << std::left << state_->nfval;
351 os << std::setw(10) << std::left << state_->ngrad;
352 os << std::setw(10) << std::left <<
"---";
353 os << std::setw(10) << std::left <<
"---";
355 os << std::setw(10) << std::left <<
"---";
358 os << std::setw(10) << std::left <<
"YES";
361 os << std::setw(10) << std::left <<
"NO";
367 os << std::setw(6) << std::left << state_->iter;
368 os << std::setw(15) << std::left << state_->value;
369 os << std::setw(15) << std::left << state_->gnorm;
370 os << std::setw(15) << std::left << state_->snorm;
371 os << std::setw(10) << std::left << state_->nfval;
372 os << std::setw(10) << std::left << state_->ngrad;
374 os << std::setw(10) << std::left << iter_;
375 os << std::setw(10) << std::left << flag_;
376 os << std::setw(10) << std::left << totalKrylov_;
379 os << std::setw(10) << std::left << iterKrylov_;
380 os << std::setw(10) << std::left << flagKrylov_;
383 os << std::setw(10) << std::left <<
"YES";
386 os << std::setw(10) << std::left <<
"NO";