ROL
ROL_TruncatedCG.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Rapid Optimization Library (ROL) Package
4//
5// Copyright 2014 NTESS and the ROL contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef ROL_TRUNCATEDCG_H
11#define ROL_TRUNCATEDCG_H
12
17#include "ROL_TrustRegion.hpp"
18#include "ROL_Types.hpp"
19
20namespace ROL {
21
22template<class Real>
23class TruncatedCG : public TrustRegion<Real> {
24private:
25 ROL::Ptr<Vector<Real> > primalVector_;
26
27 ROL::Ptr<Vector<Real> > s_;
28 ROL::Ptr<Vector<Real> > g_;
29 ROL::Ptr<Vector<Real> > v_;
30 ROL::Ptr<Vector<Real> > p_;
31 ROL::Ptr<Vector<Real> > Hp_;
32
33 int maxit_;
34 Real tol1_;
35 Real tol2_;
36
37 Real pRed_;
38
39public:
40
41 // Constructor
42 TruncatedCG( ROL::ParameterList &parlist ) : TrustRegion<Real>(parlist), pRed_(0) {
43 // Unravel Parameter List
44 Real em4(1e-4), em2(1e-2);
45 maxit_ = parlist.sublist("General").sublist("Krylov").get("Iteration Limit",20);
46 tol1_ = parlist.sublist("General").sublist("Krylov").get("Absolute Tolerance",em4);
47 tol2_ = parlist.sublist("General").sublist("Krylov").get("Relative Tolerance",em2);
48 }
49
50 void initialize( const Vector<Real> &x, const Vector<Real> &s, const Vector<Real> &g) {
52
53 primalVector_ = x.clone();
54
55 s_ = s.clone();
56 g_ = g.clone();
57 v_ = s.clone();
58 p_ = s.clone();
59 Hp_ = g.clone();
60 }
61
62 void run( Vector<Real> &s,
63 Real &snorm,
64 int &iflag,
65 int &iter,
66 const Real del,
67 TrustRegionModel<Real> &model ) {
68 Real tol = std::sqrt(ROL_EPSILON<Real>());
69 const Real zero(0), one(1), two(2), half(0.5);
70 // Initialize step
71 s.zero(); s_->zero();
72 snorm = zero;
73 Real snorm2(0), s1norm2(0);
74 // Compute (projected) gradient
75 model.dualTransform(*g_,*model.getGradient());
76 Real gnorm = g_->norm(), normg = gnorm;
77 const Real gtol = std::min(tol1_,tol2_*gnorm);
78 // Preconditioned (projected) gradient vector
79 model.precond(*v_,*g_,s,tol);
80 // Initialize basis vector
81 p_->set(*v_); p_->scale(-one);
82 Real pnorm2 = g_->apply(*v_);
83 if ( pnorm2 <= zero ) {
84 iflag = 4;
85 iter = 0;
86 return;
87 }
88 // Initialize scalar storage
89 iter = 0; iflag = 0;
90 Real kappa(0), beta(0), sigma(0), alpha(0), tmp(0), sMp(0);
91 Real gv = g_->apply(*v_);
92 pRed_ = zero;
93 // Iterate CG
94 for (iter = 0; iter < maxit_; iter++) {
95 // Apply Hessian to direction p
96 model.hessVec(*Hp_,*p_,s,tol);
97 // Check positivity of Hessian
98 kappa = Hp_->apply(*p_);
99 if (kappa <= zero) {
100 sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2;
101 s.axpy(sigma,*p_);
102 iflag = 2;
103 break;
104 }
105 // Update step
106 alpha = gv/kappa;
107 s_->set(s);
108 s_->axpy(alpha,*p_);
109 s1norm2 = snorm2 + two*alpha*sMp + alpha*alpha*pnorm2;
110 // Check if step exceeds trust region radius
111 if (s1norm2 >= del*del) {
112 sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2;
113 s.axpy(sigma,*p_);
114 iflag = 3;
115 break;
116 }
117 // Update model predicted reduction
118 pRed_ += half*alpha*gv;
119 // Set step to temporary step and store norm
120 s.set(*s_);
121 snorm2 = s1norm2;
122 // Check for convergence
123 g_->axpy(alpha,*Hp_);
124 normg = g_->norm();
125 if (normg < gtol) break;
126 // Preconditioned updated (projected) gradient vector
127 model.precond(*v_,*g_,s,tol);
128 tmp = gv;
129 gv = g_->apply(*v_);
130 beta = gv/tmp;
131 // Update basis vector
132 p_->scale(beta);
133 p_->axpy(-one,*v_);
134 sMp = beta*(sMp+alpha*pnorm2);
135 pnorm2 = gv + beta*beta*pnorm2;
136 }
137 // Update model predicted reduction
138 if (iflag > 0) pRed_ += sigma*(gv-half*sigma*kappa);
139 // Check iteration count
140 if (iter == maxit_) iflag = 1;
141 if (iflag != 1) iter++;
142 // Update norm of step and update model predicted reduction
143 model.primalTransform(*s_,s);
144 s.set(*s_);
145 snorm = s.norm();
147 }
148
149#if 0
150 void truncatedCG_proj( Vector<Real> &s, Real &snorm, Real &del, int &iflag, int &iter, const Vector<Real> &x,
151 const Vector<Real> &grad, const Real &gnorm, ProjectedObjective<Real> &pObj ) {
152 Real tol = std::sqrt(ROL_EPSILON<Real>());
153
154 const Real gtol = std::min(tol1_,tol2_*gnorm);
155
156 // Compute Cauchy Point
157 Real scnorm = 0.0;
158 ROL::Ptr<Vector<Real> > sc = x.clone();
159 cauchypoint(*sc,scnorm,del,iflag,iter,x,grad,gnorm,pObj);
160 ROL::Ptr<Vector<Real> > xc = x.clone();
161 xc->set(x);
162 xc->plus(*sc);
163
164 // Old and New Step Vectors
165 s.set(*sc);
166 snorm = s.norm();
167 Real snorm2 = snorm*snorm;
168 ROL::Ptr<Vector<Real> > s1 = x.clone();
169 s1->zero();
170 Real s1norm2 = 0.0;
171
172 // Gradient Vector
173 ROL::Ptr<Vector<Real> > g = x.clone();
174 g->set(grad);
175 ROL::Ptr<Vector<Real> > Hs = x.clone();
176 pObj.reducedHessVec(*Hs,s,*xc,x,tol);
177 g->plus(*Hs);
178 Real normg = g->norm();
179
180 // Preconditioned Gradient Vector
181 ROL::Ptr<Vector<Real> > v = x.clone();
182 pObj.reducedPrecond(*v,*g,*xc,x,tol);
183
184 // Basis Vector
185 ROL::Ptr<Vector<Real> > p = x.clone();
186 p->set(*v);
187 p->scale(-1.0);
188 Real pnorm2 = v->dot(*g);
189
190 // Hessian Times Basis Vector
191 ROL::Ptr<Vector<Real> > Hp = x.clone();
192
193 iter = 0;
194 iflag = 0;
195 Real kappa = 0.0;
196 Real beta = 0.0;
197 Real sigma = 0.0;
198 Real alpha = 0.0;
199 Real tmp = 0.0;
200 Real gv = v->dot(*g);
201 Real sMp = 0.0;
202 pRed_ = 0.0;
203
204 for (iter = 0; iter < maxit_; iter++) {
205 pObj.reducedHessVec(*Hp,*p,*xc,x,tol);
206
207 kappa = p->dot(*Hp);
208 if (kappa <= 0) {
209 sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2;
210 s.axpy(sigma,*p);
211 iflag = 2;
212 break;
213 }
214
215 alpha = gv/kappa;
216 s1->set(s);
217 s1->axpy(alpha,*p);
218 s1norm2 = snorm2 + 2.0*alpha*sMp + alpha*alpha*pnorm2;
219
220 if (s1norm2 >= del*del) {
221 sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2;
222 s.axpy(sigma,*p);
223 iflag = 3;
224 break;
225 }
226
227 pRed_ += 0.5*alpha*gv;
228
229 s.set(*s1);
230 snorm2 = s1norm2;
231
232 g->axpy(alpha,*Hp);
233 normg = g->norm();
234 if (normg < gtol) {
235 break;
236 }
237
238 pObj.reducedPrecond(*v,*g,*xc,x,tol);
239 tmp = gv;
240 gv = v->dot(*g);
241 beta = gv/tmp;
242
243 p->scale(beta);
244 p->axpy(-1.0,*v);
245 sMp = beta*(sMp+alpha*pnorm2);
246 pnorm2 = gv + beta*beta*pnorm2;
247 }
248 if (iflag > 0) {
249 pRed_ += sigma*(gv-0.5*sigma*kappa);
250 }
251
252 if (iter == maxit_) {
253 iflag = 1;
254 }
255 if (iflag != 1) {
256 iter++;
257 }
258
259 snorm = s.norm();
260 }
261#endif
262};
263
264}
265
266#endif
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Contains definitions of custom data types in ROL.
void reducedPrecond(Vector< Real > &Mv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &d, const Vector< Real > &x, Real &tol)
Apply the reduced preconditioner to a vector, v. The reduced preconditioner first removes elements ...
void reducedHessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &d, const Vector< Real > &x, Real &tol)
Apply the reduced Hessian to a vector, v. The reduced Hessian first removes elements of v correspondi...
Provides interface for truncated CG trust-region subproblem solver.
void initialize(const Vector< Real > &x, const Vector< Real > &s, const Vector< Real > &g)
ROL::Ptr< Vector< Real > > g_
TruncatedCG(ROL::ParameterList &parlist)
ROL::Ptr< Vector< Real > > s_
ROL::Ptr< Vector< Real > > Hp_
void run(Vector< Real > &s, Real &snorm, int &iflag, int &iter, const Real del, TrustRegionModel< Real > &model)
ROL::Ptr< Vector< Real > > primalVector_
ROL::Ptr< Vector< Real > > v_
ROL::Ptr< Vector< Real > > p_
Provides the interface to evaluate trust-region model functions.
virtual void precond(Vector< Real > &Pv, const Vector< Real > &v, const Vector< Real > &s, Real &tol)
Apply preconditioner to vector.
virtual void dualTransform(Vector< Real > &tv, const Vector< Real > &v)
virtual const Ptr< const Vector< Real > > getGradient(void) const
virtual void primalTransform(Vector< Real > &tv, const Vector< Real > &v)
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &s, Real &tol)
Apply Hessian approximation to vector.
Provides interface for and implements trust-region subproblem solvers.
virtual void initialize(const Vector< Real > &x, const Vector< Real > &s, const Vector< Real > &g)
void setPredictedReduction(const Real pRed)
Defines the linear algebra or vector space interface.
virtual Real norm() const =0
Returns where .
virtual void set(const Vector &x)
Set where .
virtual void zero()
Set to zero vector.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .