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:        Minimizer
10 //- Description:  Base class for the optimizer and least squares branches
11 //-               of the iterator hierarchy.
12 //- Owner:        Mike Eldred
13 //- Version: $Id: DakotaMinimizer.hpp 7018 2010-10-12 02:25:22Z mseldre $
14 
15 #ifndef DAKOTA_MINIMIZER_H
16 #define DAKOTA_MINIMIZER_H
17 
18 #include "DakotaIterator.hpp"
19 #include "DakotaResponse.hpp"
20 #include "DakotaTPLDataTransfer.hpp"
21 #include "ExperimentData.hpp"
22 
23 namespace Dakota {
24 
25 /// Base class for the optimizer and least squares branches of the
26 /// iterator hierarchy.
27 
28 /** The Minimizer class provides common data and functionality
29     for Optimizer and LeastSq. */
30 
31 class Minimizer: public Iterator
32 {
33   //
34   //- Heading: Friends
35   //
36 
37   /// the SOLBase class is not derived the iterator hierarchy but still needs
38   /// access to iterator hierarchy data (to avoid attribute replication)
39   friend class SOLBase;
40   /// the SNLLBase class is not derived the iterator hierarchy but still needs
41   /// access to iterator hierarchy data (to avoid attribute replication)
42   friend class SNLLBase;
43 
44 public:
45 
46   //
47   //- Heading: Member functions
48   //
49 
50   /// set the method constraint tolerance (constraintTol)
51   void constraint_tolerance(Real constr_tol);
52   /// return the method constraint tolerance (constraintTol)
53   Real constraint_tolerance() const;
54 
55   /// return weighted sum of squared residuals
56   static Real sum_squared_residuals(size_t num_pri_fns,
57                                     const RealVector& residuals,
58                                     const RealVector& weights);
59 
60   /// print num_terms residuals and misfit for final results
61   static void print_residuals(size_t num_terms, const RealVector& best_terms,
62                               const RealVector& weights,
63                               size_t num_best, size_t best_index,
64                               std::ostream& s);
65 
66   /// print the original user model resp in the case of data transformations
67   static void print_model_resp(size_t num_pri_fns, const RealVector& best_fns,
68                                size_t num_best, size_t best_index,
69                                std::ostream& s);
70 
71 
72   // Accessor for data transfer helper/adapters
get_data_transfer_helper() const73   std::shared_ptr<TPLDataTransfer> get_data_transfer_helper() const
74     { return dataTransferHandler; }
75 
76   //
77   //- Heading: Virtual member function redefinitions
78   //
79 
80   bool resize();
81 
82 protected:
83 
84   //
85   //- Heading: Constructors and destructor
86   //
87 
88   /// default constructor
89   Minimizer(std::shared_ptr<TraitsBase> traits =
90       std::shared_ptr<TraitsBase>(new TraitsBase()));
91   /// standard constructor
92   Minimizer(ProblemDescDB& problem_db, Model& model,
93       std::shared_ptr<TraitsBase> traits =
94       std::shared_ptr<TraitsBase>(new TraitsBase()));
95 
96   /// alternate constructor for "on the fly" instantiations
97   Minimizer(unsigned short method_name, Model& model,
98       std::shared_ptr<TraitsBase> traits =
99       std::shared_ptr<TraitsBase>(new TraitsBase()));
100   /// alternate constructor for "on the fly" instantiations
101   Minimizer(unsigned short method_name, size_t num_lin_ineq, size_t num_lin_eq,
102 	    size_t num_nln_ineq, size_t num_nln_eq,
103             std::shared_ptr<TraitsBase> traits =
104             std::shared_ptr<TraitsBase>(new TraitsBase()));
105 
106   /// destructor
107   ~Minimizer();
108 
109   //
110   //- Heading: Virtual member function redefinitions
111   //
112 
113   void update_from_model(const Model& model);
114 
115   void initialize_run();
116   void post_run(std::ostream& s);
117   void finalize_run();
118 
119   const Model& algorithm_space_model() const;
120 
121   //
122   //- Heading: New virtual functions
123   //
124 
125   /*
126   /// initialize the iterator about to be executed within a parallel iterator
127   /// scheduling function (serve_iterators() or static_schedule_iterators())
128   void initialize_iterator(int index);
129   /// pack a send_buffer for assigning an iterator job to a server
130   void pack_parameters_buffer(MPIPackBuffer& send_buffer, int job_index);
131   /// unpack a recv_buffer for accepting an iterator job from the scheduler
132   void unpack_parameters_initialize(MPIUnpackBuffer& recv_buffer);
133   /// pack a send_buffer for returning iterator results from a server
134   void pack_results_buffer(MPIPackBuffer& send_buffer, int job_index);
135   /// unpack a recv_buffer for accepting iterator results from a server
136   void unpack_results_buffer(MPIUnpackBuffer& recv_buffer, int job_index);
137   /// update local PRP results arrays with current iteration results
138   void update_local_results(int job_index);
139   */
140 
141   //
142   //- Heading: Convenience/Helper functions
143   //
144 
145   /// Return a shallow copy of the original model this Iterator was
146   /// originally passed, optionally leaving recasts_left on top of it
147   Model original_model(unsigned short recasts_left = 0) const;
148 
149   /// Wrap iteratedModel in a RecastModel that subtracts provided
150   /// observed data from the primary response functions (variables and
151   /// secondary responses are unchanged)
152   void data_transform_model();
153 
154   /// Wrap iteratedModel in a RecastModel that performs variable
155   /// and/or response scaling
156   void scale_model();
157 
158    /// compute a composite objective value from one or more primary functions
159   Real objective(const RealVector& fn_vals, const BoolDeque& max_sense,
160 		 const RealVector& primary_wts) const;
161 
162   /// compute a composite objective with specified number of source
163   /// primary functions, instead of userPrimaryFns
164   Real objective(const RealVector& fn_vals, size_t num_fns,
165 		 const BoolDeque& max_sense,
166 		 const RealVector& primary_wts) const;
167 
168   /// compute the gradient of the composite objective function
169   void objective_gradient(const RealVector& fn_vals, const RealMatrix& fn_grads,
170 			  const BoolDeque& max_sense,
171 			  const RealVector& primary_wts,
172 			  RealVector& obj_grad) const;
173   /// compute the gradient of the composite objective function
174   void objective_gradient(const RealVector& fn_vals, size_t num_fns,
175 			  const RealMatrix& fn_grads,
176 			  const BoolDeque& max_sense,
177 			  const RealVector& primary_wts,
178 			  RealVector& obj_grad) const;
179 
180   /// compute the Hessian of the composite objective function
181   void objective_hessian(const RealVector& fn_vals, const RealMatrix& fn_grads,
182 			 const RealSymMatrixArray& fn_hessians,
183 			 const BoolDeque& max_sense,
184 			 const RealVector& primary_wts,
185 			 RealSymMatrix& obj_hess) const;
186   /// compute the Hessian of the composite objective function
187   void objective_hessian(const RealVector& fn_vals, size_t num_fns,
188 			 const RealMatrix& fn_grads,
189 			 const RealSymMatrixArray& fn_hessians,
190 			 const BoolDeque& max_sense,
191 			 const RealVector& primary_wts,
192 			 RealSymMatrix& obj_hess) const;
193 
194   /// top-level archival method
195   virtual void archive_best_results();
196 
197   /// archive best variables for the index'th final solution
198   void archive_best_variables(const bool active_only = false) const;
199 
200   /// archive the index'th set of objective functions
201   void archive_best_objective_functions() const;
202 
203   /// archive the index'th set of constraints
204   void archive_best_constraints() const;
205 
206   /// Archive residuals when calibration terms are used
207   void archive_best_residuals() const;
208 
209   /// Safely resize the best variables array to newsize taking into
210   /// account the envelope-letter design pattern and any recasting.
211   void resize_best_vars_array(size_t newsize);
212 
213   /// Safely resize the best response array to newsize taking into
214   /// account the envelope-letter design pattern and any recasting.
215   void resize_best_resp_array(size_t newsize);
216 
217   /// infers MOO/NLS solution from the solution of a single-objective optimizer
218   void local_recast_retrieve(const Variables& vars, Response& response) const;
219 
220 
221   //
222   //- Heading: Data
223   //
224 
225   // Isolate complexity by letting Model::currentVariables/currentResponse
226   // manage details.  Then Iterator only needs the following:
227   size_t numFunctions;          ///< number of response functions
228   size_t numContinuousVars;     ///< number of active continuous vars
229   size_t numDiscreteIntVars;    ///< number of active discrete integer vars
230   size_t numDiscreteStringVars; ///< number of active discrete string vars
231   size_t numDiscreteRealVars;   ///< number of active discrete real vars
232 
233   Real constraintTol;   ///< optimizer/least squares constraint tolerance
234 
235   /// cutoff value for inequality constraint and continuous variable bounds
236   Real bigRealBoundSize;
237   /// cutoff value for discrete variable bounds
238   int bigIntBoundSize;
239 
240   /// number of nonlinear inequality constraints
241   size_t numNonlinearIneqConstraints;
242   /// number of nonlinear equality constraints
243   size_t numNonlinearEqConstraints;
244 
245   /// number of linear inequality constraints
246   size_t numLinearIneqConstraints;
247   /// number of linear equality constraints
248   size_t numLinearEqConstraints;
249 
250   /// total number of nonlinear constraints
251   size_t numNonlinearConstraints;
252   /// total number of linear constraints
253   size_t numLinearConstraints;
254   /// total number of linear and nonlinear constraints
255   size_t numConstraints;
256 
257   /// flag for use where optimization and NLS must be distinguished
258   bool optimizationFlag;
259   /// number of objective functions or least squares terms in the
260   /// inbound model; always initialize at Minimizer, even if
261   /// overridden later
262   size_t numUserPrimaryFns;
263   /// number of objective functions or least squares terms in
264   /// iterator's view, after transformations; always initialize at
265   /// Minimizer, even if overridden later
266   size_t numIterPrimaryFns;
267 
268   /// convenience flag for denoting the presence of user-specified bound
269   /// constraints.  Used for method selection and error checking.
270   bool boundConstraintFlag;
271 
272   bool speculativeFlag; ///< flag for speculative gradient evaluations
273 
274   /// flag indicating whether user-supplied calibration data is active
275   bool calibrationDataFlag;
276   /// Container for experimental data to which to calibrate model
277   /// using least squares or other formulations which minimize SSE
278   ExperimentData expData;
279   /// number of experiments
280   size_t numExperiments;
281   /// number of total calibration terms (sum over experiments of
282   /// number of experimental data per experiment, including field data)
283   size_t numTotalCalibTerms;
284   /// Shallow copy of the data transformation model, when present
285   /// (cached in case further wrapped by other transformations)
286   Model dataTransformModel;
287 
288   /// whether Iterator-level scaling is active
289   bool scaleFlag;
290   /// Shallow copy of the scaling transformation model, when present
291   /// (cached in case further wrapped by other transformations)
292   Model scalingModel;
293 
294   /// pointer to Minimizer used in static member functions
295   static Minimizer* minimizerInstance;
296   /// pointer containing previous value of minimizerInstance
297   Minimizer* prevMinInstance;
298 
299   /// convenience flag for gradient_type == numerical && method_source == vendor
300   bool vendorNumericalGradFlag;
301 
302   /// Emerging helper class for handling data transfers to/from Dakota and the underlying TPL
303   std::shared_ptr<TPLDataTransfer> dataTransferHandler;
304 
305 private:
306 
307   //
308   //- Heading: Convenience/Helper functions
309   //
310 
311   //
312   //- Heading: Data
313   //
314 
315 };
316 
317 
Minimizer(std::shared_ptr<TraitsBase> traits)318 inline Minimizer::Minimizer(std::shared_ptr<TraitsBase> traits):
319   Iterator(traits), calibrationDataFlag(false), scaleFlag(false)
320 { }
321 
322 
~Minimizer()323 inline Minimizer::~Minimizer() { }
324 
325 
constraint_tolerance(Real constr_tol)326 inline void Minimizer::constraint_tolerance(Real constr_tol)
327 { constraintTol = constr_tol; }
328 
329 
constraint_tolerance() const330 inline Real Minimizer::constraint_tolerance() const
331 { return constraintTol; }
332 
333 
334 /** default definition that gets redefined in selected derived Minimizers */
algorithm_space_model() const335 inline const Model& Minimizer::algorithm_space_model() const
336 { return iteratedModel; }
337 
338 
339 //inline void Minimizer::initialize_iterator(int job_index)
340 //{ } // default = no-op
341 
342 
343 /** This virtual function redefinition is executed on the dedicated master
344     processor for self scheduling.  It is not used for peer partitions. */
345 //inline void Minimizer::
346 //pack_parameters_buffer(MPIPackBuffer& send_buffer, int job_index)
347 //{ } // default = no-op
348 
349 
350 /** This virtual function redefinition is executed on an iterator server for
351     dedicated master self scheduling.  It is not used for  peer partitions. */
352 //inline void Minimizer::
353 //unpack_parameters_initialize(MPIUnpackBuffer& recv_buffer)
354 //{ } // default = no-op
355 
356 
357 /** This virtual function redefinition is executed either on an iterator
358     server for dedicated master self scheduling or on peers 2 through n
359     for static scheduling. */
360 //inline void Minimizer::
361 //pack_results_buffer(MPIPackBuffer& send_buffer, int job_index)
362 //{ } // default = no-op
363 
364 
365 /** This virtual function redefinition is executed on an environment master
366     (either the dedicated master processor for self scheduling or peer 1
367     for static scheduling). */
368 //inline void Minimizer::
369 //unpack_results_buffer(MPIUnpackBuffer& recv_buffer, int job_index)
370 //{ } // default = no-op
371 
372 
373 //inline void Minimizer::update_local_results(int job_index)
374 //{ } // default = no-op
375 
376 } // namespace Dakota
377 
378 #endif
379