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