1 /* _______________________________________________________________________ 2 3 DAKOTA: Design Analysis Kit for Optimization and Terascale Applications 4 Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS). 5 This software is distributed under the GNU Lesser General Public License. 6 For more information, see the README file in the top Dakota directory. 7 _______________________________________________________________________ */ 8 9 //- Class: SNLLOptimizer 10 //- Description: Wrapper class for opt++ 11 //- Owner: Mike Eldred 12 //- Checked by: 13 //- Version: $Id 14 15 #ifndef SNLL_OPTIMIZER_H 16 #define SNLL_OPTIMIZER_H 17 18 #include "DakotaOptimizer.hpp" 19 #include "SNLLBase.hpp" 20 21 namespace OPTPP { 22 class NLF0; 23 class NLF1; 24 class NLF2; 25 class OptPDS; 26 class OptCG; 27 class OptLBFGS; 28 class OptNewton; 29 class OptQNewton; 30 class OptFDNewton; 31 class OptBCNewton; 32 class OptBCQNewton; 33 class OptBCFDNewton; 34 class OptNIPS; 35 class OptQNIPS; 36 class OptFDNIPS; 37 } 38 39 40 namespace Dakota { 41 42 /** 43 * \brief A version of TraitsBase specialized for SNLL optimizers 44 * 45 */ 46 class SNLLTraits: public TraitsBase 47 { 48 public: 49 50 /// default constructor SNLLTraits()51 SNLLTraits() { } 52 53 /// destructor ~SNLLTraits()54 virtual ~SNLLTraits() { } 55 56 /// A temporary query used in the refactor is_derived()57 virtual bool is_derived() { return true; } 58 59 // Traits are chosen to be the most common ones across a majority of methods within this TPL. 60 61 /// Return the value of supportsContinuousVariables supports_continuous_variables()62 bool supports_continuous_variables() { return true; } 63 64 /// Return the flag indicating whether method supports linear equalities supports_linear_equality()65 bool supports_linear_equality() { return true; } 66 67 /// Return the flag indicating whether method supports linear inequalities supports_linear_inequality()68 bool supports_linear_inequality() { return true; } 69 70 /// Return the flag indicating whether method supports nonlinear equalities supports_nonlinear_equality()71 bool supports_nonlinear_equality() { return true; } 72 73 /// Return the flag indicating whether method supports nonlinear inequalities supports_nonlinear_inequality()74 bool supports_nonlinear_inequality() { return true; } 75 76 /// Return the format used for nonlinear inequality constraints nonlinear_inequality_format()77 NONLINEAR_INEQUALITY_FORMAT nonlinear_inequality_format() 78 { return NONLINEAR_INEQUALITY_FORMAT::TWO_SIDED; } 79 80 }; 81 82 83 /// Wrapper class for the OPT++ optimization library. 84 85 /** The SNLLOptimizer class provides a wrapper for OPT++, a C++ 86 optimization library of nonlinear programming and pattern search 87 techniques from the Computational Sciences and Mathematics 88 Research (CSMR) department at Sandia's Livermore CA site. It uses 89 a function pointer approach for which passed functions must be 90 either global functions or static member functions. Any attribute 91 used within static member functions must be either local to that 92 function, a static member, or accessed by static pointer. 93 94 The user input mappings are as follows: \c max_iterations, \c 95 max_function_evaluations, \c convergence_tolerance, \c max_step, 96 \c gradient_tolerance, \c search_method, and \c search_scheme_size 97 are set using OPT++'s setMaxIter(), setMaxFeval(), setFcnTol(), 98 setMaxStep(), setGradTol(), setSearchStrategy(), and setSSS() 99 member functions, respectively; \c output verbosity is used to 100 toggle OPT++'s debug mode using the setDebug() member function. 101 Internal to OPT++, there are 3 search strategies, while the DAKOTA 102 \c search_method specification supports 4 (\c 103 value_based_line_search, \c gradient_based_line_search, \c 104 trust_region, or \c tr_pds). The difference stems from the 105 "is_expensive" flag in OPT++. If the search strategy is 106 LineSearch and "is_expensive" is turned on, then the \c 107 value_based_line_search is used. Otherwise (the "is_expensive" 108 default is off), the algorithm will use the \c 109 gradient_based_line_search. Refer to [Meza, J.C., 1994] and to 110 the OPT++ source in the Dakota/packages/OPTPP directory for 111 information on OPT++ class member functions. */ 112 class SNLLOptimizer: public Optimizer, public SNLLBase 113 { 114 public: 115 116 // 117 //- Heading: Constructors and destructor 118 // 119 120 /// standard constructor 121 SNLLOptimizer(ProblemDescDB& problem_db, Model& model); 122 123 /// alternate constructor for instantiations "on the fly" 124 SNLLOptimizer(const String& method_string, Model& model); 125 126 /// alternate constructor for instantiations "on the fly" 127 SNLLOptimizer(const RealVector& initial_pt, 128 const RealVector& var_l_bnds, const RealVector& var_u_bnds, 129 const RealMatrix& lin_ineq_coeffs, const RealVector& lin_ineq_l_bnds, 130 const RealVector& lin_ineq_u_bnds, const RealMatrix& lin_eq_coeffs, 131 const RealVector& lin_eq_tgts, const RealVector& nln_ineq_l_bnds, 132 const RealVector& nln_ineq_u_bnds, const RealVector& nln_eq_tgts, 133 void (*user_obj_eval) (int mode, int n, const RealVector& x, double& f, 134 RealVector& grad_f, int& result_mode), 135 void (*user_con_eval) (int mode, int n, const RealVector& x, RealVector& g, 136 RealMatrix& grad_g, int& result_mode)); 137 138 /// alternate constructor for instantiations "on the fly", also specifying different optimizer properties 139 SNLLOptimizer(const RealVector& initial_pt, 140 const RealVector& var_l_bnds, const RealVector& var_u_bnds, 141 const RealMatrix& lin_ineq_coeffs, const RealVector& lin_ineq_l_bnds, 142 const RealVector& lin_ineq_u_bnds, const RealMatrix& lin_eq_coeffs, 143 const RealVector& lin_eq_tgts, const RealVector& nln_ineq_l_bnds, 144 const RealVector& nln_ineq_u_bnds, const RealVector& nln_eq_tgts, 145 void (*user_obj_eval) (int mode, int n, const RealVector& x, double& f, 146 RealVector& grad_f, int& result_mode), 147 void (*user_con_eval) (int mode, int n, const RealVector& x, RealVector& g, 148 RealMatrix& grad_g, int& result_mode), 149 const int max_iter, const int max_fn_evals, 150 const Real conv_tol, const Real grad_tol, 151 Real max_step); 152 153 154 ~SNLLOptimizer(); ///< destructor 155 156 // 157 //- Heading: Virtual member function redefinitions 158 // 159 160 /// Performs the iterations to determine the optimal solution. 161 void core_run(); 162 163 void reset(); 164 165 void declare_sources(); 166 167 protected: 168 169 // 170 //- Heading: Virtual member function redefinitions 171 // 172 173 /// invokes Optimizer::initialize_run(), 174 /// SNLLBase::snll_initialize_run(), and performs other set-up 175 void initialize_run(); 176 177 /// performs data recovery and calls Optimizer::post_run() 178 void post_run(std::ostream& s); 179 180 /// performs cleanup, restores instances and calls parent finalize 181 void finalize_run(); 182 183 private: 184 185 // 186 //- Heading: Helper functions 187 // 188 189 /// instantiate an OPTPP_Q_NEWTON solver using standard settings 190 void default_instantiate_q_newton( 191 void (*obj_eval) (int mode, int n, const RealVector& x, double& f, 192 RealVector& grad_f, int& result_mode), 193 void (*con_eval) (int mode, int n, const RealVector& x, RealVector& g, 194 RealMatrix& grad_g, int& result_mode) ); 195 /// instantiate an OPTPP_NEWTON solver using standard settings 196 void default_instantiate_newton( 197 void (*obj_eval) (int mode, int n, const RealVector& x, double& f, 198 RealVector& grad_f, RealSymMatrix& hess_f, 199 int& result_mode), 200 void (*con_eval) (int mode, int n, const RealVector& x, RealVector& g, 201 RealMatrix& grad_g, 202 OPTPP::OptppArray<RealSymMatrix >& hess_g, 203 int& result_mode) ); 204 205 // 206 //- Heading: Static member functions required by opt++ 207 // 208 209 //- Fn. evaluation routines which invoke Model::compute_response 210 //- in order to supply f, df/dx, and d^2f/dx^2 to the OPT++ methods. 211 212 /// objective function evaluator function for OPT++ methods which 213 /// require only function values. 214 static void nlf0_evaluator(int n, const RealVector& x, double& f, 215 int& result_mode); 216 217 /// objective function evaluator function which provides function 218 /// values and gradients to OPT++ methods. 219 static void nlf1_evaluator(int mode, int n, const RealVector& x, 220 double& f, RealVector& grad_f, int& result_mode); 221 222 /// objective function evaluator function which provides function 223 /// values, gradients, and Hessians to OPT++ methods. 224 static void nlf2_evaluator(int mode, int n, const RealVector& x, 225 double& f, RealVector& grad_f, 226 RealSymMatrix& hess_f, int& result_mode); 227 228 //- Constraint evaluation routines that invoke Model::compute_response 229 230 /// constraint evaluator function for OPT++ methods which require 231 /// only constraint values. 232 static void constraint0_evaluator(int n, const RealVector& x, 233 RealVector& g, int& result_mode); 234 235 /// constraint evaluator function which provides constraint 236 /// values and gradients to OPT++ methods. 237 static void constraint1_evaluator(int mode, int n, const RealVector& x, 238 RealVector& g, RealMatrix& grad_g, 239 int& result_mode); 240 241 /// constraint evaluator function which provides constraint 242 /// values, gradients, and Hessians to OPT++ methods. 243 static void constraint2_evaluator(int mode, int n, const RealVector& x, 244 RealVector& g, RealMatrix& grad_g, 245 OPTPP::OptppArray<RealSymMatrix >& hess_g, 246 int& result_mode); 247 248 // 249 //- Heading: Data 250 // 251 252 /// pointer to the active object instance used within the static evaluator 253 /// functions in order to avoid the need for static data 254 static SNLLOptimizer* snllOptInstance; 255 /// pointer to the previously active object instance used for 256 /// restoration in the case of iterator/model recursion 257 SNLLOptimizer* prevSnllOptInstance; 258 259 //- Base class pointers to OPT++ objects 260 OPTPP::NLP0 *nlfObjective; ///< objective NLF base class pointer 261 OPTPP::NLP0 *nlfConstraint; ///< constraint NLF base class pointer 262 OPTPP::NLP *nlpConstraint; ///< constraint NLP pointer 263 264 //- additional pointers needed for option specification 265 /// pointer to objective NLF for nongradient optimizers 266 OPTPP::NLF0 *nlf0; 267 /// pointer to objective NLF for (analytic) gradient-based optimizers 268 OPTPP::NLF1 *nlf1; 269 /// pointer to constraint NLF for (analytic) gradient-based optimizers 270 OPTPP::NLF1 *nlf1Con; 271 /// pointer to objective NLF for (finite diff) gradient-based optimizers 272 OPTPP::FDNLF1 *fdnlf1; 273 /// pointer to constraint NLF for (finite diff) gradient-based optimizers 274 OPTPP::FDNLF1 *fdnlf1Con; 275 /// pointer to objective NLF for full Newton optimizers 276 OPTPP::NLF2 *nlf2; 277 /// pointer to constraint NLF for full Newton optimizers 278 OPTPP::NLF2 *nlf2Con; 279 280 OPTPP::OptimizeClass *theOptimizer; ///< optimizer base class pointer 281 //- additional pointers needed for option specification 282 OPTPP::OptPDS *optpds; ///< PDS optimizer pointer 283 OPTPP::OptCG *optcg; ///< CG optimizer pointer 284 OPTPP::OptLBFGS *optlbfgs; ///< L-BFGS optimizer pointer 285 OPTPP::OptNewton *optnewton; ///< Newton optimizer pointer 286 OPTPP::OptQNewton *optqnewton; ///< Quasi-Newton optimizer pointer 287 OPTPP::OptFDNewton *optfdnewton; ///< Finite Difference Newton opt pointer 288 OPTPP::OptBCNewton *optbcnewton; ///< Bound constrained Newton opt pointer 289 OPTPP::OptBCQNewton *optbcqnewton; ///< Bnd constrained Quasi-Newton opt ptr 290 OPTPP::OptBCFDNewton *optbcfdnewton;///< Bnd constrained FD-Newton opt ptr 291 OPTPP::OptNIPS *optnips; ///< NIPS optimizer pointer 292 OPTPP::OptQNIPS *optqnips; ///< Quasi-Newton NIPS optimizer pointer 293 OPTPP::OptFDNIPS *optfdnips; ///< Finite Difference NIPS opt pointer 294 295 /// flag for iteration mode: "model" (normal usage) or "user_functions" 296 /// (user-supplied functions mode for "on the fly" instantiations). 297 /// NonDReliability currently uses the user_functions mode. 298 String setUpType; 299 /// holds initial point passed in for "user_functions" mode. 300 RealVector initialPoint; 301 /// holds variable lower bounds passed in for "user_functions" mode. 302 RealVector lowerBounds; 303 /// holds variable upper bounds passed in for "user_functions" mode. 304 RealVector upperBounds; 305 }; 306 307 } // namespace Dakota 308 309 #endif 310