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_OBJECTIVE_H 45 #define ROL_OBJECTIVE_H 46 47 #include "ROL_Vector.hpp" 48 #include "ROL_Types.hpp" 49 #include <iostream> 50 51 /** @ingroup func_group 52 \class ROL::Objective 53 \brief Provides the interface to evaluate objective functions. 54 55 ROL's objective function interface is designed for Fr$eacute;chet differentiable 56 functionals \f$f:\mathcal{X}\to\mathbb{R}\f$, where \f$\mathcal{X}\f$ is a Banach 57 space. The basic operator interace, to be implemented by the user, requires: 58 \li #value -- objective function evaluation. 59 60 It is strongly recommended that the user additionally overload: 61 \li #gradient -- the objective function gradient -- the default is a finite-difference approximation; 62 \li #hessVec -- the action of the Hessian -- the default is a finite-difference approximation. 63 64 The user may also overload: 65 \li #update -- update the objective function at each new iteration; 66 \li #dirDeriv -- compute the directional derivative -- the default is a finite-difference approximation; 67 \li #invHessVec -- the action of the inverse Hessian; 68 \li #precond -- the action of a preconditioner for the Hessian. 69 70 --- 71 */ 72 73 74 namespace ROL { 75 76 template <class Real> 77 class Objective { 78 public: 79 ~Objective()80 virtual ~Objective() {} 81 82 /** \brief Update objective function. 83 84 This function updates the objective function at new iterations. 85 @param[in] x is the new iterate. 86 @param[in] flag is true if the iterate has changed. 87 @param[in] iter is the outer algorithm iterations count. 88 */ update(const Vector<Real> & x,bool flag=true,int iter=-1)89 virtual void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) { 90 ROL_UNUSED(x); 91 ROL_UNUSED(flag); 92 ROL_UNUSED(iter); 93 } 94 95 /** \brief Compute value. 96 97 This function returns the objective function value. 98 @param[in] x is the current iterate. 99 @param[in] tol is a tolerance for inexact objective function computation. 100 */ 101 virtual Real value( const Vector<Real> &x, Real &tol ) = 0; 102 103 /** \brief Compute gradient. 104 105 This function returns the objective function gradient. 106 @param[out] g is the gradient. 107 @param[in] x is the current iterate. 108 @param[in] tol is a tolerance for inexact objective function computation. 109 110 The default implementation is a finite-difference approximation based on the function value. 111 This requires the definition of a basis \f$\{\phi_i\}\f$ for the optimization vectors x and 112 the definition of a basis \f$\{\psi_j\}\f$ for the dual optimization vectors (gradient vectors g). 113 The bases must be related through the Riesz map, i.e., \f$ R \{\phi_i\} = \{\psi_j\}\f$, 114 and this must be reflected in the implementation of the ROL::Vector::dual() method. 115 */ 116 virtual void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) ; 117 118 /** \brief Compute directional derivative. 119 120 This function returns the directional derivative of the objective function in the \f$d\f$ direction. 121 @param[in] x is the current iterate. 122 @param[in] d is the direction. 123 @param[in] tol is a tolerance for inexact objective function computation. 124 */ 125 virtual Real dirDeriv( const Vector<Real> &x, const Vector<Real> &d, Real &tol ) ; 126 127 /** \brief Apply Hessian approximation to vector. 128 129 This function applies the Hessian of the objective function to the vector \f$v\f$. 130 @param[out] hv is the the action of the Hessian on \f$v\f$. 131 @param[in] v is the direction vector. 132 @param[in] x is the current iterate. 133 @param[in] tol is a tolerance for inexact objective function computation. 134 */ 135 virtual void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ); 136 137 /** \brief Apply inverse Hessian approximation to vector. 138 139 This function applies the inverse Hessian of the objective function to the vector \f$v\f$. 140 @param[out] hv is the action of the inverse Hessian on \f$v\f$. 141 @param[in] v is the direction vector. 142 @param[in] x is the current iterate. 143 @param[in] tol is a tolerance for inexact objective function computation. 144 */ invHessVec(Vector<Real> & hv,const Vector<Real> & v,const Vector<Real> & x,Real & tol)145 virtual void invHessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) { 146 ROL_UNUSED(hv); 147 ROL_UNUSED(v); 148 ROL_UNUSED(x); 149 ROL_UNUSED(tol); 150 ROL_TEST_FOR_EXCEPTION(true, std::invalid_argument, 151 ">>> ERROR (ROL::Objective): invHessVec not implemented!"); 152 //hv.set(v.dual()); 153 } 154 155 /** \brief Apply preconditioner to vector. 156 157 This function applies a preconditioner for the Hessian of the objective function to the vector \f$v\f$. 158 @param[out] Pv is the action of the Hessian preconditioner on \f$v\f$. 159 @param[in] v is the direction vector. 160 @param[in] x is the current iterate. 161 @param[in] tol is a tolerance for inexact objective function computation. 162 */ precond(Vector<Real> & Pv,const Vector<Real> & v,const Vector<Real> & x,Real & tol)163 virtual void precond( Vector<Real> &Pv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) { 164 ROL_UNUSED(x); 165 ROL_UNUSED(tol); 166 Pv.set(v.dual()); 167 } 168 169 /** \brief Finite-difference gradient check. 170 171 This function computes a sequence of one-sided finite-difference checks for the gradient. 172 At each step of the sequence, the finite difference step size is decreased. The output 173 compares the error 174 \f[ 175 \left| \frac{f(x+td) - f(x)}{t} - \langle \nabla f(x),d\rangle_{\mathcal{X}^*,\mathcal{X}}\right|. 176 \f] 177 if the approximation is first order. More generally, difference approximation is 178 \f[ 179 \frac{1}{t} \sum\limits_{i=1}^m w_i f(x+t c_i d) 180 \f] 181 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 182 @param[in] x is an optimization variable. 183 @param[in] d is a direction vector. 184 @param[in] printToStream is a flag that turns on/off output. 185 @param[out] outStream is the output stream. 186 @param[in] numSteps is a parameter which dictates the number of finite difference steps. 187 @param[in] order is the order of the finite difference approximation (1,2,3,4) 188 */ checkGradient(const Vector<Real> & x,const Vector<Real> & d,const bool printToStream=true,std::ostream & outStream=std::cout,const int numSteps=ROL_NUM_CHECKDERIV_STEPS,const int order=1)189 virtual std::vector<std::vector<Real> > checkGradient( const Vector<Real> &x, 190 const Vector<Real> &d, 191 const bool printToStream = true, 192 std::ostream & outStream = std::cout, 193 const int numSteps = ROL_NUM_CHECKDERIV_STEPS, 194 const int order = 1 ) { 195 return checkGradient(x, x.dual(), d, printToStream, outStream, numSteps, order); 196 } 197 198 /** \brief Finite-difference gradient check. 199 200 This function computes a sequence of one-sided finite-difference checks for the gradient. 201 At each step of the sequence, the finite difference step size is decreased. The output 202 compares the error 203 \f[ 204 \left| \frac{f(x+td) - f(x)}{t} - \langle \nabla f(x),d\rangle_{\mathcal{X}^*,\mathcal{X}}\right|. 205 \f] 206 if the approximation is first order. More generally, difference approximation is 207 \f[ 208 \frac{1}{t} \sum\limits_{i=1}^m w_i f(x+t c_i d) 209 \f] 210 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 211 212 @param[in] x is an optimization variable. 213 @param[in] g is used to create a temporary gradient vector. 214 @param[in] d is a direction vector. 215 @param[in] printToStream is a flag that turns on/off output. 216 @param[out] outStream is the output stream. 217 @param[in] numSteps is a parameter which dictates the number of finite difference steps. 218 @param[in] order is the order of the finite difference approximation (1,2,3,4) 219 */ 220 virtual std::vector<std::vector<Real> > checkGradient( const Vector<Real> &x, 221 const Vector<Real> &g, 222 const Vector<Real> &d, 223 const bool printToStream = true, 224 std::ostream & outStream = std::cout, 225 const int numSteps = ROL_NUM_CHECKDERIV_STEPS, 226 const int order = 1 ); 227 228 229 /** \brief Finite-difference gradient check with specified step sizes. 230 231 This function computes a sequence of one-sided finite-difference checks for the gradient. 232 At each step of the sequence, the finite difference step size is decreased. The output 233 compares the error 234 \f[ 235 \left| \frac{f(x+td) - f(x)}{t} - \langle \nabla f(x),d\rangle_{\mathcal{X}^*,\mathcal{X}}\right|. 236 \f] 237 if the approximation is first order. More generally, difference approximation is 238 \f[ 239 \frac{1}{t} \sum\limits_{i=1}^m w_i f(x+t c_i d) 240 \f] 241 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 242 @param[in] x is an optimization variable. 243 @param[in] d is a direction vector. 244 @param[in] steps is vector of steps of user-specified size. 245 @param[in] printToStream is a flag that turns on/off output. 246 @param[out] outStream is the output stream. 247 @param[in] order is the order of the finite difference approximation (1,2,3,4) 248 */ checkGradient(const Vector<Real> & x,const Vector<Real> & d,const std::vector<Real> & steps,const bool printToStream=true,std::ostream & outStream=std::cout,const int order=1)249 virtual std::vector<std::vector<Real> > checkGradient( const Vector<Real> &x, 250 const Vector<Real> &d, 251 const std::vector<Real> &steps, 252 const bool printToStream = true, 253 std::ostream & outStream = std::cout, 254 const int order = 1 ) { 255 256 return checkGradient(x, x.dual(), d, steps, printToStream, outStream, order); 257 258 } 259 260 261 /** \brief Finite-difference gradient check with specified step sizes. 262 263 This function computes a sequence of one-sided finite-difference checks for the gradient. 264 At each step of the sequence, the finite difference step size is decreased. The output 265 compares the error 266 \f[ 267 \left| \frac{f(x+td) - f(x)}{t} - \langle \nabla f(x),d\rangle_{\mathcal{X}^*,\mathcal{X}}\right|. 268 \f] 269 if the approximation is first order. More generally, difference approximation is 270 \f[ 271 \frac{1}{t} \sum\limits_{i=1}^m w_i f(x+t c_i d) 272 \f] 273 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 274 275 @param[in] x is an optimization variable. 276 @param[in] g is used to create a temporary gradient vector. 277 @param[in] d is a direction vector. 278 @param[in] steps is vector of steps of user-specified size. 279 @param[in] printToStream is a flag that turns on/off output. 280 @param[out] outStream is the output stream. 281 @param[in] order is the order of the finite difference approximation (1,2,3,4) 282 */ 283 virtual std::vector<std::vector<Real> > checkGradient( const Vector<Real> &x, 284 const Vector<Real> &g, 285 const Vector<Real> &d, 286 const std::vector<Real> &steps, 287 const bool printToStream = true, 288 std::ostream & outStream = std::cout, 289 const int order = 1 ); 290 291 /** \brief Finite-difference Hessian-applied-to-vector check. 292 293 This function computes a sequence of one-sided finite-difference checks for the Hessian. 294 At each step of the sequence, the finite difference step size is decreased. The output 295 compares the error 296 \f[ 297 \left\| \frac{\nabla f(x+tv) - \nabla f(x)}{t} - \nabla^2 f(x)v\right\|_{\mathcal{X}^*}, 298 \f] 299 if the approximation is first order. More generally, difference approximation is 300 \f[ 301 \frac{1}{t} \sum\limits_{i=1}^m w_i \nabla f(x+t c_i v), 302 \f] 303 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 304 @param[in] x is an optimization variable. 305 @param[in] v is a direction vector. 306 @param[in] printToStream is a flag that turns on/off output. 307 @param[out] outStream is the output stream. 308 @param[in] numSteps is a parameter which dictates the number of finite difference steps. 309 @param[in] order is the order of the finite difference approximation (1,2,3,4) 310 */ checkHessVec(const Vector<Real> & x,const Vector<Real> & v,const bool printToStream=true,std::ostream & outStream=std::cout,const int numSteps=ROL_NUM_CHECKDERIV_STEPS,const int order=1)311 virtual std::vector<std::vector<Real> > checkHessVec( const Vector<Real> &x, 312 const Vector<Real> &v, 313 const bool printToStream = true, 314 std::ostream & outStream = std::cout, 315 const int numSteps = ROL_NUM_CHECKDERIV_STEPS, 316 const int order = 1 ) { 317 318 return checkHessVec(x, x.dual(), v, printToStream, outStream, numSteps, order); 319 320 } 321 322 /** \brief Finite-difference Hessian-applied-to-vector check. 323 324 This function computes a sequence of one-sided finite-difference checks for the Hessian. 325 At each step of the sequence, the finite difference step size is decreased. The output 326 compares the error 327 \f[ 328 \left\| \frac{\nabla f(x+tv) - \nabla f(x)}{t} - \nabla^2 f(x)v\right\|_{\mathcal{X}^*}, 329 \f] 330 if the approximation is first order. More generally, difference approximation is 331 \f[ 332 \frac{1}{t} \sum\limits_{i=1}^m w_i \nabla f(x+t c_i v), 333 \f] 334 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 335 @param[in] x is an optimization variable. 336 @param[in] hv is used to create temporary gradient and Hessian-times-vector vectors. 337 @param[in] v is a direction vector. 338 @param[in] printToStream is a flag that turns on/off output. 339 @param[out] outStream is the output stream. 340 @param[in] numSteps is a parameter which dictates the number of finite difference steps. 341 @param[in] order is the order of the finite difference approximation (1,2,3,4) 342 */ 343 virtual std::vector<std::vector<Real> > checkHessVec( const Vector<Real> &x, 344 const Vector<Real> &hv, 345 const Vector<Real> &v, 346 const bool printToStream = true, 347 std::ostream & outStream = std::cout, 348 const int numSteps = ROL_NUM_CHECKDERIV_STEPS, 349 const int order = 1) ; 350 351 352 /** \brief Finite-difference Hessian-applied-to-vector check with specified step sizes. 353 354 This function computes a sequence of one-sided finite-difference checks for the Hessian. 355 At each step of the sequence, the finite difference step size is decreased. The output 356 compares the error 357 \f[ 358 \left\| \frac{\nabla f(x+tv) - \nabla f(x)}{t} - \nabla^2 f(x)v\right\|_{\mathcal{X}^*}, 359 \f] 360 if the approximation is first order. More generally, difference approximation is 361 \f[ 362 \frac{1}{t} \sum\limits_{i=1}^m w_i \nabla f(x+t c_i v), 363 \f] 364 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 365 @param[in] x is an optimization variable. 366 @param[in] v is a direction vector. 367 @param[in] steps is vector of steps of user-specified size. 368 @param[in] printToStream is a flag that turns on/off output. 369 @param[out] outStream is the output stream. 370 @param[in] order is the order of the finite difference approximation (1,2,3,4) 371 */ checkHessVec(const Vector<Real> & x,const Vector<Real> & v,const std::vector<Real> & steps,const bool printToStream=true,std::ostream & outStream=std::cout,const int order=1)372 virtual std::vector<std::vector<Real> > checkHessVec( const Vector<Real> &x, 373 const Vector<Real> &v, 374 const std::vector<Real> &steps, 375 const bool printToStream = true, 376 std::ostream & outStream = std::cout, 377 const int order = 1 ) { 378 379 return checkHessVec(x, x.dual(), v, steps, printToStream, outStream, order); 380 381 } 382 383 /** \brief Finite-difference Hessian-applied-to-vector check with specified step sizes. 384 385 This function computes a sequence of one-sided finite-difference checks for the Hessian. 386 At each step of the sequence, the finite difference step size is decreased. The output 387 compares the error 388 \f[ 389 \left\| \frac{\nabla f(x+tv) - \nabla f(x)}{t} - \nabla^2 f(x)v\right\|_{\mathcal{X}^*}, 390 \f] 391 if the approximation is first order. More generally, difference approximation is 392 \f[ 393 \frac{1}{t} \sum\limits_{i=1}^m w_i \nabla f(x+t c_i v), 394 \f] 395 where m = order+1, \f$w_i\f$ are the difference weights and \f$c_i\f$ are the difference steps 396 @param[in] x is an optimization variable. 397 @param[in] hv is used to create temporary gradient and Hessian-times-vector vectors. 398 @param[in] v is a direction vector. 399 @param[in] steps is vector of steps of user-specified size. 400 @param[in] printToStream is a flag that turns on/off output. 401 @param[out] outStream is the output stream. 402 @param[in] order is the order of the finite difference approximation (1,2,3,4) 403 */ 404 virtual std::vector<std::vector<Real> > checkHessVec( const Vector<Real> &x, 405 const Vector<Real> &hv, 406 const Vector<Real> &v, 407 const std::vector<Real> &steps, 408 const bool printToStream = true, 409 std::ostream & outStream = std::cout, 410 const int order = 1) ; 411 412 413 /** \brief Hessian symmetry check. 414 415 This function checks the symmetry of the Hessian by comparing 416 \f[ 417 \langle \nabla^2f(x)v,w\rangle_{\mathcal{X}^*,\mathcal{X}} 418 \quad\text{and}\quad 419 \langle \nabla^2f(x)w,v\rangle_{\mathcal{X}^*,\mathcal{X}}. 420 \f] 421 @param[in] x is an optimization variable. 422 @param[in] v is a direction vector. 423 @param[in] w is a direction vector. 424 @param[in] printToStream is a flag that turns on/off output. 425 @param[out] outStream is the output stream. 426 */ checkHessSym(const Vector<Real> & x,const Vector<Real> & v,const Vector<Real> & w,const bool printToStream=true,std::ostream & outStream=std::cout)427 virtual std::vector<Real> checkHessSym( const Vector<Real> &x, 428 const Vector<Real> &v, 429 const Vector<Real> &w, 430 const bool printToStream = true, 431 std::ostream & outStream = std::cout ) { 432 433 return checkHessSym(x, x.dual(), v, w, printToStream, outStream); 434 435 } 436 437 /** \brief Hessian symmetry check. 438 439 This function checks the symmetry of the Hessian by comparing 440 \f[ 441 \langle \nabla^2f(x)v,w\rangle_{\mathcal{X}^*,\mathcal{X}} 442 \quad\text{and}\quad 443 \langle \nabla^2f(x)w,v\rangle_{\mathcal{X}^*,\mathcal{X}}. 444 \f] 445 @param[in] x is an optimization variable. 446 @param[in] hv is used to create temporary Hessian-times-vector vectors. 447 @param[in] v is a direction vector. 448 @param[in] w is a direction vector. 449 @param[in] printToStream is a flag that turns on/off output. 450 @param[out] outStream is the output stream. 451 */ 452 virtual std::vector<Real> checkHessSym( const Vector<Real> &x, 453 const Vector<Real> &hv, 454 const Vector<Real> &v, 455 const Vector<Real> &w, 456 const bool printToStream = true, 457 std::ostream & outStream = std::cout ); 458 459 // Definitions for parametrized (stochastic) objective functions 460 private: 461 std::vector<Real> param_; 462 463 protected: getParameter(void) const464 const std::vector<Real> getParameter(void) const { 465 return param_; 466 } 467 468 public: setParameter(const std::vector<Real> & param)469 virtual void setParameter(const std::vector<Real> ¶m) { 470 param_.assign(param.begin(),param.end()); 471 } 472 473 }; // class Objective 474 475 } // namespace ROL 476 477 // include templated definitions 478 #include <ROL_ObjectiveDef.hpp> 479 480 #endif 481