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: SharedRegressPolyApproxData
10 //- Description: Class for Multivariate Orthogonal Polynomial Approximations
11 //-
12 //- Owner: John Jakeman
13
14 #ifndef SHARED_REGRESS_ORTHOG_POLY_APPROX_DATA_HPP
15 #define SHARED_REGRESS_ORTHOG_POLY_APPROX_DATA_HPP
16
17 #include "SharedOrthogPolyApproxData.hpp"
18 #include "LightweightSparseGridDriver.hpp"
19 #include "LinearSolverPecosSrc.hpp"
20
21 namespace Pecos {
22
23
24 /// Container class for various regression configuration options
25
26 /** The RegressionConfigOptions class provides a simple container class
27 for regression configuration options related to ... */
28
29 class RegressionConfigOptions
30 {
31 //
32 //- Heading: Friends
33 //
34
35 //friend class PolynomialApproximation;
36
37 public:
38
39 /// default constructor
40 RegressionConfigOptions();
41 /// constructor
42 RegressionConfigOptions(bool cv, bool cv_noise_only, int seed,
43 const RealVector& noise_tols, Real l2_penalty,
44 bool normalize_cv, unsigned short init_lev,
45 unsigned short growth_fact,
46 unsigned short num_advance);
47 /// copy constructor
48 RegressionConfigOptions(const RegressionConfigOptions& rc_options);
49 /// destructor
50 ~RegressionConfigOptions();
51
52 //private:
53
54 /// flag for use of automatic cross-validation for parameter
55 /// selection in regression approaches
56 bool crossValidation;
57 /// flag to restrict cross-validation to only estimate the noise
58 /// tolerance in order to manage computational cost
59 bool crossValidNoiseOnly;
60
61 /// random seed for data fold definition within cross validation
62 int randomSeed;
63
64 /// noise tolerance(s) for compressed sensing algorithms; vector form
65 /// used in cross-validation
66 RealVector noiseTols;
67 /// the L2 penalty parameter for LASSO (elastic net variant)
68 Real l2Penalty;
69
70 /// flag indicating whether to scale the CV error estimates by the size
71 /// of the candidate basis expansion within adapted basis selection
72 bool normalizeCV;
73
74 /// initial sparse grid level that provides the starting point for basis
75 /// adaptation in ADAPTED_BASIS_GENERALIZED mode
76 unsigned short initSGLevel;
77 /// a scalar growth factor for defining the tpMultiIndex contribution
78 /// from a particular trial index set for basis adaptation in
79 /// ADAPTED_BASIS_GENERALIZED mode
80 unsigned short multiIndexGrowthFactor;
81
82 /// number of front expansions per iteration for basis adaptation in
83 /// ADAPTED_BASIS_EXPANDING_FRONT mode
84 unsigned short numAdvancements;
85
86 /// flag indicating restriction and front expansion using a multi-index
87 /// frontier
88 /** This option reduces memory requirements somewhat, but allowing
89 multi-index gaps in the general case results in reduced mutual
90 coherence and better numerical performance. */
91 bool advanceByFrontier;
92 };
93
94
RegressionConfigOptions()95 inline RegressionConfigOptions::RegressionConfigOptions():
96 crossValidation(false), crossValidNoiseOnly(false), randomSeed(0),
97 l2Penalty(0.), normalizeCV(false), initSGLevel(0), multiIndexGrowthFactor(2),
98 numAdvancements(3), advanceByFrontier(false)
99 { }
100
101
102 inline RegressionConfigOptions::
RegressionConfigOptions(bool cv,bool cv_noise_only,int seed,const RealVector & noise_tols,Real l2_penalty,bool normalize_cv,unsigned short init_lev,unsigned short growth_fact,unsigned short num_advance)103 RegressionConfigOptions(bool cv, bool cv_noise_only, int seed,
104 const RealVector& noise_tols,
105 Real l2_penalty, bool normalize_cv,
106 unsigned short init_lev, unsigned short growth_fact,
107 unsigned short num_advance):
108 crossValidation(cv), crossValidNoiseOnly(cv_noise_only), randomSeed(seed),
109 noiseTols(noise_tols), l2Penalty(l2_penalty), normalizeCV(normalize_cv),
110 initSGLevel(init_lev), multiIndexGrowthFactor(growth_fact),
111 numAdvancements(num_advance), advanceByFrontier(false)
112 { }
113
114
115 inline RegressionConfigOptions::
RegressionConfigOptions(const RegressionConfigOptions & rc_options)116 RegressionConfigOptions(const RegressionConfigOptions& rc_options):
117 crossValidation(rc_options.crossValidation),
118 crossValidNoiseOnly(rc_options.crossValidNoiseOnly),
119 randomSeed(rc_options.randomSeed), noiseTols(rc_options.noiseTols),
120 l2Penalty(rc_options.l2Penalty), normalizeCV(rc_options.normalizeCV),
121 initSGLevel(rc_options.initSGLevel),
122 multiIndexGrowthFactor(rc_options.multiIndexGrowthFactor),
123 numAdvancements(rc_options.numAdvancements),
124 advanceByFrontier(rc_options.advanceByFrontier)
125 { }
126
127
~RegressionConfigOptions()128 inline RegressionConfigOptions::~RegressionConfigOptions()
129 { }
130
131
132 /// Derived approximation class for multivariate orthogonal polynomial
133 /// approximation with coefficient estimation via regression.
134
135 /** The SharedRegressOrthogPolyApproxData class provides a global
136 approximation based on multivariate orthogonal polynomials, where
137 the coefficients are computed using regression approaches such as
138 least squares (L2) or compressed sensing (L1). It is used
139 primarily for polynomial chaos expansion aproaches to UQ. */
140
141 class SharedRegressOrthogPolyApproxData: public SharedOrthogPolyApproxData
142 {
143 //
144 //- Heading: Friends
145 //
146
147 friend class RegressOrthogPolyApproximation;
148
149 public:
150
151 //
152 //- Heading: Constructor and destructor
153 //
154
155 /// lightweight constructor
156 SharedRegressOrthogPolyApproxData(short basis_type,
157 const UShortArray& approx_order,
158 size_t num_vars);
159 /// full constructor
160 SharedRegressOrthogPolyApproxData(short basis_type,
161 const UShortArray& approx_order,
162 size_t num_vars,
163 const ExpansionConfigOptions& ec_options,
164 const BasisConfigOptions& bc_options,
165 const RegressionConfigOptions& rc_options);
166 /// destructor
167 ~SharedRegressOrthogPolyApproxData();
168
169 //
170 //- Heading: Member functions
171 //
172
173 /// helper function for incrementing that is modular on trial set and
174 /// multi-index
175 void increment_trial_set(const UShortArray& trial_set,
176 UShort2DArray& aggregated_mi);
177
178 /// define the TP index sets that can be removed from a generalized
179 /// sparse grid based on the recovered sparse_indices; used for the
180 /// restriction operation within basis adaptation
181 bool set_restriction(UShort2DArray& aggregated_mi, SizetSet& sparse_indices,
182 SizetSet& save_tp);
183
184 /// clear adapted basis bookkeeping
185 void clear_adapted();
186
187 /// set regressConfigOptions
188 void configuration_options(const RegressionConfigOptions& rc_options);
189
190 protected:
191
192 //
193 //- Heading: Virtual function redefinitions
194 //
195
196 void allocate_data();
197 void increment_data();
198 void decrement_data();
199
200 void pre_push_data();
201 //void post_push_data();
202
203 //void pre_finalize_data();
204 //void post_finalize_data();
205
206 //
207 //- Heading: Member functions
208 //
209
210 /// append multi-indices from append_mi that do not already appear in
211 /// combined_mi (consistent ordering assumed); define append_mi_map
212 /// and append_mi_map_ref
213 void append_leading_multi_index(const UShort2DArray& append_mi,
214 UShort2DArray& combined_mi,
215 SizetSet& append_mi_map,
216 size_t& append_mi_map_ref);
217 /// append multi-indices from append_mi that do not already appear in
218 /// combined_mi, updating sparse_indices, exp_coeffs, and exp_coeff_grads
219 void append_sparse_multi_index(SizetSet& sparse_indices,
220 const UShort2DArray& append_mi,
221 UShort2DArray& combined_mi,
222 RealVector& exp_coeffs,
223 RealMatrix& exp_coeff_grads);
224
225 private:
226
227 //
228 //- Heading: Member functions
229 //
230
231 /// update shared approxOrder based on settings computed for one of the QoI
232 void update_approx_order(unsigned short new_order);
233 /// convert active approxOrder to active multiIndex according to basis type
234 void approx_order_to_multi_index();
235
236 /// pack polynomial contributions to Psi matrix for regression
237 void pack_polynomial_data(const RealVector& c_vars, const UShortArray& mi,
238 bool add_val, double* pack_val, size_t& pv_cntr,
239 bool add_grad, double* pack_grad, size_t& pg_cntr);
240 /// pack response contributions to RHS for regression
241 void pack_response_data(const SurrogateDataResp& sdr,
242 bool add_val, double* pack_val, size_t& pv_cntr,
243 bool add_grad, double* pack_grad, size_t& pg_cntr);
244
245 //
246 //- Heading: Data
247 //
248
249 /// container for regression configuration options
250 RegressionConfigOptions regressConfigOptions;
251
252 /// Wrapper class that is used to solve regression problems
253 CompressedSensingTool CSTool;
254
255 /// lower matrix factor in factorization
256 RealMatrix lowerFactor;
257 /// upper matrix factor in factorization
258 RealMatrix upperFactor;
259 /// pivoting history of block-LU factorization
260 RealMatrix pivotHistory;
261 /// pivoting vector
262 IntVector pivotVect;
263
264 /// sparse grid driver for adapting a CS candidate basis using greedy
265 /// adaptation via the generalized sparse grid algorithm; it's state
266 /// is reset for each response QoI
267 LightweightSparseGridDriver lsgDriver;
268 };
269
270
271 inline SharedRegressOrthogPolyApproxData::
SharedRegressOrthogPolyApproxData(short basis_type,const UShortArray & approx_order,size_t num_vars)272 SharedRegressOrthogPolyApproxData(short basis_type,
273 const UShortArray& approx_order,
274 size_t num_vars):
275 SharedOrthogPolyApproxData(basis_type, approx_order, num_vars)
276 { }
277
278
279 inline SharedRegressOrthogPolyApproxData::
SharedRegressOrthogPolyApproxData(short basis_type,const UShortArray & approx_order,size_t num_vars,const ExpansionConfigOptions & ec_options,const BasisConfigOptions & bc_options,const RegressionConfigOptions & rc_options)280 SharedRegressOrthogPolyApproxData(short basis_type,
281 const UShortArray& approx_order,
282 size_t num_vars,
283 const ExpansionConfigOptions& ec_options,
284 const BasisConfigOptions& bc_options,
285 const RegressionConfigOptions& rc_options):
286 SharedOrthogPolyApproxData(basis_type, approx_order, num_vars,
287 ec_options, bc_options),
288 regressConfigOptions(rc_options)
289 { }
290
291
~SharedRegressOrthogPolyApproxData()292 inline SharedRegressOrthogPolyApproxData::~SharedRegressOrthogPolyApproxData()
293 { }
294
295
296 inline void SharedRegressOrthogPolyApproxData::
configuration_options(const RegressionConfigOptions & rc_options)297 configuration_options(const RegressionConfigOptions& rc_options)
298 { regressConfigOptions = rc_options; }
299
300
clear_adapted()301 inline void SharedRegressOrthogPolyApproxData::clear_adapted()
302 {
303 switch (expConfigOptions.expBasisType) {
304 case ADAPTED_BASIS_GENERALIZED:
305 // reset tensor-product bookkeeping and save restorable data
306 //poppedLevMultiIndex[activeKey].clear();
307 poppedMultiIndex[activeKey].clear();
308 poppedMultiIndexMap[activeKey].clear();
309 poppedMultiIndexMapRef[activeKey].clear();
310
311 tpMultiIndex[activeKey].clear(); // will be rebuilt in allocate_data()
312 tpMultiIndexMap[activeKey].clear(); // will be rebuilt in allocate_data()
313 tpMultiIndexMapRef[activeKey].clear(); // will be rebuilt in allocate_data()
314 break;
315 }
316 }
317
318 } // namespace Pecos
319
320 #endif
321