1 /*  _______________________________________________________________________
2 
3     PECOS: Parallel Environment for Creation Of Stochastics
4     Copyright (c) 2011, Sandia National Laboratories.
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Pecos directory.
7     _______________________________________________________________________ */
8 
9 //- Class:	 SparseGridDriver
10 //- Description: Wrapper class for C++ code from packages/quadrature/sparse_grid
11 //- Owner:       Mike Eldred
12 //- Revised by:
13 //- Version:
14 
15 #ifndef INCREMENTAL_SPARSE_GRID_DRIVER_HPP
16 #define INCREMENTAL_SPARSE_GRID_DRIVER_HPP
17 
18 #include "CombinedSparseGridDriver.hpp"
19 
20 
21 namespace Pecos {
22 
23 /// Derived integration driver class that generates N-dimensional
24 /// Smolyak sparse grids for numerical evaluation of expectation
25 /// integrals over independent standard random variables.
26 
27 /** This class is used by Dakota::NonDSparseGrid, but could also be
28     used for general numerical integration of moments.  It employs 1-D
29     Clenshaw-Curtis, Newton-Cotes, and Gaussian quadrature rules
30     within Smolyak sparse grids. */
31 
32 class IncrementalSparseGridDriver: public CombinedSparseGridDriver
33 {
34 public:
35 
36   //
37   //- Heading: Constructors and destructor
38   //
39 
40   /// default constructor
41   IncrementalSparseGridDriver();
42   /// constructor
43   IncrementalSparseGridDriver(unsigned short ssg_level,
44 			      const RealVector& dim_pref = RealVector(),
45 			      short growth_rate = MODERATE_RESTRICTED_GROWTH,
46 			      short refine_control = NO_CONTROL);
47   /// destructor
48   ~IncrementalSparseGridDriver();
49 
50   //
51   //- Heading: Virtual function redefinitions
52   //
53 
54   /// update {smolMI,smolCoeffs,collocKey,collocInd}Iter from activeKey
55   void update_active_iterators();
56 
57   void compute_grid();
58   void compute_grid(RealMatrix& var_sets);
59   int grid_size();
60 
61   /// initialize all sparse grid settings (distribution params already
62   /// set within poly_basis)
63   void initialize_grid(const std::vector<BasisPolynomial>& poly_basis);
64 
65   void clear_inactive();
66   void clear_keys();
67 
68   void initialize_sets();
69   void increment_smolyak_multi_index(const UShortArray& set);
70   bool push_trial_available(const UShortArray& key, const UShortArray& tr_set);
71   bool push_trial_available(const UShortArray& key);
72   bool push_trial_available();
73   size_t push_trial_index(const UShortArray& key, const UShortArray& tr_set);
74   size_t push_trial_index(const UShortArray& key);
75   size_t push_trial_index();
76   size_t push_index(const UShortArray& key) const;
77   //size_t finalize_index(size_t i, const UShortArray& key) const;
78 
79   void compute_trial_grid(RealMatrix& var_sets);
80   void push_set();
81   void pop_set();
82   void finalize_sets(bool output_sets, bool converged_within_tol,
83 		     bool reverted);
84 
85   void compute_increment(RealMatrix& var_sets);
86   void push_increment();
87   void pop_increment();
88   void merge_unique();
89 
90   /// return smolyakCoeffsRef
91   const IntArray& smolyak_coefficients_reference() const;
92   /// update smolyakCoeffsRef and type{1,2}WeightSetsRef for use within the
93   /// adaptive grid refinement procedures
94   void update_reference();
95 
96   /// return active trial set under evaluation as a refinement candidate
97   const UShortArray& trial_set() const;
98   /// return trial set corresponding to key
99   const UShortArray& trial_set(const UShortArray& key) const;
100 
101   /// return num_unique2
102   int unique_trial_points() const;
103 
104   //
105   //- Heading: Member functions
106   //
107 
108   /// initialize all sparse grid settings except for distribution params
109   void initialize_grid(unsigned short ssg_level, const RealVector& dim_pref,
110     const MultivariateDistribution& u_dist,
111     const ExpansionConfigOptions& ec_options, BasisConfigOptions& bc_options,
112     short growth_rate = MODERATE_RESTRICTED_GROWTH,
113     bool track_uniq_prod_wts = true);
114 
115   /// update smolyakMultiIndex and smolyakCoeffs
116   void update_smolyak_arrays();
117   /// update collocKey for the trailing index sets within smolyakMultiIndex
118   void update_collocation_key();
119 
120   /// define a1{Points,Type1Weights,Type2Weights} based on the reference grid
121   void reference_unique(bool update_1d_pts_wts = true);
122   /// define a2Points and update collocIndices and uniqueIndexMapping
123   /// for trailing index sets within smolyakMultiIndex
124   void increment_unique(size_t start_index, bool update_1d_pts_wts = true);
125   /// apply all remaining trial sets
126   void finalize_unique(size_t start_index);
127 
128 private:
129 
130   //
131   //- Heading: Convenience functions
132   //
133 
134   /// modular helper for public increment_unique(size_t, bool)
135   void increment_unique_points_weights(size_t start_index,
136     const UShort2DArray& sm_mi, const IntArray& sm_coeffs,
137     const IntArray& sm_coeffs_ref, const UShort3DArray& colloc_key,
138     Sizet2DArray& colloc_ind, int& num_colloc_pts, RealMatrix& a1_pts,
139     RealVector& a1_t1w, RealMatrix& a1_t2w,  RealMatrix& a2_pts,
140     RealVector& a2_t1w, RealMatrix& a2_t2w, RealVector& zv, RealVector& r1v,
141     RealVector& r2v, IntArray& sind1, BitArray& isu1, IntArray& uind1,
142     IntArray& uset1, int& num_u1, IntArray& sind2, BitArray& isu2,
143     IntArray& uind2, IntArray& uset2, int& num_u2, IntArray& unique_index_map,
144     bool update_1d_pts_wts, RealMatrix& pts, RealVector& t1_wts,
145     RealMatrix& t2_wts);
146   /// modular helper for public merge_unique()
147   void merge_unique_points_weights(const UShort2DArray& sm_mi,
148     const IntArray& sm_coeffs, const IntArray& sm_coeffs_ref,
149     const UShort3DArray& colloc_key, Sizet2DArray& colloc_ind,
150     int& num_colloc_pts, RealMatrix& a1_pts, RealVector& a1_t1w,
151     RealMatrix& a1_t2w, RealMatrix& a2_pts, RealVector& a2_t1w,
152     RealMatrix& a2_t2w, RealVector& r1v, RealVector& r2v,
153     IntArray& sind1, BitArray& isu1, IntArray& uind1, IntArray& uset1,
154     int& num_u1, IntArray& sind2, BitArray& isu2, IntArray& uind2,
155     IntArray& uset2, int& num_u2, IntArray& unique_index_map,
156     RealMatrix& pts, RealVector& t1_wts, RealMatrix& t2_wts);
157 
158   /// updates sm_mi from sm_coeffs after uniform/isotropic refinement
159   void update_smolyak_arrays(UShort2DArray& sm_mi, IntArray& sm_coeffs);
160   /// updates sm_mi from sm_coeffs after anisotropic refinement
161   void update_smolyak_arrays_aniso(UShort2DArray& sm_mi, IntArray& sm_coeffs);
162   /// increment sm_{mi,coeffs} to sync with new_sm_{mi,coeffs}
163   void increment_smolyak_arrays(const UShort2DArray& new_sm_mi,
164 				const IntArray& new_sm_coeffs,
165 				UShort2DArray& sm_mi, IntArray& sm_coeffs);
166   /// decrement sm_{mi,coeffs} to sync with new_sm_{mi,coeffs}
167   void decrement_smolyak_arrays(const UShort2DArray& new_sm_mi,
168 				const IntArray& new_sm_coeffs,
169 				UShort2DArray& sm_mi, IntArray& sm_coeffs);
170 
171   /// define an increment to the collocation indices
172   void update_unique_indices(size_t start_index, int num_uniq1,
173 			     const IntArray& xdnu1, const IntArray& undx1,
174 			     const BitArray& isu2,  const IntArray& xdnu2,
175 			     const IntArray& undx2, IntArray& unique_index_map);
176 
177   /// process raw a2 points to create a unique point set increment
178   void increment_sparse_points(const Sizet2DArray& colloc_ind,
179 			       size_t start_index,
180 			       const BitArray& raw_is_unique,
181 			       size_t colloc_index_offset,
182 			       const RealMatrix& raw_incr_pts,
183 			       RealMatrix& unique_incr_pts);
184 
185   /// define the reference type{1,2}WeightSets
186   void assign_sparse_weights();
187   /// update type{1,2}WeightSets based on a grid increment
188   void update_sparse_weights(size_t start_index);
189   /// convenience function for updating sparse weights from two sets of
190   /// tensor weights and updated coefficients
191   void update_sparse_weights(size_t start_index,
192 			     const UShort3DArray& colloc_key,
193 			     const Sizet2DArray& colloc_ind, int num_colloc_pts,
194 			     const IntArray& sm_coeffs,
195 			     const IntArray& sm_coeffs_ref,
196 			     const RealVector& a1_t1_wts,
197 			     const RealMatrix& a1_t2_wts,
198 			     const RealVector& a2_t1_wts,
199 			     const RealMatrix& a2_t2_wts,
200 			     RealVector& unique_t1_wts,
201 			     RealMatrix& unique_t2_wts);
202   /// restore type{1,2}WeightSets to reference values
203   void pop_weights();
204 
205   //
206   //- Heading: Data
207   //
208 
209   /// reference values for the Smolyak combinatorial coefficients;
210   /// used in incremental approaches that update smolyakCoeffs
211   std::map<UShortArray, IntArray> smolyakCoeffsRef;
212   /// reference values for the type1 weights corresponding to the current
213   /// reference grid; used in incremental approaches that update type1WeightSets
214   std::map<UShortArray, RealVector> type1WeightSetsRef;
215   /// reference values for the type2 weights corresponding to the current
216   /// reference grid; used in incremental approaches that update type2WeightSets
217   std::map<UShortArray, RealMatrix> type2WeightSetsRef;
218 
219   /// index into poppedTrialSets for data to be restored
220   std::map<UShortArray, size_t> pushIndex;
221   // indices into poppedTrialSets indicating finalization order
222   //std::map<UShortArray, SizetArray> finalizeIndex;
223 
224   /// number of unique points in set 1 (reference)
225   std::map<UShortArray, int> numUnique1;
226   /// active entry within numUnique1
227   std::map<UShortArray, int>::iterator numUniq1Iter;
228   /// number of unique points in set 2 (increment)
229   std::map<UShortArray, int> numUnique2;
230   /// active entry within numUnique2
231   std::map<UShortArray, int>::iterator numUniq2Iter;
232 
233   /// random vector used within sgmgg for sorting
234   std::map<UShortArray, RealVector> zVec;
235   /// distance values for sorting in set 1 (reference)
236   std::map<UShortArray, RealVector> r1Vec;
237   /// distance values for sorting in set 2 (increment)
238   std::map<UShortArray, RealVector> r2Vec;
239 
240   /// array of collocation points in set 1 (reference)
241   std::map<UShortArray, RealMatrix> a1Points;
242   /// active entry within a1Points
243   std::map<UShortArray, RealMatrix>::iterator a1PIter;
244   /// vector of type1 weights in set 1 (reference)
245   std::map<UShortArray, RealVector> a1Type1Weights;
246   /// active entry within a1Type1Weights
247   std::map<UShortArray, RealVector>::iterator a1T1WIter;
248   /// matrix of type2 weights in set 1 (reference)
249   std::map<UShortArray, RealMatrix> a1Type2Weights;
250   /// active entry within a1Type2Weights
251   std::map<UShortArray, RealMatrix>::iterator a1T2WIter;
252 
253   /// array of collocation points in set 2 (increment)
254   std::map<UShortArray, RealMatrix> a2Points;
255   /// active entry within a2Points
256   std::map<UShortArray, RealMatrix>::iterator a2PIter;
257   /// vector of type1 weights in set 2 (increment)
258   std::map<UShortArray, RealVector> a2Type1Weights;
259   /// active entry within a2Type1Weights
260   std::map<UShortArray, RealVector>::iterator a2T1WIter;
261   /// matrix of type2 weights in set 2 (increment)
262   std::map<UShortArray, RealMatrix> a2Type2Weights;
263   /// active entry within a2Type2Weights
264   std::map<UShortArray, RealMatrix>::iterator a2T2WIter;
265 
266   /// ascending sort index for set 1 (reference)
267   std::map<UShortArray, IntArray> sortIndex1;
268   /// ascending sort index for set 2 (increment)
269   std::map<UShortArray, IntArray> sortIndex2;
270 
271   /// index within a1 (reference set) of unique points
272   std::map<UShortArray, IntArray> uniqueSet1;
273   /// active entry within uniqueSet1
274   std::map<UShortArray, IntArray>::iterator uniqSet1Iter;
275   /// index within a2 (increment set) of unique points
276   std::map<UShortArray, IntArray> uniqueSet2;
277   /// active entry within uniqueSet2
278   std::map<UShortArray, IntArray>::iterator uniqSet2Iter;
279 
280   /// index within uniqueSet1 corresponding to all of a1
281   std::map<UShortArray, IntArray> uniqueIndex1;
282   /// active entry within uniqueIndex1
283   std::map<UShortArray, IntArray>::iterator uniqInd1Iter;
284   /// index within uniqueSet2 corresponding to all of a2
285   std::map<UShortArray, IntArray> uniqueIndex2;
286   /// active entry within uniqueIndex2
287   std::map<UShortArray, IntArray>::iterator uniqInd2Iter;
288 
289   /// key to unique points in set 1 (reference)
290   std::map<UShortArray, BitArray> isUnique1;
291   /// active entry within isUnique1
292   std::map<UShortArray, BitArray>::iterator isUniq1Iter;
293   /// key to unique points in set 2 (increment)
294   std::map<UShortArray, BitArray> isUnique2;
295   /// active entry within isUnique2
296   std::map<UShortArray, BitArray>::iterator isUniq2Iter;
297 };
298 
299 
IncrementalSparseGridDriver()300 inline IncrementalSparseGridDriver::IncrementalSparseGridDriver():
301   CombinedSparseGridDriver(), a1PIter(a1Points.end())
302 { update_active_iterators(); }
303 
304 
305 inline IncrementalSparseGridDriver::
IncrementalSparseGridDriver(unsigned short ssg_level,const RealVector & dim_pref,short growth_rate,short refine_control)306 IncrementalSparseGridDriver(unsigned short ssg_level,
307 			    const RealVector& dim_pref, short growth_rate,
308 			    short refine_control):
309   CombinedSparseGridDriver(ssg_level, dim_pref, growth_rate, refine_control),
310   a1PIter(a1Points.end())
311 { update_active_iterators(); }
312 
313 
~IncrementalSparseGridDriver()314 inline IncrementalSparseGridDriver::~IncrementalSparseGridDriver()
315 { }
316 
317 
update_active_iterators()318 inline void IncrementalSparseGridDriver::update_active_iterators()
319 {
320   // Test for change
321   if (a1PIter != a1Points.end() && a1PIter->first == activeKey)
322     return;
323 
324   a1PIter = a1Points.find(activeKey);
325   if (a1PIter == a1Points.end()) {
326     std::pair<UShortArray, RealMatrix> ua_pair(activeKey, RealMatrix());
327     a1PIter = a1Points.insert(ua_pair).first;
328   }
329   a1T1WIter = a1Type1Weights.find(activeKey);
330   if (a1T1WIter == a1Type1Weights.end()) {
331     std::pair<UShortArray, RealVector> ua_pair(activeKey, RealVector());
332     a1T1WIter = a1Type1Weights.insert(ua_pair).first;
333   }
334   a1T2WIter = a1Type2Weights.find(activeKey);
335   if (a1T2WIter == a1Type2Weights.end()) {
336     std::pair<UShortArray, RealMatrix> ua_pair(activeKey, RealMatrix());
337     a1T2WIter = a1Type2Weights.insert(ua_pair).first;
338   }
339   a2PIter = a2Points.find(activeKey);
340   if (a2PIter == a2Points.end()) {
341     std::pair<UShortArray, RealMatrix> ua_pair(activeKey, RealMatrix());
342     a2PIter = a2Points.insert(ua_pair).first;
343   }
344   a2T1WIter = a2Type1Weights.find(activeKey);
345   if (a2T1WIter == a2Type1Weights.end()) {
346     std::pair<UShortArray, RealVector> ua_pair(activeKey, RealVector());
347     a2T1WIter = a2Type1Weights.insert(ua_pair).first;
348   }
349   a2T2WIter = a2Type2Weights.find(activeKey);
350   if (a2T2WIter == a2Type2Weights.end()) {
351     std::pair<UShortArray, RealMatrix> ua_pair(activeKey, RealMatrix());
352     a2T2WIter = a2Type2Weights.insert(ua_pair).first;
353   }
354   numUniq1Iter = numUnique1.find(activeKey);
355   if (numUniq1Iter == numUnique1.end()) {
356     std::pair<UShortArray, int> ua_pair(activeKey, 0);
357     numUniq1Iter = numUnique1.insert(ua_pair).first;
358   }
359   numUniq2Iter = numUnique2.find(activeKey);
360   if (numUniq2Iter == numUnique2.end()) {
361     std::pair<UShortArray, int> ua_pair(activeKey, 0);
362     numUniq2Iter = numUnique2.insert(ua_pair).first;
363   }
364   uniqSet1Iter = uniqueSet1.find(activeKey);
365   if (uniqSet1Iter == uniqueSet1.end()) {
366     std::pair<UShortArray, IntArray> ua_pair(activeKey, IntArray());
367     uniqSet1Iter = uniqueSet1.insert(ua_pair).first;
368   }
369   uniqSet2Iter = uniqueSet2.find(activeKey);
370   if (uniqSet2Iter == uniqueSet2.end()) {
371     std::pair<UShortArray, IntArray> ua_pair(activeKey, IntArray());
372     uniqSet2Iter = uniqueSet2.insert(ua_pair).first;
373   }
374   uniqInd1Iter = uniqueIndex1.find(activeKey);
375   if (uniqInd1Iter == uniqueIndex1.end()) {
376     std::pair<UShortArray, IntArray> ua_pair(activeKey, IntArray());
377     uniqInd1Iter = uniqueIndex1.insert(ua_pair).first;
378   }
379   uniqInd2Iter = uniqueIndex2.find(activeKey);
380   if (uniqInd2Iter == uniqueIndex2.end()) {
381     std::pair<UShortArray, IntArray> ua_pair(activeKey, IntArray());
382     uniqInd2Iter = uniqueIndex2.insert(ua_pair).first;
383   }
384   isUniq1Iter = isUnique1.find(activeKey);
385   if (isUniq1Iter == isUnique1.end()) {
386     std::pair<UShortArray, BitArray> ua_pair(activeKey, BitArray());
387     isUniq1Iter = isUnique1.insert(ua_pair).first;
388   }
389   isUniq2Iter = isUnique2.find(activeKey);
390   if (isUniq2Iter == isUnique2.end()) {
391     std::pair<UShortArray, BitArray> ua_pair(activeKey, BitArray());
392     isUniq2Iter = isUnique2.insert(ua_pair).first;
393   }
394 
395   CombinedSparseGridDriver::update_active_iterators();
396 }
397 
398 
clear_keys()399 inline void IncrementalSparseGridDriver::clear_keys()
400 {
401   CombinedSparseGridDriver::clear_keys();
402 
403   smolyakCoeffsRef.clear();
404   type1WeightSetsRef.clear(); type2WeightSetsRef.clear();
405 
406   zVec.clear();            r1Vec.clear();          r2Vec.clear();
407   sortIndex1.clear();      sortIndex2.clear();
408 
409   numUnique1.clear();      numUniq1Iter = numUnique1.end();
410   numUnique2.clear();      numUniq2Iter = numUnique2.end();
411   a1Points.clear();        a1PIter      = a1Points.end();
412   a1Type1Weights.clear();  a1T1WIter    = a1Type1Weights.end();
413   a1Type2Weights.clear();  a1T2WIter    = a1Type2Weights.end();
414   a2Points.clear();        a2PIter      = a2Points.end();
415   a2Type1Weights.clear();  a2T1WIter    = a2Type1Weights.end();
416   a2Type2Weights.clear();  a2T2WIter    = a2Type2Weights.end();
417   uniqueSet1.clear();      uniqSet1Iter = uniqueSet1.end();
418   uniqueSet2.clear();      uniqSet2Iter = uniqueSet2.end();
419   uniqueIndex1.clear();    uniqInd1Iter = uniqueIndex1.end();
420   uniqueIndex2.clear();    uniqInd2Iter = uniqueIndex2.end();
421   isUnique1.clear();       isUniq1Iter  = isUnique1.end();
422   isUnique2.clear();       isUniq2Iter  = isUnique2.end();
423 }
424 
425 
compute_grid(RealMatrix & var_sets)426 inline void IncrementalSparseGridDriver::compute_grid(RealMatrix& var_sets)
427 {
428   compute_grid();
429   var_sets = varSetsIter->second; // copy
430 }
431 
432 
433 inline void IncrementalSparseGridDriver::
reference_unique(bool update_1d_pts_wts)434 reference_unique(bool update_1d_pts_wts)
435 {
436   compute_unique_points_weights(smolMIIter->second, smolCoeffsIter->second,
437     collocKeyIter->second, collocIndIter->second, numPtsIter->second,
438     a1PIter->second, a1T1WIter->second, a1T2WIter->second, zVec[activeKey],
439     r1Vec[activeKey], sortIndex1[activeKey], isUniq1Iter->second,
440     uniqInd1Iter->second, uniqSet1Iter->second, numUniq1Iter->second,
441     uniqIndMapIter->second, update_1d_pts_wts, varSetsIter->second,
442     t1WtIter->second, t2WtIter->second);
443 }
444 
445 
446 inline void IncrementalSparseGridDriver::
increment_unique(size_t start_index,bool update_1d_pts_wts)447 increment_unique(size_t start_index, bool update_1d_pts_wts)
448 {
449   increment_unique_points_weights(start_index, smolMIIter->second,
450     smolCoeffsIter->second, smolyakCoeffsRef[activeKey], collocKeyIter->second,
451     collocIndIter->second, numPtsIter->second, a1PIter->second,
452     a1T1WIter->second, a1T2WIter->second, a2PIter->second, a2T1WIter->second,
453     a2T2WIter->second, zVec[activeKey], r1Vec[activeKey], r2Vec[activeKey],
454     sortIndex1[activeKey], isUniq1Iter->second, uniqInd1Iter->second,
455     uniqSet1Iter->second, numUniq1Iter->second, sortIndex2[activeKey],
456     isUniq2Iter->second,  uniqInd2Iter->second, uniqSet2Iter->second,
457     numUniq2Iter->second, uniqIndMapIter->second, update_1d_pts_wts,
458     varSetsIter->second,  t1WtIter->second, t2WtIter->second);
459 }
460 
461 
merge_unique()462 inline void IncrementalSparseGridDriver::merge_unique()
463 {
464   merge_unique_points_weights(smolMIIter->second, smolCoeffsIter->second,
465     smolyakCoeffsRef[activeKey], collocKeyIter->second, collocIndIter->second,
466     numPtsIter->second, a1PIter->second, a1T1WIter->second, a1T2WIter->second,
467     a2PIter->second, a2T1WIter->second, a2T2WIter->second, r1Vec[activeKey],
468     r2Vec[activeKey], sortIndex1[activeKey], isUniq1Iter->second,
469     uniqInd1Iter->second, uniqSet1Iter->second, numUniq1Iter->second,
470     sortIndex2[activeKey], isUniq2Iter->second, uniqInd2Iter->second,
471     uniqSet2Iter->second, numUniq2Iter->second, uniqIndMapIter->second,
472     varSetsIter->second, t1WtIter->second, t2WtIter->second);
473 }
474 
475 
finalize_unique(size_t start_index)476 inline void IncrementalSparseGridDriver::finalize_unique(size_t start_index)
477 {
478   increment_unique(start_index, false);
479   merge_unique();
480 
481   // Note: This doesn't address issue of potential point replication changes
482   // between initial trial set status and finalization.  Need an improved
483   // mechanism for point restore/finalize in Dakota::Approximation.  Could add
484   // a virtual fn to interrogate collocation_indices() from the Approximation
485   // level.  Perhaps run some performance tests first to verify that this
486   // condition is possible (or does structure of admissible indices prevent
487   // replication in trial sets that is not first detected in old sets?).
488 }
489 
490 
491 inline const UShortArray& IncrementalSparseGridDriver::
trial_set(const UShortArray & key) const492 trial_set(const UShortArray& key) const
493 {
494   std::map<UShortArray, UShort2DArray>::const_iterator cit
495     = smolyakMultiIndex.find(key);
496   if (cit == smolyakMultiIndex.end()) {
497     PCerr << "Error: key not found in IncrementalSparseGridDriver::trial_set()"
498 	  << std::endl;
499     abort_handler(-1);
500   }
501   return cit->second.back();
502 }
503 
504 
trial_set() const505 inline const UShortArray& IncrementalSparseGridDriver::trial_set() const
506 { return smolMIIter->second.back(); } // last set appended to active smolyak MI
507 
508 
509 /** identify if newly-pushed trial set exists within stored data sets */
510 inline bool IncrementalSparseGridDriver::
push_trial_available(const UShortArray & key,const UShortArray & tr_set)511 push_trial_available(const UShortArray& key, const UShortArray& tr_set)
512 {
513   const UShortArrayDeque& pop_tr = poppedTrialSets[key];
514   return (std::find(pop_tr.begin(), pop_tr.end(), tr_set) != pop_tr.end());
515 }
516 
517 
518 /** identify if newly-pushed trial set exists within stored data sets */
519 inline bool IncrementalSparseGridDriver::
push_trial_available(const UShortArray & key)520 push_trial_available(const UShortArray& key)
521 {
522   const UShortArrayDeque& pop_tr = poppedTrialSets[key];
523   return
524     (std::find(pop_tr.begin(), pop_tr.end(), trial_set(key)) != pop_tr.end());
525 }
526 
527 
528 /** identify if newly-pushed trial set exists within stored data sets */
push_trial_available()529 inline bool IncrementalSparseGridDriver::push_trial_available()
530 {
531   const UShortArrayDeque& pop_tr = poppedTrialSets[activeKey];
532   return (std::find(pop_tr.begin(), pop_tr.end(), trial_set()) != pop_tr.end());
533 }
534 
535 
536 /** identify where newly-pushed trial set exists within stored data sets */
537 inline size_t IncrementalSparseGridDriver::
push_trial_index(const UShortArray & key,const UShortArray & tr_set)538 push_trial_index(const UShortArray& key, const UShortArray& tr_set)
539 { return find_index(poppedTrialSets[key], tr_set); }
540 
541 
542 /** identify where newly-pushed trial set exists within stored data sets */
543 inline size_t IncrementalSparseGridDriver::
push_trial_index(const UShortArray & key)544 push_trial_index(const UShortArray& key)
545 { return find_index(poppedTrialSets[key], trial_set(key)); }
546 
547 
548 /** identify where newly-pushed trial set exists within stored data sets */
push_trial_index()549 inline size_t IncrementalSparseGridDriver::push_trial_index()
550 { return find_index(poppedTrialSets[activeKey], trial_set()); }
551 
552 
553 inline size_t IncrementalSparseGridDriver::
push_index(const UShortArray & key) const554 push_index(const UShortArray& key) const
555 {
556   std::map<UShortArray, size_t>::const_iterator cit = pushIndex.find(key);
557   return (cit == pushIndex.end()) ? _NPOS : cit->second;
558 }
559 
560 
561 /*
562 inline size_t IncrementalSparseGridDriver::
563 finalize_index(size_t i, const UShortArray& key) const
564 {
565   std::map<UShortArray, SizetArray>::const_iterator cit
566     = finalizeIndex.find(key);
567   return (cit == finalizeIndex.end()) ? _NPOS : cit->second[i];
568 }
569 */
570 
571 
update_reference()572 inline void IncrementalSparseGridDriver::update_reference()
573 {
574   smolyakCoeffsRef[activeKey] = smolCoeffsIter->second;
575   if (trackUniqueProdWeights) {
576     type1WeightSetsRef[activeKey] = t1WtIter->second;
577     if (computeType2Weights)
578       type2WeightSetsRef[activeKey] = t2WtIter->second;
579   }
580 }
581 
582 
pop_weights()583 inline void IncrementalSparseGridDriver::pop_weights()
584 {
585   // restore type{1,2}WeightSets to reference values
586   // (update_sparse_weights() involves overlays so nontrivial to back out)
587   if (trackUniqueProdWeights) {
588     t1WtIter->second = type1WeightSetsRef[activeKey];
589     if (computeType2Weights)
590       t2WtIter->second = type2WeightSetsRef[activeKey];
591   }
592 }
593 
594 
595 inline const IntArray& IncrementalSparseGridDriver::
smolyak_coefficients_reference() const596 smolyak_coefficients_reference() const
597 {
598   std::map<UShortArray, IntArray>::const_iterator cit
599     = smolyakCoeffsRef.find(activeKey);
600   if (cit == smolyakCoeffsRef.end()) {
601     PCerr << "Error: active key not found in CombinedSparseGridDriver::"
602 	  << "smolyak_coefficients_reference()." << std::endl;
603     abort_handler(-1);
604   }
605   return cit->second;
606 }
607 
608 
unique_trial_points() const609 inline int IncrementalSparseGridDriver::unique_trial_points() const
610 { return numUniq2Iter->second; }
611 
612 
613 /** Start from scratch rather than incur incremental coefficient update. */
update_smolyak_arrays()614 inline void IncrementalSparseGridDriver::update_smolyak_arrays()
615 {
616   if (isotropic())
617     update_smolyak_arrays(smolMIIter->second, smolCoeffsIter->second);
618   else
619     update_smolyak_arrays_aniso(smolMIIter->second, smolCoeffsIter->second);
620 }
621 
622 } // namespace Pecos
623 
624 #endif
625