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: NonDExpansion
10 //- Description: Iterator base class for polynomial expansion methods for UQ
11 //- Owner: Mike Eldred, Sandia National Laboratories
12
13 #ifndef NOND_EXPANSION_H
14 #define NOND_EXPANSION_H
15
16 #include "DakotaNonD.hpp"
17
18
19 namespace Dakota {
20
21 /// Base class for polynomial chaos expansions (PCE), stochastic
22 /// collocation (SC) and functional tensor train (FT)
23
24 /** The NonDExpansion class provides a base class for methods that use
25 polynomial expansions to approximate the effect of parameter
26 uncertainties on response functions of interest. */
27
28 class NonDExpansion: public NonD
29 {
30 public:
31
32 //
33 //- Heading: Constructors and destructor
34 //
35
36 /// standard constructor
37 NonDExpansion(ProblemDescDB& problem_db, Model& model);
38 /// alternate constructor
39 NonDExpansion(unsigned short method_name, Model& model,
40 short exp_coeffs_approach, const RealVector& dim_pref, int seed,
41 short refine_type, short refine_control, short covar_control,
42 Real colloc_ratio, short rule_nest, short rule_growth,
43 bool piecewise_basis, bool use_derivs);
44 /// destructor
45 ~NonDExpansion();
46
47 //
48 //- Heading: Virtual function redefinitions
49 //
50
51 bool resize();
52 void derived_init_communicators(ParLevLIter pl_iter);
53 void derived_set_communicators(ParLevLIter pl_iter);
54 void derived_free_communicators(ParLevLIter pl_iter);
55
56 void nested_variable_mappings(const SizetArray& c_index1,
57 const SizetArray& di_index1,
58 const SizetArray& ds_index1,
59 const SizetArray& dr_index1,
60 const ShortArray& c_target2,
61 const ShortArray& di_target2,
62 const ShortArray& ds_target2,
63 const ShortArray& dr_target2);
64
65 /// perform a forward uncertainty propagation using PCE/SC methods
66 void core_run();
67 /// print the final statistics
68 void print_results(std::ostream& s, short results_state = FINAL_RESULTS);
69
70 const Model& algorithm_space_model() const;
71
72 //
73 //- Heading: Virtual functions
74 //
75
76 /// return specification for number of collocation points (may be
77 /// part of a sequence specification)
78 virtual size_t collocation_points() const;
79 /// return specification for random seed (may be part of a sequence
80 /// specification)
81 virtual int random_seed() const;
82 /// return first seed in sequence specification (defaults to random_seed())
83 virtual int first_seed() const;
84
85 /// evaluate allSamples for inclusion in the (PCE regression) approximation
86 /// and retain the best set (well spaced) of size batch_size
87 virtual void select_refinement_points(
88 const RealVectorArray& candidate_samples, unsigned short batch_size,
89 RealMatrix& best_samples);
90
91 /// generate numSamplesOnModel, append to approximation data, and update
92 /// QoI expansions
93 virtual void append_expansion();
94 /// append new data to uSpaceModel and, when appropriate,
95 /// update expansion order
96 virtual void append_expansion(const RealMatrix& samples,
97 const IntResponseMap& resp_map);
98
99 /// verify supported and define default discrepancy emulation mode
100 virtual void assign_discrepancy_mode();
101 /// define the surrogate response mode for a hierarchical model in
102 /// multilevel/multifidelity expansions
103 virtual void assign_hierarchical_response_mode();
104
105 virtual void infer_pilot_sample(/*Real ratio, */SizetArray& delta_N_l);
106
107 //
108 //- Heading: Member functions
109 //
110
111 /// return maxRefineIterations
112 int maximum_refinement_iterations() const;
113 /// set maxRefineIterations
114 void maximum_refinement_iterations(int max_refine_iter);
115
116 protected:
117
118 //
119 //- Heading: Virtual functions
120 //
121
122 /// perform error checks and mode overrides
123 virtual void resolve_inputs(short& u_space_type, short& data_order);
124 /// initialize uSpaceModel polynomial approximations with PCE/SC data
125 virtual void initialize_u_space_model();
126 /// initialize random variable definitions and final stats arrays
127 virtual void initialize_expansion();
128 /// form the expansion by calling uSpaceModel.build_approximation()
129 virtual void compute_expansion();
130 /// finalize mappings for the uSpaceModel
131 virtual void finalize_expansion();
132 /// assign the current values from the input specification sequence
133 virtual void assign_specification_sequence();
134 /// increment the input specification sequence and assign values
135 virtual void increment_specification_sequence();
136 /// update an expansion; avoids overhead in compute_expansion()
137 virtual void update_expansion();
138 /// combine coefficients, promote to active, and update statsMetricMode
139 virtual void combined_to_active();
140 /// archive expansion coefficients, as supported by derived instance
141 virtual void archive_coefficients();
142
143 /// helper function to manage different push increment cases
144 virtual void push_increment();
145 /// helper function to manage different pop increment cases
146 virtual void pop_increment();
147
148 /// compute 2-norm of change in response covariance
149 virtual Real compute_covariance_metric(bool revert, bool print_metric);
150 /// compute 2-norm of change in final statistics
151 virtual Real compute_level_mappings_metric(bool revert, bool print_metric);
152 // compute 2-norm of change in final statistics
153 //virtual Real compute_final_statistics_metric(bool revert,bool print_metric);
154
155 /// calculate analytic and numerical statistics from the expansion,
156 /// supporting {REFINEMENT,INTERMEDIATE,FINAL}_RESULTS modes
157 virtual void compute_statistics(short results_state = FINAL_RESULTS);
158 /// extract statistics from native stats arrays for a selected candidate
159 virtual void pull_candidate(RealVector& stats_star);
160 /// restore statistics into native stats arrays for a selected candidate
161 virtual void push_candidate(const RealVector& stats_star);
162
163 /// initializations for multilevel_regression()
164 virtual void initialize_ml_regression(size_t num_lev, bool& import_pilot);
165 /// increment sequence in numSamplesOnModel for multilevel_regression()
166 virtual void increment_sample_sequence(size_t new_samp, size_t total_samp,
167 size_t step);
168 /// accumulate one of the level metrics for {RIP,RANK}_SAMPLING cases
169 virtual void sample_allocation_metric(Real& metric, Real power);
170 /// compute delta_N_l for {RIP,RANK}_SAMPLING cases
171 virtual void compute_sample_increment(const RealVector& lev_metrics,
172 const SizetArray& N_l,
173 SizetArray& delta_N_l);
174 /// finalizations for multilevel_regression()
175 virtual void finalize_ml_regression();
176
177 /// update numSamplesOnModel after an order increment
178 virtual void update_samples_from_order_increment();
179 /// update (restore previous) numSamplesOnModel after an order decrement
180 virtual void update_samples_from_order_decrement();
181
182 /// print global sensitivity indices
183 virtual void print_sobol_indices(std::ostream& s);
184
185 //
186 //- Heading: Virtual function redefinitions
187 //
188
189 /// set covarianceControl defaults and shape respCovariance
190 void initialize_response_covariance();
191 /// update function values within finalStatistics
192 void update_final_statistics();
193 /// update function gradients within finalStatistics
194 void update_final_statistics_gradients();
195
196 //
197 //- Heading: Member functions
198 //
199
200 /// helper for initializing a numerical integration grid
201 void initialize_u_space_grid();
202
203 /// check length and content of dimension preference vector
204 void check_dimension_preference(const RealVector& dim_pref) const;
205
206 /// assign a NonDCubature instance within u_space_sampler
207 void construct_cubature(Iterator& u_space_sampler, Model& g_u_model,
208 unsigned short cub_int_order);
209 /// assign a NonDQuadrature instance within u_space_sampler based on
210 /// a quad_order specification
211 void construct_quadrature(Iterator& u_space_sampler, Model& g_u_model,
212 unsigned short quad_order,
213 const RealVector& dim_pref);
214 /// assign a NonDQuadrature instance within u_space_sampler that
215 /// generates a filtered tensor product sample set
216 void construct_quadrature(Iterator& u_space_sampler, Model& g_u_model,
217 unsigned short quad_order,
218 const RealVector& dim_pref, int filtered_samples);
219 /// assign a NonDQuadrature instance within u_space_sampler that
220 /// samples randomly from a tensor product multi-index
221 void construct_quadrature(Iterator& u_space_sampler, Model& g_u_model,
222 unsigned short quad_order,
223 const RealVector& dim_pref,
224 int random_samples, int seed);
225 /// assign a NonDSparseGrid instance within u_space_sampler
226 void construct_sparse_grid(Iterator& u_space_sampler, Model& g_u_model,
227 unsigned short ssg_level,
228 const RealVector& dim_pref);
229 // assign a NonDIncremLHSSampling instance within u_space_sampler
230 //void construct_incremental_lhs(Iterator& u_space_sampler, Model& u_model,
231 // int num_samples, int seed, const String& rng);
232
233 /// configure exp_orders from inputs
234 void configure_expansion_orders(unsigned short exp_order,
235 const RealVector& dim_pref,
236 UShortArray& exp_orders);
237
238 /// configure expansion and basis configuration options for Pecos
239 /// polynomial approximations
240 void configure_pecos_options();
241
242 /// construct the expansionSampler for evaluating samples on uSpaceModel
243 void construct_expansion_sampler(unsigned short sample_type,
244 const String& rng, unsigned short integration_refine = NO_INT_REFINE,
245 const IntVector& refine_samples = IntVector(),
246 const String& import_approx_file = String(),
247 unsigned short import_approx_format = TABULAR_ANNOTATED,
248 bool import_approx_active_only = false);
249
250 /// construct a multifidelity expansion, across model forms or
251 /// discretization levels
252 void multifidelity_expansion();
253 /// allocate a multilevel expansion based on some approximation to an
254 /// optimal resource allocation across model forms/discretization levels
255 void multilevel_regression();
256
257 /// configure fidelity/level counts from model hierarchy
258 void configure_sequence(unsigned short& num_steps,
259 unsigned short& fixed_index,
260 bool& multilevel, bool mf_precedence);
261 /// extract cost estimates from model hierarchy (forms or resolutions)
262 void configure_cost(unsigned short num_steps, bool multilevel,
263 RealVector& cost);
264 /// extract cost estimates from model hierarchy, if available
265 bool query_cost(unsigned short num_steps, bool multilevel, RealVector& cost);
266 /// configure response mode and active/truth/surrogate model keys within a
267 /// hierarchical model. s_index is the sequence index that defines the
268 /// active dimension for a model sequence.
269 void configure_indices(unsigned short group, unsigned short form,
270 unsigned short lev, unsigned short s_index);
271 /// return aggregate cost (one or more models) for a level sample
272 Real sequence_cost(unsigned short step, const RealVector& cost);
273 /// compute equivHFEvals from samples per level and cost per evaluation
274 void compute_equivalent_cost(const SizetArray& N_l, const RealVector& cost);
275
276 /// compute increment in samples for multilevel_regression() based
277 /// on ESTIMATOR_VARIANCE
278 void compute_sample_increment(const RealVector& agg_var,
279 const RealVector& cost, Real sum_root_var_cost,
280 Real eps_sq_div_2, const SizetArray& N_l,
281 SizetArray& delta_N_l);
282
283 /// return number of collocation points for index within model sequence
284 size_t collocation_points(size_t index) const;
285 /// return random seed for index within model sequence
286 int random_seed(size_t index) const;
287
288 /// refine the reference expansion found by compute_expansion() using
289 /// uniform/adaptive p-/h-refinement strategies
290 void refine_expansion();
291 /// initialization of expansion refinement, if necessary
292 void pre_refinement();
293 /// advance the refinement strategy one step
294 size_t core_refinement(Real& metric, bool revert = false,
295 bool print_metric = true);
296 /// finalization of expansion refinement, if necessary
297 void post_refinement(Real& metric, bool reverted = false);
298
299 /// helper function to manage different grid increment cases
300 void increment_grid(bool update_anisotropy = true);
301 /// helper function to manage different grid decrement cases
302 void decrement_grid();
303 /// helper function to manage different grid merge cases
304 void merge_grid();
305
306 /// uniformly increment the expansion order and structured/unstructured grid
307 /// (PCE and FT)
308 void increment_order_and_grid();
309 /// uniformly decrement the expansion order and structured/unstructured grid
310 /// (PCE and FT)
311 void decrement_order_and_grid();
312
313 /// publish numSamplesOnModel update to the DataFitSurrModel instance
314 void update_model_from_samples();
315
316 /// perform sampler updates after a change to numSamplesOnModel
317 /// (shared code from ML/MF updaters)
318 void update_u_space_sampler(size_t sequence_index,
319 const UShortArray& approx_orders);
320
321 /// update statsMetricMode, here and in Pecos::ExpansionConfigOptions
322 void refinement_statistics_mode(short stats_mode);//, bool clear_bits = true);
323
324 /// perform any required expansion roll-ups prior to metric computation
325 void metric_roll_up(short results_state = FINAL_RESULTS);
326
327 /// Aggregate variance across the set of QoI for a particular model level
328 void aggregate_variance(Real& agg_var_l);
329
330 /// calculate the response covariance (diagonal or full matrix) for
331 /// the expansion indicated by statsMetricMode
332 void compute_covariance();
333 /// calculate the response covariance of the active expansion
334 void compute_active_covariance();
335 /// calculate the response covariance of the combined expansion
336 void compute_combined_covariance();
337
338 /// calculate the diagonal response variance of the active expansion
339 void compute_active_diagonal_variance();
340 /// calculate the diagonal response variance of the cmbined expansion
341 void compute_combined_diagonal_variance();
342
343 /// calculate off diagonal terms in respCovariance(i,j) for j<i for
344 /// the expansion indicated by statsMetricMode
345 void compute_off_diagonal_covariance();
346 /// calculate off diagonal terms in respCovariance(i,j) for j<i
347 /// using the active expansion coefficients
348 void compute_active_off_diagonal_covariance();
349 /// calculate off diagonal terms in respCovariance(i,j) for j<i
350 /// using the combined expansion coefficients
351 void compute_combined_off_diagonal_covariance();
352
353 /// compute expansion moments; this uses a lightweight approach for
354 /// incremental statistics (no additional moments; no finalStatistics update)
355 void compute_moments();
356 /// compute all analytic/numerical level mappings; this uses a lightweight
357 /// approach for incremental statistics (no derivatives, no finalStatistics
358 /// update)
359 void compute_level_mappings();
360 /// compute only numerical level mappings; this uses a lightweight approach
361 /// for incremental statistics (no derivatives, no finalStatistics update)
362 void compute_numerical_level_mappings();
363 /// compute Sobol' indices for main, interaction, and total effects; this
364 /// is intended for incremental statistics
365 void compute_sobol_indices();
366
367 /// print resp{Variance,Covariance}
368 void print_covariance(std::ostream& s);
369 /// print resp_var (response variance vector) using optional pre-pend
370 void print_variance(std::ostream& s, const RealVector& resp_var,
371 const String& prepend = "");
372 /// print resp_covar (response covariance matrix) using optional pre-pend
373 void print_covariance(std::ostream& s, const RealSymMatrix& resp_covar,
374 const String& prepend = "");
375
376 /// archive the central moments (numerical and expansion) to ResultsDB
377 void archive_moments();
378
379 /// archive the Sobol' indices to the resultsDB
380 void archive_sobol_indices();
381
382 void pull_reference(RealVector& stats_ref);
383 void push_reference(const RealVector& stats_ref);
384
385 /// pull lower triangle of symmetric matrix into vector
386 void pull_lower_triangle(const RealSymMatrix& mat, RealVector& vec,
387 size_t offset = 0);
388 /// push vector into lower triangle of symmetric matrix
389 void push_lower_triangle(const RealVector& vec, RealSymMatrix& mat,
390 size_t offset = 0);
391
392 /// convert number of regression terms and collocation ratio to a
393 /// number of collocation samples
394 int terms_ratio_to_samples(size_t num_exp_terms, Real colloc_ratio);
395 /// convert number of regression terms and number of collocation samples
396 /// to a collocation ratio
397 Real terms_samples_to_ratio(size_t num_exp_terms, int samples);
398
399 //
400 //- Heading: Data
401 //
402
403 /// Model representing the approximate response function in u-space,
404 /// after u-space recasting and polynomial data fit recursions
405 Model uSpaceModel;
406
407 /// Iterator used for sampling on the uSpaceModel to generate approximate
408 /// probability/reliability/response level statistics. Currently this is
409 /// an LHS sampling instance, but AIS could also be used.
410 Iterator expansionSampler;
411 /// Iterator used to refine the approximate probability estimates
412 /// generated by the expansionSampler using importance sampling
413 Iterator importanceSampler;
414
415 /// method for collocation point generation and subsequent
416 /// calculation of the expansion coefficients
417 short expansionCoeffsApproach;
418 /// type of expansion basis: DEFAULT_BASIS or
419 /// Pecos::{NODAL,HIERARCHICAL}_INTERPOLANT for SC or
420 /// Pecos::{TENSOR_PRODUCT,TOTAL_ORDER,ADAPTED}_BASIS for PCE regression
421 short expansionBasisType;
422
423 /// type of statistical metric roll-up: {NO,ACTIVE,COMBINED}_EXPANSION_STATS
424 short statsMetricMode;
425 /// flag indicating the use of relative scaling in refinement metrics
426 bool relativeMetric;
427
428 /// user specification for dimension_preference
429 RealVector dimPrefSpec;
430
431 /// user specification of number of initial samples per model instance,
432 /// including adaptive cases where an optimal sample profile is the
433 /// target of iteration (e.g., multilevel_regression())
434 SizetArray collocPtsSeqSpec;
435 /// factor applied to terms^termsOrder in computing number of regression
436 /// points, either user-specified or inferred
437 Real collocRatio;
438 /// exponent applied to number of expansion terms for computing
439 /// number of regression points (usually 1)
440 Real termsOrder;
441
442 /// seed for random number generator (used for regression with LHS
443 /// and sub-sampled tensor grids, as well as for expansionSampler)
444 int randomSeed;
445 /// user specification for seed_sequence
446 SizetArray randomSeedSeqSpec;
447 /// don't continue an existing random number sequence, rather reset
448 /// seed each time within some sampling-based iteration
449 bool fixedSeed;
450 /// top level iteration counter in adaptive NonDExpansion ML/MF algorithms,
451 /// allowing special updating logic for some sequence handlers
452 size_t mlmfIter;
453
454 /// flag for combined variable expansions which include a
455 /// non-probabilistic subset (design, epistemic, state)
456 bool allVars;
457 /// option for regression FT using a filtered set of tensor-product
458 /// quadrature points
459 bool tensorRegression;
460
461 /// type of sample allocation scheme for discretization levels / model forms
462 /// within multilevel / multifidelity methods
463 short multilevAllocControl;
464 /// emulation approach for multilevel / multifidelity discrepancy:
465 /// distinct or recursive
466 short multilevDiscrepEmulation;
467
468 /// number of samples allocated to each level of a discretization/model
469 /// hierarchy within multilevel/multifidelity methods
470 SizetArray NLev;
471 /// equivalent number of high fidelity evaluations accumulated using samples
472 /// across multiple model forms and/or discretization levels
473 Real equivHFEvals;
474 /// rate parameter for allocation by ESTIMATOR_VARIANCE in
475 /// multilevel_regression()
476 Real kappaEstimatorRate;
477 /// scale parameter for allocation by ESTIMATOR_VARIANCE in
478 /// multilevel_regression()
479 Real gammaEstimatorScale;
480
481 /// number of truth samples performed on g_u_model to form the expansion
482 int numSamplesOnModel;
483 /// number of approximation samples performed on the polynomial
484 /// expansion in order to estimate probabilities
485 int numSamplesOnExpansion;
486
487 /// flag for indicating state of \c nested and \c non_nested overrides of
488 /// default rule nesting, which depends on the type of integration driver;
489 /// this is defined in construct_{quadrature,sparse_grid}(), such that
490 /// override attributes (defined in ctors) must be used upstream
491 bool nestedRules;
492 /// user override of default rule nesting: NO_NESTING_OVERRIDE,
493 /// NESTED, or NON_NESTED
494 short ruleNestingOverride;
495 /// user override of default rule growth: NO_GROWTH_OVERRIDE,
496 /// RESTRICTED, or UNRESTRICTED
497 short ruleGrowthOverride;
498
499 /// flag for \c piecewise specification, indicating usage of local
500 /// basis polynomials within the stochastic expansion
501 bool piecewiseBasis;
502
503 /// flag for \c use_derivatives specification, indicating usage of derivative
504 /// data (with respect to expansion variables) to enhance the calculation of
505 /// the stochastic expansion.
506 /** This is part of the method specification since the instantiation of the
507 global data fit surrogate is implicit with no user specification. This
508 behavior is distinct from the usage of response derivatives with respect
509 to auxilliary variables (design, epistemic) for computing derivatives of
510 aleatory expansion statistics with respect to these variables. */
511 bool useDerivs;
512
513 /// stores the initial variables data in u-space
514 RealVector initialPtU;
515
516 /// refinement type: NO_REFINEMENT, P_REFINEMENT, or H_REFINEMENT
517 short refineType;
518 /// refinement control: NO_CONTROL, UNIFORM_CONTROL, LOCAL_ADAPTIVE_CONTROL,
519 /// DIMENSION_ADAPTIVE_CONTROL_SOBOL, DIMENSION_ADAPTIVE_CONTROL_DECAY, or
520 /// DIMENSION_ADAPTIVE_CONTROL_GENERALIZED
521 short refineControl;
522 /// refinement metric: NO_METRIC, COVARIANCE_METRIC, LEVEL_STATS_METRIC,
523 /// or MIXED_STATS_METRIC
524 short refineMetric;
525
526 /// enumeration for controlling response covariance calculation and
527 /// output: {DEFAULT,DIAGONAL,FULL}_COVARIANCE
528 short covarianceControl;
529
530 /// number of consecutive iterations within tolerance required to
531 /// indicate soft convergence
532 unsigned short softConvLimit;
533
534 /// symmetric matrix of analytic response covariance (full response
535 /// covariance option)
536 RealSymMatrix respCovariance;
537 /// vector of response variances (diagonal response covariance option)
538 RealVector respVariance;
539
540 /// stats of the best refinement candidate for the current model indices
541 RealVector statsStar;
542
543 /// number of invocations of core_run()
544 size_t numUncertainQuant;
545
546 private:
547
548 //
549 //- Heading: Convenience function definitions
550 //
551
552 /// initialize data based on variable counts
553 void initialize_counts();
554
555 /// set response mode to AGGREGATED_MODELS and recur response size updates
556 void aggregated_models_mode();
557 /// set response mode to BYPASS_SURROGATE and recur response size updates
558 void bypass_surrogate_mode();
559
560 /// generate a set of reference expansions across a model hierarchy
561 void multifidelity_reference_expansion();
562 /// separately refine each of the multifidelity reference expansions
563 void multifidelity_individual_refinement();
564 /// refine each of the multifidelity reference expansions within an
565 /// integrated competition
566 void multifidelity_integrated_refinement();
567
568 /// compute average of total Sobol' indices (from VBD) across the
569 /// response set for use as an anisotropy indicator
570 void reduce_total_sobol_sets(RealVector& avg_sobol);
571 /// compute minimum of spectral coefficient decay rates across the
572 /// response set for use as an anisotropy indicator
573 void reduce_decay_rate_sets(RealVector& min_decay);
574
575 /// print additional refinement diagnostics not covered by compute_*_metric()
576 void print_refinement_diagnostics(std::ostream& s);
577
578 /// perform an adaptive refinement increment using generalized sparse grids
579 size_t increment_sets(Real& delta_star, bool revert, bool print_metric);
580 /// finalization of adaptive refinement using generalized sparse grids
581 void finalize_sets(bool converged_within_tol, bool reverted = false);
582
583 /// promote selected candidate into reference grid + expansion
584 void select_candidate(size_t best_candidate);
585 /// promote selected index set candidate into reference grid + expansion
586 void select_index_set_candidate(
587 std::set<UShortArray>::const_iterator cit_star);
588 /// promote selected refinement increment candidate into reference
589 /// grid + expansion
590 void select_increment_candidate();
591
592 /// analytic portion of compute_statistics() from post-processing of
593 /// expansion coefficients (used for FINAL_RESULTS)
594 void compute_analytic_statistics();
595 /// numerical portion of compute_statistics() from sampling on the
596 /// expansion (used for FINAL_RESULTS)
597 void compute_numerical_statistics();
598 /// refinements to numerical probability statistics from importanceSampler
599 void compute_numerical_stat_refinements(RealVectorArray& imp_sampler_stats,
600 RealRealPairArray& min_max_fns);
601
602 /// helper to define the expansionSampler's data requests when sampling on
603 /// the expansion
604 void define_sampler_asv(ShortArray& sampler_asv);
605 /// helper to run the expansionSampler and compute its statistics
606 void run_sampler(const ShortArray& sampler_asv,
607 RealVector& exp_sampler_stats);
608 /// helper to refine the results from expansionSampler with importance
609 /// sampling (for probability levels) or bounds post-processing (for PDFs)
610 void refine_sampler(RealVectorArray& imp_sampler_stats,
611 RealRealPairArray& min_max_fns);
612
613 /// print expansion and numerical moments
614 void print_moments(std::ostream& s);
615 /// print local sensitivities evaluated at initialPtU
616 void print_local_sensitivity(std::ostream& s);
617
618 //
619 //- Heading: Data
620 //
621
622 /// derivative of the expansion with respect to the x-space variables
623 /// evaluated at the means (used as uncertainty importance metrics)
624 RealMatrix expGradsMeanX;
625
626 /// maximum number of uniform/adaptive refinement iterations
627 /// (specialization of maxIterations)
628 int maxRefineIterations;
629 /// maximum number of regression solver iterations (specialization
630 /// of maxIterations)
631 int maxSolverIterations;
632
633 /// flag indicating the activation of variance-bsaed decomposition
634 /// for computing Sobol' indices
635 bool vbdFlag;
636 /// limits the order of interactions within the component Sobol' indices
637 unsigned short vbdOrderLimit;
638 /// tolerance for omitting output of small VBD indices
639 Real vbdDropTol;
640
641 // sample type for \c expansion_samples approach to estimating PCE
642 // coefficients (supports construct_incremental_lhs())
643 //String expansionSampleType;
644 };
645
646
647 inline void NonDExpansion::
nested_variable_mappings(const SizetArray & c_index1,const SizetArray & di_index1,const SizetArray & ds_index1,const SizetArray & dr_index1,const ShortArray & c_target2,const ShortArray & di_target2,const ShortArray & ds_target2,const ShortArray & dr_target2)648 nested_variable_mappings(const SizetArray& c_index1,
649 const SizetArray& di_index1,
650 const SizetArray& ds_index1,
651 const SizetArray& dr_index1,
652 const ShortArray& c_target2,
653 const ShortArray& di_target2,
654 const ShortArray& ds_target2,
655 const ShortArray& dr_target2)
656 {
657 uSpaceModel.nested_variable_mappings(c_index1, di_index1, ds_index1,
658 dr_index1, c_target2, di_target2,
659 ds_target2, dr_target2);
660 }
661
662
collocation_points(size_t index) const663 inline size_t NonDExpansion::collocation_points(size_t index) const
664 {
665 if (collocPtsSeqSpec.empty()) return std::numeric_limits<size_t>::max();
666 else
667 return (index < collocPtsSeqSpec.size()) ?
668 collocPtsSeqSpec[index] : collocPtsSeqSpec.back();
669 }
670
671
random_seed() const672 inline int NonDExpansion::random_seed() const
673 { return randomSeed; } // default (overridden in case of seed_sequence)
674
675
first_seed() const676 inline int NonDExpansion::first_seed() const
677 { return random_seed(); } // default (overridden for multilevel)
678
679
680 /** extract an active seed from a seed sequence */
random_seed(size_t index) const681 inline int NonDExpansion::random_seed(size_t index) const
682 {
683 // return 0 for cases where seed is undefined or will not be updated
684
685 if (randomSeedSeqSpec.empty()) return 0; // no spec -> non-repeatable samples
686 else if (fixedSeed) // continually reset seed to specified value
687 return (index < randomSeedSeqSpec.size()) ?
688 randomSeedSeqSpec[index] : randomSeedSeqSpec.back();
689 // only set sequence of seeds for first pass, then let RNG state continue
690 else if (mlmfIter == 0 && index < randomSeedSeqSpec.size()) // pilot iter only
691 return randomSeedSeqSpec[index];
692 else return 0; // seed sequence exhausted, do not update
693 }
694
695
maximum_refinement_iterations() const696 inline int NonDExpansion::maximum_refinement_iterations() const
697 { return maxRefineIterations; }
698
699
maximum_refinement_iterations(int max_refine_iter)700 inline void NonDExpansion::maximum_refinement_iterations(int max_refine_iter)
701 { maxRefineIterations = max_refine_iter; }
702
703
algorithm_space_model() const704 inline const Model& NonDExpansion::algorithm_space_model() const
705 { return uSpaceModel; }
706
707
708 inline void NonDExpansion::
configure_cost(unsigned short num_steps,bool multilevel,RealVector & cost)709 configure_cost(unsigned short num_steps, bool multilevel, RealVector& cost)
710 {
711 bool cost_defined = query_cost(num_steps, multilevel, cost);
712 if (!cost_defined) {
713 Cerr << "Error: missing required simulation cost data in NonDExpansion::"
714 << "configure_cost()." << std::endl;
715 abort_handler(METHOD_ERROR);
716 }
717 }
718
719
collocation_points() const720 inline size_t NonDExpansion::collocation_points() const
721 { return 0; }
722
723
aggregated_models_mode()724 inline void NonDExpansion::aggregated_models_mode()
725 {
726 // update iteratedModel / uSpaceModel in separate calls rather than using
727 // uSpaceModel.surrogate_response_mode(mode) since DFSurrModel must pass
728 // mode along to iteratedModel (a HierarchSurrModel) without absorbing it
729 if (iteratedModel.surrogate_response_mode() != AGGREGATED_MODELS) {
730 iteratedModel.surrogate_response_mode(AGGREGATED_MODELS);//MODEL_DISCREPANCY
731 uSpaceModel.resize_from_subordinate_model();// recurs until hits aggregation
732 }
733 }
734
735
bypass_surrogate_mode()736 inline void NonDExpansion::bypass_surrogate_mode()
737 {
738 // update iteratedModel / uSpaceModel in separate calls rather than using
739 // uSpaceModel.surrogate_response_mode(mode) since DFSurrModel must pass
740 // mode along to iteratedModel (a HierarchSurrModel) without absorbing it
741 if (iteratedModel.surrogate_response_mode() != BYPASS_SURROGATE) {
742 iteratedModel.surrogate_response_mode(BYPASS_SURROGATE); // single level
743 uSpaceModel.resize_from_subordinate_model();// recurs until hits aggregation
744 }
745 }
746
747
748 inline Real NonDExpansion::
sequence_cost(unsigned short step,const RealVector & cost)749 sequence_cost(unsigned short step, const RealVector& cost)
750 {
751 if (cost.empty())
752 return 0.;
753 else {
754 Real cost_l = cost[step];
755 if (step && multilevDiscrepEmulation == DISTINCT_EMULATION)
756 cost_l += cost[step-1]; // discrepancies incur 2 level costs
757 return cost_l;
758 }
759 }
760
761
metric_roll_up(short results_state)762 inline void NonDExpansion::metric_roll_up(short results_state)
763 {
764 // if COMBINED_EXPANSIONS_STATS, assess refinement candidates using combined
765 // stat metrics, which by default require expansion combination (overridden
766 // for hierarchical SC)
767 if (statsMetricMode == Pecos::COMBINED_EXPANSION_STATS)
768 switch (results_state) {
769 case REFINEMENT_RESULTS:
770 // PCE and Nodal SC require combined expansion coefficients for computing
771 // combined stat metrics, but Hierarchical SC can efficiently compute
772 // deltas based only on active expansions (no combination required)
773 if (expansionBasisType != Pecos::HIERARCHICAL_INTERPOLANT)
774 uSpaceModel.combine_approximation();
775 break;
776 case INTERMEDIATE_RESULTS:
777 uSpaceModel.combine_approximation(); break;
778 // FINAL_RESULTS should not occur: no roll up after combined_to_active()
779 }
780
781 // TO DO: case of level mappings for numerical stats --> sampling on
782 // combined expansion
783 }
784
785
compute_active_covariance()786 inline void NonDExpansion::compute_active_covariance()
787 {
788 switch (covarianceControl) {
789 case DIAGONAL_COVARIANCE:
790 compute_active_diagonal_variance(); break;
791 case FULL_COVARIANCE:
792 compute_active_diagonal_variance();
793 compute_active_off_diagonal_covariance(); break;
794 }
795 }
796
797
compute_combined_covariance()798 inline void NonDExpansion::compute_combined_covariance()
799 {
800 switch (covarianceControl) {
801 case DIAGONAL_COVARIANCE:
802 compute_combined_diagonal_variance(); break;
803 case FULL_COVARIANCE:
804 compute_combined_diagonal_variance();
805 compute_combined_off_diagonal_covariance(); break;
806 }
807 }
808
809
compute_off_diagonal_covariance()810 inline void NonDExpansion::compute_off_diagonal_covariance()
811 {
812 if (numFunctions <= 1)
813 return;
814
815 // See also full_covar_stats logic in compute_analytic_statistics() ...
816
817 switch (statsMetricMode) {
818 case Pecos::ACTIVE_EXPANSION_STATS:
819 compute_active_off_diagonal_covariance(); break;
820 case Pecos::COMBINED_EXPANSION_STATS:
821 compute_combined_off_diagonal_covariance(); break;
822 }
823 }
824
825
compute_covariance()826 inline void NonDExpansion::compute_covariance()
827 {
828 switch (statsMetricMode) {
829 // multifidelity_expansion() is outer loop:
830 // > use of refine_expansion(): refine individually based on level covariance
831 // > after combine_approx(), combined_to_active() enables use of active covar
832 case Pecos::ACTIVE_EXPANSION_STATS:
833 compute_active_covariance(); break;
834 // if COMBINED_EXPANSIONS_STATS:
835 // > roll up effect of refinement candidate on combined multilevel covariance,
836 // avoiding combined_to_active() promotion until end
837 // > limited stats support for combinedExpCoeffs: only compute_covariance()
838 case Pecos::COMBINED_EXPANSION_STATS:
839 compute_combined_covariance(); break;
840 }
841 }
842
843
844 inline void NonDExpansion::
pull_lower_triangle(const RealSymMatrix & mat,RealVector & vec,size_t offset)845 pull_lower_triangle(const RealSymMatrix& mat, RealVector& vec, size_t offset)
846 {
847 size_t i, j, cntr = offset, nr = mat.numRows(),
848 min_vec_len = offset + (nr*nr + nr)/2;
849 if (vec.length() < min_vec_len) vec.resize(min_vec_len);
850 for (i=0; i<nr; ++i)
851 for (j=0; j<=i; ++j, ++cntr)
852 vec[cntr] = mat(i,j); // pull from lower triangle
853 }
854
855
856 inline void NonDExpansion::
push_lower_triangle(const RealVector & vec,RealSymMatrix & mat,size_t offset)857 push_lower_triangle(const RealVector& vec, RealSymMatrix& mat, size_t offset)
858 {
859 size_t i, j, cntr = offset, nr = mat.numRows(),
860 min_vec_len = offset + (nr*nr + nr)/2;
861 if (vec.length() < min_vec_len) {
862 Cerr << "Error: insufficient vector length in NonDExpansion::"
863 << "push_lower_triangle()" << std::endl;
864 abort_handler(METHOD_ERROR);
865 }
866 for (i=0; i<nr; ++i)
867 for (j=0; j<=i; ++j, ++cntr)
868 mat(i,j) = vec[cntr]; // push to lower triangle
869 }
870
871
pull_candidate(RealVector & stats_star)872 inline void NonDExpansion::pull_candidate(RealVector& stats_star)
873 { pull_reference(stats_star); } // default implementation: candidate same as ref
874
875
push_candidate(const RealVector & stats_star)876 inline void NonDExpansion::push_candidate(const RealVector& stats_star)
877 { push_reference(stats_star); } // default implementation: candidate same as ref
878
879
update_final_statistics()880 inline void NonDExpansion::update_final_statistics()
881 {
882 // aleatory final stats & their grads are updated directly within
883 // compute_statistics() (NonD::update_aleatory_final_statistics() is awkward
884 // for NonDExpansion since Pecos manages the moment arrays), such that all
885 // that remains are system final stats and additional gradient scaling.
886 if (respLevelTargetReduce) {
887 update_system_final_statistics();
888 update_system_final_statistics_gradients();
889 }
890 update_final_statistics_gradients();
891 }
892
893
archive_coefficients()894 inline void NonDExpansion::archive_coefficients()
895 { /* default is no-op */ }
896
897
898 inline void NonDExpansion::
check_dimension_preference(const RealVector & dim_pref) const899 check_dimension_preference(const RealVector& dim_pref) const
900 {
901 size_t len = dim_pref.length();
902 if (len) {
903 if (len != numContinuousVars) {
904 Cerr << "Error: length of dimension preference specification (" << len
905 << ") is inconsistent with continuous expansion variables ("
906 << numContinuousVars << ")." << std::endl;
907 abort_handler(METHOD_ERROR);
908 }
909 else
910 for (size_t i=0; i<len; ++i)
911 if (dim_pref[i] < 0.) { // allow zero preference
912 Cerr << "Error: bad dimension preference value (" << dim_pref[i]
913 << ")." << std::endl;
914 abort_handler(METHOD_ERROR);
915 }
916 }
917 }
918
919
920 inline int NonDExpansion::
terms_ratio_to_samples(size_t num_exp_terms,Real colloc_ratio)921 terms_ratio_to_samples(size_t num_exp_terms, Real colloc_ratio)
922 {
923 // for under-determined solves (compressed sensing), colloc_ratio can be < 1
924 size_t data_per_pt = (useDerivs) ? numContinuousVars + 1 : 1;
925 Real min_pts = std::pow((Real)num_exp_terms, termsOrder) / (Real)data_per_pt;
926 int tgt_samples = (int)std::floor(colloc_ratio*min_pts + .5); // rounded
927 if (colloc_ratio >= 1.) {
928 // logic is to round to the nearest integral sample count for the given
929 // colloc_ratio, but with a lower bound determined by rounding up with a
930 // unit colloc_ratio. The lower bound prevents creating an under-determined
931 // system due to rounding down when the intent is over- or uniquely
932 // determined (can only happen with non-integral min_pts due to use of
933 // derivative enhancement).
934 int min_samples = (int)std::ceil(min_pts); // lower bound
935 return std::max(min_samples, tgt_samples);
936 }
937 else
938 // for under-determined systems, data starvation is not a problem and we
939 // just need at least one sample.
940 return std::max(tgt_samples, 1);
941 }
942
943
944 inline Real NonDExpansion::
terms_samples_to_ratio(size_t num_exp_terms,int samples)945 terms_samples_to_ratio(size_t num_exp_terms, int samples)
946 {
947 size_t data_per_pt = (useDerivs) ? numContinuousVars + 1 : 1;
948 return (Real)(samples * data_per_pt) /
949 std::pow((Real)num_exp_terms, termsOrder);
950 }
951
952 } // namespace Dakota
953
954 #endif
955