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:        SharedHierarchInterpPolyApproxData
10 //- Description:  Class for Nodal Interpolation Polynomial Approximation
11 //-
12 //- Owner:        Mike Eldred
13 
14 #ifndef SHARED_HIERARCH_INTERP_POLY_APPROX_DATA_HPP
15 #define SHARED_HIERARCH_INTERP_POLY_APPROX_DATA_HPP
16 
17 #include "SharedInterpPolyApproxData.hpp"
18 #include "HierarchSparseGridDriver.hpp"
19 
20 namespace Pecos {
21 
22 
23 /// Derived approximation class for hierarchical interpolation polynomials
24 /// (interpolating values and potentially gradients at collocation points).
25 
26 /** The SharedHierarchInterpPolyApproxData class provides a polynomial
27     approximation based on hierarchical interpolation.  Both local and
28     global hierarchical basis functions are available.  It is used
29     primarily for stochastic collocation approaches to uncertainty
30     quantification. */
31 
32 class SharedHierarchInterpPolyApproxData: public SharedInterpPolyApproxData
33 {
34   //
35   //- Heading: Friends
36   //
37 
38   friend class HierarchInterpPolyApproximation;
39 
40 public:
41 
42   //
43   //- Heading: Constructor and destructor
44   //
45 
46   /// lightweight constructor
47   SharedHierarchInterpPolyApproxData(short basis_type, size_t num_vars);
48   /// full constructor
49   SharedHierarchInterpPolyApproxData(short basis_type, size_t num_vars,
50 				     const ExpansionConfigOptions& ec_options,
51 				     const BasisConfigOptions& bc_options);
52   /// destructor
53   ~SharedHierarchInterpPolyApproxData();
54 
55 protected:
56 
57   //
58   //- Heading: Virtual function redefinitions
59   //
60 
61   void allocate_component_sobol();
62   void increment_component_sobol();
63 
64   void pre_combine_data();
65   //void post_combine_data();
66   void combined_to_active(bool clear_combined = true);
67 
68   void set_new_point(const RealVector& x, const UShortArray& basis_index,
69 		     short order);
70   void set_new_point(const RealVector& x, const UShortArray& basis_index,
71 		     const SizetList& subset_indices, short order);
72 
73   size_t barycentric_exact_index(const UShortArray& basis_index);
74   size_t barycentric_exact_index(const UShortArray& basis_index,
75 				 const SizetList& subset_indices);
76 
77   unsigned short tensor_product_num_key(size_t i, unsigned short level_i);
78   unsigned short tensor_product_max_key(size_t i, unsigned short level_i);
79   void precompute_keys(const UShortArray& basis_index);
80   void precompute_keys(const UShortArray& basis_index,
81 		       const SizetList& subset_indices);
82   void precompute_max_keys(const UShortArray& basis_index);
83   void precompute_max_keys(const UShortArray& basis_index,
84 			   const SizetList& subset_indices);
85 
86 private:
87 
88   //
89   //- Heading: Convenience functions
90   //
91 
92   /// return driverRep cast to requested derived type
93   std::shared_ptr<HierarchSparseGridDriver> hsg_driver();
94 
95   //
96   //- Heading: Data
97   //
98 
99   /// Pecos:PIECEWISE_INTERP_POLYNOMIAL or Pecos:PIECEWISE_CUBIC_INTERP
100   short polyType;
101 
102   /// used for precomputation of the number of hierarchical keys for a
103   /// particular basis_index
104   UShortArray tpNumKeys;
105   /// used for precomputation of the maximum hierarchical key index
106   /// for a particular basis_index
107   UShortArray tpMaxKeys;
108 };
109 
110 
111 inline SharedHierarchInterpPolyApproxData::
SharedHierarchInterpPolyApproxData(short basis_type,size_t num_vars)112 SharedHierarchInterpPolyApproxData(short basis_type, size_t num_vars):
113   SharedInterpPolyApproxData(basis_type, num_vars)
114 { }
115 
116 
117 inline SharedHierarchInterpPolyApproxData::
SharedHierarchInterpPolyApproxData(short basis_type,size_t num_vars,const ExpansionConfigOptions & ec_options,const BasisConfigOptions & bc_options)118 SharedHierarchInterpPolyApproxData(short basis_type, size_t num_vars,
119 				   const ExpansionConfigOptions& ec_options,
120 				   const BasisConfigOptions& bc_options):
121   SharedInterpPolyApproxData(basis_type, num_vars, ec_options, bc_options)
122 { }
123 
124 
~SharedHierarchInterpPolyApproxData()125 inline SharedHierarchInterpPolyApproxData::~SharedHierarchInterpPolyApproxData()
126 { }
127 
128 
129 inline void SharedHierarchInterpPolyApproxData::
set_new_point(const RealVector & x,const UShortArray & basis_index,short order)130 set_new_point(const RealVector& x, const UShortArray& basis_index, short order)
131 {
132   unsigned short bi_j; UShortArray delta_key;
133   std::shared_ptr<HierarchSparseGridDriver> hsg_driver =
134     std::static_pointer_cast<HierarchSparseGridDriver>(driverRep);
135   for (size_t j=0; j<numVars; ++j) {
136     bi_j = basis_index[j];
137     if (bi_j) { // exclusion of pt must be sync'd w/ factors/scalings
138       hsg_driver->level_to_delta_key(j, bi_j, delta_key);
139       polynomialBasis[bi_j][j].set_new_point(x[j], order, delta_key);
140     }
141   }
142 }
143 
144 
145 inline void SharedHierarchInterpPolyApproxData::
set_new_point(const RealVector & x,const UShortArray & basis_index,const SizetList & subset_indices,short order)146 set_new_point(const RealVector& x, const UShortArray& basis_index,
147 	      const SizetList& subset_indices, short order)
148 {
149   SizetList::const_iterator cit; size_t j; unsigned short bi_j;
150   UShortArray delta_key;
151   std::shared_ptr<HierarchSparseGridDriver> hsg_driver =
152     std::static_pointer_cast<HierarchSparseGridDriver>(driverRep);
153   for (cit=subset_indices.begin(); cit!=subset_indices.end(); ++cit) {
154     j = *cit; bi_j = basis_index[j];
155     if (bi_j) { // exclusion of pt must be sync'd w/ factors/scalings
156       hsg_driver->level_to_delta_key(j, bi_j, delta_key);
157       polynomialBasis[bi_j][j].set_new_point(x[j], order, delta_key);
158     }
159   }
160 }
161 
162 
163 inline unsigned short SharedHierarchInterpPolyApproxData::
tensor_product_num_key(size_t i,unsigned short level_i)164 tensor_product_num_key(size_t i, unsigned short level_i)
165 {
166   // for the case of precomputed keys:
167   return tpNumKeys[i];
168 
169   //HierarchSparseGridDriver* hsg_driver = (HierarchSparseGridDriver*)driverRep;
170   //return hsg_driver->level_to_delta_size(i, level_i);
171 }
172 
173 
174 inline unsigned short SharedHierarchInterpPolyApproxData::
tensor_product_max_key(size_t i,unsigned short level_i)175 tensor_product_max_key(size_t i, unsigned short level_i)
176 {
177   // for the case of precomputed keys:
178   return tpMaxKeys[i];
179 
180   //HierarchSparseGridDriver* hsg_driver = (HierarchSparseGridDriver*)driverRep;
181   //return hsg_driver->level_to_delta_pair(i, level_i).second;
182 }
183 
184 
185 inline void SharedHierarchInterpPolyApproxData::
precompute_keys(const UShortArray & basis_index)186 precompute_keys(const UShortArray& basis_index)
187 {
188   std::shared_ptr<HierarchSparseGridDriver> hsg_driver =
189     std::static_pointer_cast<HierarchSparseGridDriver>(driverRep);
190   if (tpNumKeys.empty()) tpNumKeys.resize(numVars);
191   if (tpMaxKeys.empty()) tpMaxKeys.resize(numVars);
192   UShortUShortPair key_pr;
193   for (size_t i=0; i<numVars; ++i) {
194     key_pr = hsg_driver->level_to_delta_pair(i, basis_index[i]);
195     tpNumKeys[i] = key_pr.first; tpMaxKeys[i] = key_pr.second;
196   }
197 }
198 
199 
200 inline void SharedHierarchInterpPolyApproxData::
precompute_keys(const UShortArray & basis_index,const SizetList & subset_indices)201 precompute_keys(const UShortArray& basis_index, const SizetList& subset_indices)
202 {
203   std::shared_ptr<HierarchSparseGridDriver> hsg_driver =
204     std::static_pointer_cast<HierarchSparseGridDriver>(driverRep);
205   if (tpNumKeys.empty()) tpNumKeys.resize(numVars);
206   if (tpMaxKeys.empty()) tpMaxKeys.resize(numVars);
207   SizetList::const_iterator cit; size_t i; UShortUShortPair key_pr;
208   for (cit=subset_indices.begin(); cit!=subset_indices.end(); ++cit) {
209     i = *cit;
210     key_pr = hsg_driver->level_to_delta_pair(i, basis_index[i]);
211     tpNumKeys[i] = key_pr.first; tpMaxKeys[i] = key_pr.second;
212   }
213 }
214 
215 
216 inline void SharedHierarchInterpPolyApproxData::
precompute_max_keys(const UShortArray & basis_index)217 precompute_max_keys(const UShortArray& basis_index)
218 {
219   std::shared_ptr<HierarchSparseGridDriver> hsg_driver =
220     std::static_pointer_cast<HierarchSparseGridDriver>(driverRep);
221   if (tpMaxKeys.empty()) tpMaxKeys.resize(numVars);
222   for (size_t i=0; i<numVars; ++i)
223     tpMaxKeys[i] = hsg_driver->level_to_delta_pair(i, basis_index[i]).second;
224 }
225 
226 
227 inline void SharedHierarchInterpPolyApproxData::
precompute_max_keys(const UShortArray & basis_index,const SizetList & subset_indices)228 precompute_max_keys(const UShortArray& basis_index,
229 		    const SizetList& subset_indices)
230 {
231   std::shared_ptr<HierarchSparseGridDriver> hsg_driver =
232     std::static_pointer_cast<HierarchSparseGridDriver>(driverRep);
233   if (tpMaxKeys.empty()) tpMaxKeys.resize(numVars);
234   SizetList::const_iterator cit; size_t i;
235   for (cit=subset_indices.begin(); cit!=subset_indices.end(); ++cit) {
236     i = *cit;
237     tpMaxKeys[i] = hsg_driver->level_to_delta_pair(i, basis_index[i]).second;
238   }
239 }
240 
241 
242 inline std::shared_ptr<HierarchSparseGridDriver>
hsg_driver()243 SharedHierarchInterpPolyApproxData::hsg_driver()
244 { return std::static_pointer_cast<HierarchSparseGridDriver>(driverRep); }
245 
246 } // namespace Pecos
247 
248 #endif
249