ROL
ROL_TrustRegionUtilities.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #ifndef ROL_TRUSTREGIONUTILITIES_U_H
45 #define ROL_TRUSTREGIONUTILITIES_U_H
46 
48 
49 namespace ROL {
50 namespace TRUtils {
51 
62 enum ETRFlag {
63  SUCCESS = 0,
70 };
71 
72 inline std::string ETRFlagToString(ETRFlag trf) {
73  std::string retString;
74  switch(trf) {
75  case SUCCESS:
76  retString = "Both actual and predicted reductions are positive (success)";
77  break;
78  case POSPREDNEG:
79  retString = "Actual reduction is positive and predicted reduction is negative (impossible)";
80  break;
81  case NPOSPREDPOS:
82  retString = "Actual reduction is nonpositive and predicted reduction is positive";
83  break;
84  case NPOSPREDNEG:
85  retString = "Actual reduction is nonpositive and predicted reduction is negative (impossible)";
86  break;
87  case TRNAN:
88  retString = "Actual and/or predicted reduction is a NaN";
89  break;
90  case QMINSUFDEC:
91  retString = "Subproblem solution did not produce sufficient decrease";
92  break;
93  default:
94  retString = "INVALID ETRFlag";
95  }
96  return retString;
97 }
98 
99 template<typename Real>
100 inline Real initialRadius(int &nfval,
101  const Vector<Real> &x,
102  const Vector<Real> &g,
103  Vector<Real> &Bg,
104  const Real fx,
105  const Real gnorm,
106  const Real gtol,
107  Objective<Real> &obj,
109  const Real delMax,
110  std::ostream &outStream,
111  const bool print = false) {
112  const Real zero(0), half(0.5), one(1), two(2), three(3), six(6);
113  const Real eps(ROL_EPSILON<Real>());
114  Real del(ROL_INF<Real>());
115  Real htol = gtol;
116  Ptr<Vector<Real>> xcp = x.clone();
117  model.setData(obj,x,g,htol);
118  model.hessVec(Bg,g.dual(),x,htol);
119  Real gBg = Bg.dot(g);
120  Real alpha = (gBg > eps ? gnorm*gnorm/gBg : one);
121  // Evaluate the objective function at the Cauchy point
122  xcp->set(g.dual());
123  xcp->scale(-alpha);
124  //Real gs = xcp->dot(g.dual());
125  Real gs = xcp->apply(g);
126  xcp->plus(x);
127  obj.update(*xcp,UpdateType::Temp);
128  Real ftol = static_cast<Real>(0.1)*ROL_OVERFLOW<Real>();
129  Real fnew = obj.value(*xcp,ftol); // MUST DO SOMETHING HERE WITH FTOL
130  nfval++;
131  // Perform cubic interpolation to determine initial trust region radius
132  Real a = fnew - fx - gs - half*alpha*alpha*gBg;
133  if ( std::abs(a) < eps ) {
134  // a = 0 implies the objective is quadratic in the negative gradient direction
135  del = std::min(alpha*gnorm,delMax);
136  }
137  else {
138  Real b = half*alpha*alpha*gBg;
139  Real c = gs;
140  if ( b*b-three*a*c > eps ) {
141  // There is at least one critical point
142  Real t1 = (-b-std::sqrt(b*b-three*a*c))/(three*a);
143  Real t2 = (-b+std::sqrt(b*b-three*a*c))/(three*a);
144  if ( six*a*t1 + two*b > zero ) {
145  // t1 is the minimizer
146  del = std::min(t1*alpha*gnorm,delMax);
147  }
148  else {
149  // t2 is the minimizer
150  del = std::min(t2*alpha*gnorm,delMax);
151  }
152  }
153  else {
154  del = std::min(alpha*gnorm,delMax);
155  }
156  }
157  if (del <= eps*gnorm) {
158  del = one;
159  }
160  obj.update(x,UpdateType::Revert);
161  if ( print ) {
162  outStream << " In TrustRegionUtilities::initialRadius" << std::endl;
163  outStream << " Initial radius: " << del << std::endl;
164  }
165  return del;
166 }
167 
168 template<typename Real>
169 inline void analyzeRatio(Real &rho,
170  ETRFlag &flag,
171  const Real fold,
172  const Real ftrial,
173  const Real pRed,
174  const Real epsi,
175  std::ostream &outStream = std::cout,
176  const bool print = false) {
177  const Real zero(0), one(1);
178  Real eps = epsi*std::max(one,fold);
179  Real aRed = fold - ftrial;
180  Real aRed_safe = aRed + eps, pRed_safe = pRed + eps;
181  if (((std::abs(aRed_safe) < epsi) && (std::abs(pRed_safe) < epsi)) || aRed == pRed) {
182  rho = one;
183  flag = SUCCESS;
184  }
185  else if ( std::isnan(aRed_safe) || std::isnan(pRed_safe) ) {
186  rho = -one;
187  flag = TRNAN;
188  }
189  else {
190  rho = aRed_safe/pRed_safe;
191  if (pRed_safe < zero && aRed_safe > zero) {
192  flag = POSPREDNEG;
193  }
194  else if (aRed_safe <= zero && pRed_safe > zero) {
195  flag = NPOSPREDPOS;
196  }
197  else if (aRed_safe <= zero && pRed_safe < zero) {
198  flag = NPOSPREDNEG;
199  }
200  else {
201  flag = SUCCESS;
202  }
203  }
204  if ( print ) {
205  outStream << " In TrustRegionUtilities::analyzeRatio" << std::endl;
206  outStream << " Current objective function value: " << fold << std::endl;
207  outStream << " New objective function value: " << ftrial << std::endl;
208  outStream << " Actual reduction: " << aRed << std::endl;
209  outStream << " Predicted reduction: " << pRed << std::endl;
210  outStream << " Safeguard: " << epsi << std::endl;
211  outStream << " Actual reduction with safeguard: " << aRed_safe << std::endl;
212  outStream << " Predicted reduction with safeguard: " << pRed_safe << std::endl;
213  outStream << " Ratio of actual and predicted reduction: " << rho << std::endl;
214  outStream << " Trust-region flag: " << flag << std::endl;
215  outStream << std::endl;
216  }
217 }
218 
219 template<typename Real>
220 inline Real interpolateRadius(const Vector<Real> &g,
221  const Vector<Real> &s,
222  const Real snorm,
223  const Real pRed,
224  const Real fold,
225  const Real ftrial,
226  const Real del,
227  const Real gamma0,
228  const Real gamma1,
229  const Real eta2,
230  std::ostream &outStream = std::cout,
231  const bool print = false) {
232  const Real one(1);
233  //Real gs = g.dot(s.dual());
234  Real gs = g.apply(s);
235  Real modelVal = fold - pRed;
236  Real theta = (one-eta2)*gs/((one-eta2)*(fold+gs)+eta2*modelVal-ftrial);
237  if ( print ) {
238  outStream << " In TrustRegionUtilities::interpolateRadius" << std::endl;
239  outStream << " Interpolation model value: " << modelVal << std::endl;
240  outStream << " Interpolation step length: " << theta << std::endl;
241  outStream << std::endl;
242  }
243  return std::min(gamma1*std::min(snorm,del),std::max(gamma0,theta)*del);
244 }
245 
246 } // namespace TrustRegion
247 } // namespace ROL
248 
249 
250 #endif
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...
Definition: ROL_Vector.hpp:226
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Real interpolateRadius(const Vector< Real > &g, const Vector< Real > &s, const Real snorm, const Real pRed, const Real fold, const Real ftrial, const Real del, const Real gamma0, const Real gamma1, const Real eta2, std::ostream &outStream=std::cout, const bool print=false)
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
Definition: ROL_Vector.hpp:238
virtual Real value(const Vector< Real > &x, Real &tol)=0
Compute value.
Real initialRadius(int &nfval, const Vector< Real > &x, const Vector< Real > &g, Vector< Real > &Bg, const Real fx, const Real gnorm, const Real gtol, Objective< Real > &obj, TrustRegionModel_U< Real > &model, const Real delMax, std::ostream &outStream, const bool print=false)
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
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.
Provides the interface to evaluate trust-region model functions.
std::string ETRFlagToString(ETRFlag trf)
void analyzeRatio(Real &rho, ETRFlag &flag, const Real fold, const Real ftrial, const Real pRed, const Real epsi, std::ostream &outStream=std::cout, const bool print=false)
virtual void setData(Objective< Real > &obj, const Vector< Real > &x, const Vector< Real > &g, Real &tol)