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