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: ParamStudy
10 //- Description: Parameter study driver program. This class iterates a
11 //- Model object using simple rules, i.e. evaluating
12 //- a variety of specified points in the design space.
13 //- Owner: Mike Eldred
14 //- Version: $Id: ParamStudy.hpp 7024 2010-10-16 01:24:42Z mseldre $
15
16 #ifndef PARAM_STUDY_H
17 #define PARAM_STUDY_H
18
19 #include "DakotaPStudyDACE.hpp"
20 #include "dakota_data_io.hpp"
21
22
23 namespace Dakota {
24
25 /// Class for vector, list, centered, and multidimensional parameter studies.
26
27 /** The ParamStudy class contains several algorithms for performing
28 parameter studies of different types. The vector parameter study
29 steps along an n-dimensional vector from an arbitrary initial
30 point to an arbitrary final point in a specified number of steps.
31 The centered parameter study performs a number of plus and minus
32 offsets in each coordinate direction around a center point. A
33 multidimensional parameter study fills an n-dimensional hypercube
34 based on bounds and a specified number of partitions for each
35 dimension. And the list parameter study provides for a user
36 specification of a list of points to evaluate, which allows
37 general parameter investigations not fitting the structure of
38 vector, centered, or multidim parameter studies. */
39
40 class ParamStudy: public PStudyDACE
41 {
42 public:
43
44 //
45 //- Heading: Constructors and destructors
46 //
47
48 ParamStudy(ProblemDescDB& problem_db, Model& model); ///< constructor
49 ~ParamStudy(); ///< destructor
50
51 //
52 //- Heading: Virtual member function redefinitions
53 //
54
55 bool resize();
56 void pre_run();
57 void core_run();
58 void post_input();
59 void post_run(std::ostream& s);
60
61 /// Archive variables for parameter set idx
62 void archive_model_variables(const Model&, size_t idx) const override;
63 /// Archive responses for parameter set idx
64 void archive_model_response(const Response&, size_t idx) const override;
65
66 protected:
67 /// Allocate space to archive parameters and responses
68 void archive_allocate_sets() const;
69 private:
70
71 //
72 //- Heading: Convenience/internal member functions
73 //
74
75 /// performs the parameter study by sampling from a list of points
76 void sample();
77 /// performs the parameter study by sampling along a vector, starting from
78 /// an initial point followed by numSteps increments along continous/discrete
79 /// step vectors
80 void vector_loop();
81 /// performs a number of plus and minus offsets for each parameter
82 /// centered about an initial point
83 void centered_loop();
84 /// performs a full factorial combination for all intersections
85 /// defined by a set of multidimensional partitions
86 void multidim_loop();
87
88 /// load list of points from data file and distribute among
89 /// listCVPoints, listDIVPoints, listDSVPoints, and listDRVPoints
90 bool load_distribute_points(const String& points_filename,
91 unsigned short tabular_format,
92 bool active_only);
93
94 /// distributes incoming all vector in standard variable ordering among
95 /// continuous, discrete int, discrete string, and discrete real vectors
96 template <typename OrdinalType, typename ScalarTypeA, typename ScalarTypeC,
97 typename ScalarTypeDI, typename ScalarTypeDS,typename ScalarTypeDR>
98 bool distribute(
99 const Teuchos::SerialDenseVector<OrdinalType, ScalarTypeA>& all_data,
100 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeC>& c_data,
101 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeDI>& di_data,
102 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeDS>& ds_data,
103 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeDR>& dr_data);
104
105 /// distributes incoming all array in standard variable ordering among
106 /// continuous, discrete int, discrete string, and discrete real arrays
107 template <typename ScalarType>
108 bool distribute(const std::vector<ScalarType>& all_data,
109 std::vector<ScalarType>& c_data,
110 std::vector<ScalarType>& di_data,
111 std::vector<ScalarType>& ds_data,
112 std::vector<ScalarType>& dr_data);
113
114 /// distributes list_of_pts coming from user spec among
115 /// listCVPoints, listDIVPoints, listDSVPoints, and listDRVPoints
116 bool distribute_list_of_points(const RealVector& list_of_pts);
117 /// compute step vectors from finalPoint, initial points, and numSteps
118 void final_point_to_step_vector();
119 /// compute step vectors from {cont,discInt,discString,discReal}VarPartitions
120 /// and global bounds
121 void distribute_partitions();
122
123 /// perform error checks on numSteps
124 bool check_num_steps(int num_steps);
125 /// perform error checks on numSteps
126 bool check_step_vector(const RealVector& step_vector);
127 /// perform error checks on finalPoint
128 bool check_final_point(const RealVector& final_pt);
129 /// perform error checks on stepsPerVariable
130 bool check_steps_per_variable(const IntVector& steps_per_var);
131 /// perform error checks on variable partitions
132 bool check_variable_partitions(const UShortArray& partitions);
133 /// check for finite variable bounds within iteratedModel,
134 /// as required for computing partitions of finite ranges
135 bool check_finite_bounds();
136 /// sanity check for vector parameter study
137 bool check_ranges_sets(int num_steps);
138 /// sanity check for centered parameter study
139 bool check_ranges_sets(const IntVector& c_steps, const IntVector& di_steps,
140 const IntVector& ds_steps, const IntVector& dr_steps);
141 /// sanity check for increments along int/real set dimensions
142 bool check_sets(const IntVector& c_steps, const IntVector& di_steps,
143 const IntVector& ds_steps, const IntVector& dr_steps);
144
145 /// check for integer remainder and return step
146 int integer_step(int range, int num_steps) const;
147 /// check for out of bounds and index remainder and return step
148 int index_step(size_t start, size_t end, int num_steps) const;
149
150 /// helper function for performing a continuous step in one variable
151 void c_step(size_t c_index, int increment, Variables& vars);
152 /// helper function for performing a discrete step in an integer
153 /// range variable
154 void dri_step(size_t di_index, int increment, Variables& vars);
155 /// helper function for performing a discrete step in an integer set variable
156 void dsi_step(size_t di_index, int increment, const IntSet& values,
157 Variables& vars);
158 /// helper function for performing a discrete step in an string set variable
159 void dss_step(size_t ds_index, int increment, const StringSet& values,
160 Variables& vars);
161 /// helper function for performing a discrete step in a real set variable
162 void dsr_step(size_t dr_index, int increment, const RealSet& values,
163 Variables& vars);
164
165 /// reset vars to initial point (center)
166 void reset(Variables& vars);
167 /// store a centered parameter study header within allHeaders
168 void centered_header(const String& type, size_t var_index, int step,
169 size_t hdr_index);
170
171 /// specialized per-variable slice output for centered param study
172 void archive_allocate_cps() const;
173
174 /// specialized per-variable slice output for centered param study
175 void archive_cps_vars(const Model& model, size_t idx) const;
176
177 /// specialized per-variable slice output for centered param study
178 void archive_cps_resp(const Response& response, size_t idx) const;
179
180 /// map an overall parameter study (zero-based) evaluation index to
181 /// the (zero-based) variable index (among all variables) and the
182 /// (zero-based) step index within that variable
183 void index_to_var_step(const size_t study_idx,
184 size_t& var_idx, size_t& step_idx) const;
185
186 //
187 //- Heading: Data
188 //
189
190 /// total number of parameter study evaluations computed from specification
191 size_t numEvals;
192
193 /// array of continuous evaluation points for the list_parameter_study
194 RealVectorArray listCVPoints;
195 /// array of discrete int evaluation points for the list_parameter_study
196 IntVectorArray listDIVPoints;
197 /// array of discrete string evaluation points for the list_parameter_study
198 StringMulti2DArray listDSVPoints;
199 /// array of discrete real evaluation points for the list_parameter_study
200 RealVectorArray listDRVPoints;
201
202 /// the continuous start point for vector and centered parameter studies
203 RealVector initialCVPoint;
204 /// the discrete int start point for vector and centered parameter studies
205 IntVector initialDIVPoint;
206 /// the discrete string start point for vector and centered parameter studies
207 StringMultiArray initialDSVPoint;
208 /// the discrete real start point for vector and centered parameter studies
209 RealVector initialDRVPoint;
210
211 /// the continuous ending point for vector_parameter_study
212 RealVector finalCVPoint;
213 /// the discrete int range value or set index ending point for
214 /// vector_parameter_study
215 IntVector finalDIVPoint;
216 /// the discrete string set index ending point for vector_parameter_study
217 IntVector finalDSVPoint;
218 /// the discrete real set index ending point for vector_parameter_study
219 IntVector finalDRVPoint;
220
221 /// the n-dimensional continuous increment
222 RealVector contStepVector;
223 /// the n-dimensional discrete integer range value or set index increment
224 IntVector discIntStepVector;
225 /// the n-dimensional discrete string set index increment
226 IntVector discStringStepVector;
227 /// the n-dimensional discrete real set index increment
228 IntVector discRealStepVector;
229
230 /// the number of times continuous/discrete step vectors are applied
231 /// for vector_parameter_study (a specification option)
232 int numSteps;
233
234 /// number of offsets in the plus and the minus direction for each
235 /// variable in a centered_parameter_study
236 /** The per-type step arrays below could be made views into this,
237 instead of duplicating, but if so, distribute() will not be
238 allowed to resize the individual vectors. */
239 IntVector stepsPerVariable;
240
241 /// number of offsets in the plus and the minus direction for each
242 /// continuous variable in a centered_parameter_study
243 IntVector contStepsPerVariable;
244 /// number of offsets in the plus and the minus direction for each
245 /// discrete integer variable in a centered_parameter_study
246 IntVector discIntStepsPerVariable;
247 /// number of offsets in the plus and the minus direction for each
248 /// discrete string variable in a centered_parameter_study
249 IntVector discStringStepsPerVariable;
250 /// number of offsets in the plus and the minus direction for each
251 /// discrete real variable in a centered_parameter_study
252 IntVector discRealStepsPerVariable;
253
254 /// number of partitions for each continuous variable in a
255 /// multidim_parameter_study
256 UShortArray contVarPartitions;
257 /// number of partitions for each discrete integer variable in a
258 /// multidim_parameter_study
259 UShortArray discIntVarPartitions;
260 /// number of partitions for each discrete string variable in a
261 /// multidim_parameter_study
262 UShortArray discStringVarPartitions;
263 /// number of partitions for each discrete real variable in a
264 /// multidim_parameter_study
265 UShortArray discRealVarPartitions;
266 };
267
268
~ParamStudy()269 inline ParamStudy::~ParamStudy() { }
270
271
272 template <typename OrdinalType, typename ScalarTypeA, typename ScalarTypeC,
273 typename ScalarTypeDI, typename ScalarTypeDS, typename ScalarTypeDR>
274 bool ParamStudy::
distribute(const Teuchos::SerialDenseVector<OrdinalType,ScalarTypeA> & all_data,Teuchos::SerialDenseVector<OrdinalType,ScalarTypeC> & c_data,Teuchos::SerialDenseVector<OrdinalType,ScalarTypeDI> & di_data,Teuchos::SerialDenseVector<OrdinalType,ScalarTypeDS> & ds_data,Teuchos::SerialDenseVector<OrdinalType,ScalarTypeDR> & dr_data)275 distribute(const Teuchos::SerialDenseVector<OrdinalType, ScalarTypeA>& all_data,
276 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeC>& c_data,
277 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeDI>& di_data,
278 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeDS>& ds_data,
279 Teuchos::SerialDenseVector<OrdinalType, ScalarTypeDR>& dr_data)
280 {
281 size_t num_vars = numContinuousVars + numDiscreteIntVars
282 + numDiscreteStringVars + numDiscreteRealVars;
283 if (all_data.length() != num_vars) {
284 Cerr << "\nError: ParamStudy::distribute() input length must be "
285 << num_vars << '.' << std::endl;
286 return true;
287 }
288 c_data.sizeUninitialized(numContinuousVars);
289 di_data.sizeUninitialized(numDiscreteIntVars);
290 ds_data.sizeUninitialized(numDiscreteStringVars);
291 dr_data.sizeUninitialized(numDiscreteRealVars);
292
293 // Extract in order:
294 // cdv/ddiv/ddrv, cauv/dauiv/daurv, ceuv/deuiv/deurv, csv/dsiv/dsrv
295 const SharedVariablesData& svd
296 = iteratedModel.current_variables().shared_data();
297 const SizetArray& active_totals = svd.active_components_totals();
298 size_t i,
299 num_cdv = active_totals[TOTAL_CDV], num_ddiv = active_totals[TOTAL_DDIV],
300 num_ddsv = active_totals[TOTAL_DDSV], num_ddrv = active_totals[TOTAL_DDRV],
301 num_cauv = active_totals[TOTAL_CAUV],
302 num_dauiv = active_totals[TOTAL_DAUIV],
303 num_dausv = active_totals[TOTAL_DAUSV],
304 num_daurv = active_totals[TOTAL_DAURV],
305 num_ceuv = active_totals[TOTAL_CEUV],
306 num_deuiv = active_totals[TOTAL_DEUIV],
307 num_deusv = active_totals[TOTAL_DEUSV],
308 num_deurv = active_totals[TOTAL_DEURV],
309 num_csv = active_totals[TOTAL_CSV], num_dsiv = active_totals[TOTAL_DSIV],
310 num_dssv = active_totals[TOTAL_DSSV], num_dsrv = active_totals[TOTAL_DSRV],
311 s_cntr = 0, c_cntr = 0, di_cntr = 0, ds_cntr = 0, dr_cntr = 0;
312 for (i=0; i<num_cdv; ++i, ++s_cntr, ++c_cntr)
313 c_data[c_cntr] = static_cast<ScalarTypeC>(all_data[s_cntr]);
314 for (i=0; i<num_ddiv; ++i, ++s_cntr, ++di_cntr)
315 di_data[di_cntr] = static_cast<ScalarTypeDI>(all_data[s_cntr]);
316 for (i=0; i<num_ddsv; ++i, ++s_cntr, ++ds_cntr)
317 ds_data[ds_cntr] = static_cast<ScalarTypeDS>(all_data[s_cntr]);
318 for (i=0; i<num_ddrv; ++i, ++s_cntr, ++dr_cntr)
319 dr_data[dr_cntr] = static_cast<ScalarTypeDR>(all_data[s_cntr]);
320 for (i=0; i<num_cauv; ++i, ++s_cntr, ++c_cntr)
321 c_data[c_cntr] = static_cast<ScalarTypeC>(all_data[s_cntr]);
322 for (i=0; i<num_dauiv; ++i, ++s_cntr, ++di_cntr)
323 di_data[di_cntr] = static_cast<ScalarTypeDI>(all_data[s_cntr]);
324 for (i=0; i<num_dausv; ++i, ++s_cntr, ++ds_cntr)
325 ds_data[ds_cntr] = static_cast<ScalarTypeDS>(all_data[s_cntr]);
326 for (i=0; i<num_daurv; ++i, ++s_cntr, ++dr_cntr)
327 dr_data[dr_cntr] = static_cast<ScalarTypeDR>(all_data[s_cntr]);
328 for (i=0; i<num_ceuv; ++i, ++s_cntr, ++c_cntr)
329 c_data[c_cntr] = static_cast<ScalarTypeC>(all_data[s_cntr]);
330 for (i=0; i<num_deuiv; ++i, ++s_cntr, ++di_cntr)
331 di_data[di_cntr] = static_cast<ScalarTypeDI>(all_data[s_cntr]);
332 for (i=0; i<num_deusv; ++i, ++s_cntr, ++ds_cntr)
333 ds_data[ds_cntr] = static_cast<ScalarTypeDS>(all_data[s_cntr]);
334 for (i=0; i<num_deurv; ++i, ++s_cntr, ++dr_cntr)
335 dr_data[dr_cntr] = static_cast<ScalarTypeDR>(all_data[s_cntr]);
336 for (i=0; i<num_csv; ++i, ++s_cntr, ++c_cntr)
337 c_data[c_cntr] = static_cast<ScalarTypeC>(all_data[s_cntr]);
338 for (i=0; i<num_dsiv; ++i, ++s_cntr, ++di_cntr)
339 di_data[di_cntr] = static_cast<ScalarTypeDI>(all_data[s_cntr]);
340 for (i=0; i<num_dssv; ++i, ++s_cntr, ++ds_cntr)
341 ds_data[ds_cntr] = static_cast<ScalarTypeDS>(all_data[s_cntr]);
342 for (i=0; i<num_dsrv; ++i, ++s_cntr, ++dr_cntr)
343 dr_data[dr_cntr] = static_cast<ScalarTypeDR>(all_data[s_cntr]);
344
345 #ifdef DEBUG
346 Cout << "distribute():\n";
347 if (numContinuousVars) Cout << "continuous vector:\n" << c_data;
348 if (numDiscreteIntVars) Cout << "discrete int vector:\n" << di_data;
349 if (numDiscreteStringVars)
350 { Cout << "discrete string vector:\n"; write_data(Cout, ds_data); }
351 if (numDiscreteRealVars) Cout << "discrete real vector:\n" << dr_data;
352 #endif // DEBUG
353
354 return false;
355 }
356
357
358 template <typename ScalarType> bool ParamStudy::
distribute(const std::vector<ScalarType> & all_data,std::vector<ScalarType> & c_data,std::vector<ScalarType> & di_data,std::vector<ScalarType> & ds_data,std::vector<ScalarType> & dr_data)359 distribute(const std::vector<ScalarType>& all_data,
360 std::vector<ScalarType>& c_data,
361 std::vector<ScalarType>& di_data,
362 std::vector<ScalarType>& ds_data,
363 std::vector<ScalarType>& dr_data)
364 {
365 size_t num_vars = numContinuousVars + numDiscreteIntVars
366 + numDiscreteStringVars + numDiscreteRealVars;
367 if (all_data.size() != num_vars) {
368 Cerr << "\nError: ParamStudy::distribute() input length must be "
369 << num_vars << '.' << std::endl;
370 return true;
371 }
372 c_data.resize(numContinuousVars);
373 di_data.resize(numDiscreteIntVars);
374 ds_data.resize(numDiscreteStringVars);
375 dr_data.resize(numDiscreteRealVars);
376
377 // Extract in order:
378 // cdv/ddiv/ddrv, cauv/dauiv/daurv, ceuv/deuiv/deurv, csv/dsiv/dsrv
379 const SharedVariablesData& svd
380 = iteratedModel.current_variables().shared_data();
381 const SizetArray& active_totals = svd.active_components_totals();
382 size_t i,
383 num_cdv = active_totals[TOTAL_CDV], num_ddiv = active_totals[TOTAL_DDIV],
384 num_ddsv = active_totals[TOTAL_DDSV], num_ddrv = active_totals[TOTAL_DDRV],
385 num_cauv = active_totals[TOTAL_CAUV],
386 num_dauiv = active_totals[TOTAL_DAUIV],
387 num_dausv = active_totals[TOTAL_DAUSV],
388 num_daurv = active_totals[TOTAL_DAURV],
389 num_ceuv = active_totals[TOTAL_CEUV],
390 num_deuiv = active_totals[TOTAL_DEUIV],
391 num_deusv = active_totals[TOTAL_DEUSV],
392 num_deurv = active_totals[TOTAL_DEURV],
393 num_csv = active_totals[TOTAL_CSV], num_dsiv = active_totals[TOTAL_DSIV],
394 num_dssv = active_totals[TOTAL_DSSV], num_dsrv = active_totals[TOTAL_DSRV],
395 s_cntr = 0, c_cntr = 0, di_cntr = 0, ds_cntr = 0, dr_cntr = 0;
396 for (i=0; i<num_cdv; ++i, ++s_cntr, ++c_cntr)
397 c_data[c_cntr] = all_data[s_cntr];
398 for (i=0; i<num_ddiv; ++i, ++s_cntr, ++di_cntr)
399 di_data[di_cntr] = all_data[s_cntr];
400 for (i=0; i<num_ddsv; ++i, ++s_cntr, ++ds_cntr)
401 ds_data[ds_cntr] = all_data[s_cntr];
402 for (i=0; i<num_ddrv; ++i, ++s_cntr, ++dr_cntr)
403 dr_data[dr_cntr] = all_data[s_cntr];
404 for (i=0; i<num_cauv; ++i, ++s_cntr, ++c_cntr)
405 c_data[c_cntr] = all_data[s_cntr];
406 for (i=0; i<num_dauiv; ++i, ++s_cntr, ++di_cntr)
407 di_data[di_cntr] = all_data[s_cntr];
408 for (i=0; i<num_dausv; ++i, ++s_cntr, ++ds_cntr)
409 ds_data[ds_cntr] = all_data[s_cntr];
410 for (i=0; i<num_daurv; ++i, ++s_cntr, ++dr_cntr)
411 dr_data[dr_cntr] = all_data[s_cntr];
412 for (i=0; i<num_ceuv; ++i, ++s_cntr, ++c_cntr)
413 c_data[c_cntr] = all_data[s_cntr];
414 for (i=0; i<num_deuiv; ++i, ++s_cntr, ++di_cntr)
415 di_data[di_cntr] = all_data[s_cntr];
416 for (i=0; i<num_deusv; ++i, ++s_cntr, ++ds_cntr)
417 ds_data[ds_cntr] = all_data[s_cntr];
418 for (i=0; i<num_deurv; ++i, ++s_cntr, ++dr_cntr)
419 dr_data[dr_cntr] = all_data[s_cntr];
420 for (i=0; i<num_csv; ++i, ++s_cntr, ++c_cntr)
421 c_data[c_cntr] = all_data[s_cntr];
422 for (i=0; i<num_dsiv; ++i, ++s_cntr, ++di_cntr)
423 di_data[di_cntr] = all_data[s_cntr];
424 for (i=0; i<num_dssv; ++i, ++s_cntr, ++ds_cntr)
425 ds_data[ds_cntr] = all_data[s_cntr];
426 for (i=0; i<num_dsrv; ++i, ++s_cntr, ++dr_cntr)
427 dr_data[dr_cntr] = all_data[s_cntr];
428
429 #ifdef DEBUG
430 Cout << "distribute():\n";
431 if (numContinuousVars) Cout << "continuous array:\n" << c_data;
432 if (numDiscreteIntVars) Cout << "discrete int array:\n" << di_data;
433 if (numDiscreteStringVars)
434 { Cout << "discrete string array:\n"; write_data(Cout, ds_data); }
435 if (numDiscreteRealVars) Cout << "discrete real array:\n" << dr_data;
436 #endif // DEBUG
437
438 return false;
439 }
440
441
check_num_steps(int num_steps)442 inline bool ParamStudy::check_num_steps(int num_steps)
443 {
444 // basic num_steps checks only; additional checks occur downstream
445 if (num_steps < 0) {
446 Cerr << "\nError: num_steps must be nonnegative in "
447 << "vector_parameter_study." << std::endl;
448 return true;
449 }
450 numSteps = num_steps;
451 numEvals = numSteps + 1;
452 return false;
453 }
454
455
check_step_vector(const RealVector & step_vec)456 inline bool ParamStudy::check_step_vector(const RealVector& step_vec)
457 {
458 // basic final_point checks only, additional checks occur downstream
459 size_t num_vars = numContinuousVars + numDiscreteIntVars
460 + numDiscreteStringVars + numDiscreteRealVars;
461 if (step_vec.length() != num_vars) {
462 Cerr << "\nError: step_vector must be of dimension " << num_vars
463 << " in vector_parameter_study." << std::endl;
464 return true;
465 }
466 return distribute(step_vec, contStepVector, discIntStepVector,
467 discStringStepVector, discRealStepVector);
468 }
469
470
check_final_point(const RealVector & final_pt)471 inline bool ParamStudy::check_final_point(const RealVector& final_pt)
472 {
473 // basic final_point checks only, additional checks occur downstream
474 size_t num_vars = numContinuousVars + numDiscreteIntVars
475 + numDiscreteStringVars + numDiscreteRealVars;
476 if (final_pt.length() != num_vars) {
477 Cerr << "\nError: final_point must be of dimension " << num_vars
478 << " in vector_parameter_study." << std::endl;
479 return true;
480 }
481 return distribute(final_pt, finalCVPoint, finalDIVPoint, finalDSVPoint,
482 finalDRVPoint);
483 }
484
485
check_steps_per_variable(const IntVector & steps_per_var)486 inline bool ParamStudy::check_steps_per_variable(const IntVector& steps_per_var)
487 {
488 size_t spv_len = steps_per_var.length(),
489 num_vars = numContinuousVars + numDiscreteIntVars +
490 numDiscreteStringVars + numDiscreteRealVars;
491 // allow spv_len of 1 or num_vars
492 if (spv_len == num_vars) {
493 distribute(steps_per_var, contStepsPerVariable, discIntStepsPerVariable,
494 discStringStepsPerVariable, discRealStepsPerVariable);
495 // the steps are ordered by type, not by user variable ordering,
496 // so the mapping to all steps vector must follow distribution
497 stepsPerVariable.sizeUninitialized(num_vars);
498 copy_data_partial(contStepsPerVariable, stepsPerVariable, 0);
499 copy_data_partial(discIntStepsPerVariable, stepsPerVariable,
500 numContinuousVars);
501 copy_data_partial(discStringStepsPerVariable, stepsPerVariable,
502 numContinuousVars + numDiscreteIntVars);
503 copy_data_partial(discRealStepsPerVariable, stepsPerVariable,
504 numContinuousVars + numDiscreteIntVars +
505 numDiscreteStringVars);
506 }
507 else if (spv_len == 1) {
508 int steps = steps_per_var[0];
509 contStepsPerVariable.sizeUninitialized(numContinuousVars);
510 contStepsPerVariable = steps;
511 discIntStepsPerVariable.sizeUninitialized(numDiscreteIntVars);
512 discIntStepsPerVariable = steps;
513 discStringStepsPerVariable.sizeUninitialized(numDiscreteStringVars);
514 discStringStepsPerVariable = steps;
515 discRealStepsPerVariable.sizeUninitialized(numDiscreteRealVars);
516 discRealStepsPerVariable = steps;
517 stepsPerVariable.sizeUninitialized(num_vars);
518 stepsPerVariable = steps;
519 }
520 else {
521 Cerr << "\nError: steps_per_variable must be of length 1 or " << num_vars
522 << " in centered_parameter_study." << std::endl;
523 return true;
524 }
525 size_t i, spv_sum = 0;
526 for (i=0; i<numContinuousVars; ++i)
527 spv_sum += std::abs(contStepsPerVariable[i]);
528 for (i=0; i<numDiscreteIntVars; ++i)
529 spv_sum += std::abs(discIntStepsPerVariable[i]);
530 for (i=0; i<numDiscreteStringVars; ++i)
531 spv_sum += std::abs(discStringStepsPerVariable[i]);
532 for (i=0; i<numDiscreteRealVars; ++i)
533 spv_sum += std::abs(discRealStepsPerVariable[i]);
534 numEvals = 2*spv_sum + 1;
535 return false;
536 }
537
538
check_variable_partitions(const UShortArray & partitions)539 inline bool ParamStudy::check_variable_partitions(const UShortArray& partitions)
540 {
541 size_t i, vp_len = partitions.size();
542 // allow vp_len of 1 or num_vars
543 if (vp_len == numContinuousVars + numDiscreteIntVars +
544 numDiscreteStringVars + numDiscreteRealVars)
545 distribute(partitions, contVarPartitions, discIntVarPartitions,
546 discStringVarPartitions, discRealVarPartitions);
547 else if (vp_len == 1) {
548 unsigned short part = partitions[0];
549 contVarPartitions.assign(numContinuousVars, part);
550 discIntVarPartitions.assign(numDiscreteIntVars, part);
551 discStringVarPartitions.assign(numDiscreteStringVars, part);
552 discRealVarPartitions.assign(numDiscreteRealVars, part);
553 }
554 else {
555 Cerr << "\nError: partitions must be of length 1 or "
556 << numContinuousVars + numDiscreteIntVars + numDiscreteStringVars +
557 numDiscreteRealVars << " in multidim_parameter_study." << std::endl;
558 return true;
559 }
560 numEvals = 1;
561 for (i=0; i<numContinuousVars; ++i)
562 numEvals *= contVarPartitions[i] + 1;
563 for (i=0; i<numDiscreteIntVars; ++i)
564 numEvals *= discIntVarPartitions[i] + 1;
565 for (i=0; i<numDiscreteStringVars; ++i)
566 numEvals *= discStringVarPartitions[i] + 1;
567 for (i=0; i<numDiscreteRealVars; ++i)
568 numEvals *= discRealVarPartitions[i] + 1;
569 return false;
570 }
571
572
check_finite_bounds()573 inline bool ParamStudy::check_finite_bounds()
574 {
575 bool bnds_err = false;
576 // Finite bounds required for partitioning: check for case of default bounds
577 // (upper/lower = +/- type limits)
578 size_t i;
579 Real dbl_inf = std::numeric_limits<Real>::infinity();
580 if (numContinuousVars) {
581 const RealVector& c_l_bnds = iteratedModel.continuous_lower_bounds();
582 const RealVector& c_u_bnds = iteratedModel.continuous_upper_bounds();
583 for (i=0; i<numContinuousVars; ++i)
584 if (c_l_bnds[i] == -dbl_inf || c_u_bnds[i] == dbl_inf)
585 { bnds_err = true; break; }
586 }
587 if (numDiscreteIntVars) {
588 const IntVector& di_l_bnds = iteratedModel.discrete_int_lower_bounds();
589 const IntVector& di_u_bnds = iteratedModel.discrete_int_upper_bounds();
590 for (i=0; i<numDiscreteIntVars; ++i)
591 if (di_l_bnds[i] <= INT_MIN || di_u_bnds[i] >= INT_MAX)
592 { bnds_err = true; break; }
593 }
594 if (numDiscreteRealVars) {
595 const RealVector& dr_l_bnds = iteratedModel.discrete_real_lower_bounds();
596 const RealVector& dr_u_bnds = iteratedModel.discrete_real_upper_bounds();
597 for (i=0; i<numDiscreteRealVars; ++i)
598 if (dr_l_bnds[i] == -dbl_inf || dr_u_bnds[i] == dbl_inf)
599 { bnds_err = true; break; }
600 }
601 if (bnds_err)
602 Cerr << "\nError: multidim_parameter_study requires specification of "
603 << "variable bounds." << std::endl;
604 return bnds_err;
605 }
606
607
check_ranges_sets(int num_steps)608 inline bool ParamStudy::check_ranges_sets(int num_steps)
609 {
610 // convert scalar to a single vector
611 IntVector c_steps_per_var(numContinuousVars, false),
612 di_steps_per_var(numDiscreteIntVars, false),
613 ds_steps_per_var(numDiscreteStringVars, false),
614 dr_steps_per_var(numDiscreteRealVars, false);
615 c_steps_per_var = num_steps;
616 di_steps_per_var = num_steps;
617 ds_steps_per_var = num_steps;
618 dr_steps_per_var = num_steps;
619 return check_sets(c_steps_per_var, di_steps_per_var, ds_steps_per_var,
620 dr_steps_per_var);
621 }
622
623
624 inline bool ParamStudy::
check_ranges_sets(const IntVector & c_steps_per_var,const IntVector & di_steps_per_var,const IntVector & ds_steps_per_var,const IntVector & dr_steps_per_var)625 check_ranges_sets(const IntVector& c_steps_per_var,
626 const IntVector& di_steps_per_var,
627 const IntVector& ds_steps_per_var,
628 const IntVector& dr_steps_per_var)
629 {
630 // convert vector to plus and minus vector steps
631 IntVector c_steps(c_steps_per_var), di_steps(di_steps_per_var),
632 ds_steps(ds_steps_per_var), dr_steps(dr_steps_per_var);
633 bool err = check_sets(c_steps, di_steps, ds_steps, dr_steps); // + offsets
634 c_steps.scale(-1); di_steps.scale(-1); dr_steps.scale(-1);
635 if (check_sets(c_steps, di_steps, ds_steps, dr_steps)) // - offsets
636 err = true;
637 return err;
638 }
639
640
integer_step(int range,int num_steps) const641 inline int ParamStudy::integer_step(int range, int num_steps) const
642 {
643 if (range % num_steps) {
644 Cerr << "\nError: numSteps results in nonintegral division of integer/"
645 << "index range defined by start and final points." << std::endl;
646 abort_handler(-1);
647 }
648 return range / num_steps;
649 }
650
651
index_step(size_t start,size_t end,int num_steps) const652 inline int ParamStudy::index_step(size_t start, size_t end, int num_steps) const
653 {
654 if (start == _NPOS) {
655 Cerr << "\nError: specified start value not found in set." << std::endl;
656 abort_handler(-1);
657 }
658 else if (end == _NPOS) {
659 Cerr << "\nError: specified final value not found in set." << std::endl;
660 abort_handler(-1);
661 }
662 int range = (int)end - (int)start; // can be negative
663 return integer_step(range, num_steps);
664 }
665
666
c_step(size_t c_index,int increment,Variables & vars)667 inline void ParamStudy::c_step(size_t c_index, int increment, Variables& vars)
668 {
669 // bounds currently ignored for range types
670 Real c_var = initialCVPoint[c_index] + increment * contStepVector[c_index];
671 vars.continuous_variable(c_var, c_index);
672 }
673
674
675 inline void ParamStudy::
dri_step(size_t di_index,int increment,Variables & vars)676 dri_step(size_t di_index, int increment, Variables& vars)
677 {
678 // bounds currently ignored for range types
679 int di_var = initialDIVPoint[di_index]
680 + increment * discIntStepVector[di_index];
681 vars.discrete_int_variable(di_var, di_index);
682 }
683
684
685 inline void ParamStudy::
dsi_step(size_t di_index,int increment,const IntSet & values,Variables & vars)686 dsi_step(size_t di_index, int increment, const IntSet& values, Variables& vars)
687 {
688 // valid values and indices are checked for set types
689 size_t index0 = set_value_to_index(initialDIVPoint[di_index], values);
690 if (index0 == _NPOS) {
691 Cerr << "\nError: value " << initialDIVPoint[di_index] << " does not exist "
692 << "within discrete integer set in ParamStudy::dsi_step()."<<std::endl;
693 abort_handler(-1);
694 }
695 int index = index0 + increment * discIntStepVector[di_index];// +/- increments
696 if (index >= 0 && index < values.size())
697 vars.discrete_int_variable(set_index_to_value(index, values), di_index);
698 else {
699 Cerr << "\nError: index " << index << " out of range within discrete "
700 << "integer set in ParamStudy::dsi_step()." << std::endl;
701 abort_handler(-1);
702 }
703 }
704
705
706 inline void ParamStudy::
dss_step(size_t ds_index,int increment,const StringSet & values,Variables & vars)707 dss_step(size_t ds_index, int increment, const StringSet& values,
708 Variables& vars)
709 {
710 // valid values and indices are checked for set types
711 size_t index0 = set_value_to_index(initialDSVPoint[ds_index], values);
712 if (index0 == _NPOS) {
713 Cerr << "\nError: value " << initialDSVPoint[ds_index] << " does not exist "
714 << "within discrete string set in ParamStudy::dss_step()."<< std::endl;
715 abort_handler(-1);
716 }
717 int index = index0 + increment * discStringStepVector[ds_index]; // +/- steps
718 if (index >= 0 && index < values.size())
719 vars.discrete_string_variable(set_index_to_value(index, values), ds_index);
720 else {
721 Cerr << "\nError: index " << index << " out of range within discrete "
722 << "string set in ParamStudy::dsr_step()." << std::endl;
723 abort_handler(-1);
724 }
725 }
726
727
728 inline void ParamStudy::
dsr_step(size_t dr_index,int increment,const RealSet & values,Variables & vars)729 dsr_step(size_t dr_index, int increment, const RealSet& values, Variables& vars)
730 {
731 // valid values and indices are checked for set types
732 size_t index0 = set_value_to_index(initialDRVPoint[dr_index], values);
733 if (index0 == _NPOS) {
734 Cerr << "\nError: value " << initialDRVPoint[dr_index] << " does not exist "
735 << "within discrete real set in ParamStudy::dsr_step()." << std::endl;
736 abort_handler(-1);
737 }
738 int index = index0 + increment * discRealStepVector[dr_index];//+/- increments
739 if (index >= 0 && index < values.size())
740 vars.discrete_real_variable(set_index_to_value(index, values), dr_index);
741 else {
742 Cerr << "\nError: index " << index << " out of range within discrete "
743 << "real set in ParamStudy::dsr_step()." << std::endl;
744 abort_handler(-1);
745 }
746 }
747
748
reset(Variables & vars)749 inline void ParamStudy::reset(Variables& vars)
750 {
751 if (numContinuousVars) vars.continuous_variables(initialCVPoint);
752 if (numDiscreteIntVars) vars.discrete_int_variables(initialDIVPoint);
753 if (numDiscreteStringVars) vars.discrete_string_variables(
754 initialDSVPoint[boost::indices[idx_range(0, numDiscreteStringVars)]]);
755 if (numDiscreteRealVars) vars.discrete_real_variables(initialDRVPoint);
756 }
757
758
759 inline void ParamStudy::
centered_header(const String & type,size_t var_index,int step,size_t hdr_index)760 centered_header(const String& type, size_t var_index, int step,
761 size_t hdr_index)
762 {
763 String& h_string = allHeaders[hdr_index];
764 h_string.clear();
765 if (iteratedModel.asynch_flag())
766 h_string += "\n\n";
767 // This code expanded due to MSVC issue with Dakota::String operator +/+=
768 // Can be combined once using std::string everywhere
769 h_string += ">>>>> Centered parameter study evaluation for ";
770 h_string += type;
771 h_string += "[";
772 h_string += std::to_string(var_index+1);
773 h_string += "]";
774 if (step < 0) h_string += " - " + std::to_string(-step);
775 else h_string += " + " + std::to_string( step);
776 h_string += "delta:\n";
777 }
778
779 } // namespace Dakota
780
781 #endif
782