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: RangeVariable
10 //- Description: Encapsulates random variable data and utilities
11 //- Owner: Mike Eldred
12 //- Revised by:
13 //- Version:
14
15 #ifndef RANGE_VARIABLE_HPP
16 #define RANGE_VARIABLE_HPP
17
18 #include "RandomVariable.hpp"
19 #include "UniformRandomVariable.hpp"
20
21 namespace Pecos {
22
23
24 /// Derived RandomVariable class for range variables.
25
26 /** This is distinct from UniformRandomVariable in that it is used for
27 non-random types without associated probability densities. As
28 such, some statistical operations are suppressed. */
29
30 template <typename T>
31 class RangeVariable: public RandomVariable
32 {
33 public:
34
35 //
36 //- Heading: Constructors and destructor
37 //
38
39 /// default constructor
40 RangeVariable();
41 /// alternate constructor
42 RangeVariable(T lwr, T upr);
43 /// destructor
44 ~RangeVariable();
45
46 //
47 //- Heading: Virtual function redefinitions
48 //
49
50 Real cdf(Real x) const;
51 Real ccdf(Real x) const;
52 Real inverse_cdf(Real p_cdf) const;
53 Real inverse_ccdf(Real p_ccdf) const;
54
55 Real pdf(Real x) const;
56 Real pdf_gradient(Real x) const;
57 Real pdf_hessian(Real x) const;
58 Real log_pdf_gradient(Real x) const;
59 Real log_pdf_hessian(Real x) const;
60
61 Real mean() const;
62 //Real median() const;
63 Real mode() const;
64 Real standard_deviation() const;
65 Real variance() const;
66
67 RealRealPair moments() const;
68 RealRealPair distribution_bounds() const;
69
70 void lower_bound(T l_bnd);
71 void upper_bound(T l_bnd);
72
73 //Real coefficient_of_variation() const;
74
75 void pull_parameter(short dist_param, T& val) const;
76 void push_parameter(short dist_param, T val);
77
78 void copy_parameters(const RandomVariable& rv);
79
80 Real correlation_warping_factor(const RandomVariable& rv, Real corr) const;
81 Real dx_ds(short dist_param, short u_type, Real x, Real z) const;
82 Real dz_ds_factor(short u_type, Real x, Real z) const;
83
84 //
85 //- Heading: Member functions
86 //
87
88 void update(T lwr, T upr);
89
90 //
91 //- Heading: Static member functions (global utilities)
92 //
93
94 //static void moments_from_params(T lwr, T upr, Real& mean, Real& std_dev);
95
96 protected:
97
98 //
99 //- Heading: Member functions
100 //
101
102 void no_template_specialization(String fn) const;
103
104 //
105 //- Heading: Data
106 //
107
108 /// lower bound of range variable
109 T lowerBnd;
110 /// upper bound of range variable
111 T upperBnd;
112 };
113
114
115 //// GENERIC ////
116
117
118 template <typename T>
RangeVariable()119 RangeVariable<T>::RangeVariable():
120 RandomVariable(BaseConstructor())
121 { }
122
123
124 template <typename T>
RangeVariable(T lwr,T upr)125 RangeVariable<T>::RangeVariable(T lwr, T upr):
126 RandomVariable(BaseConstructor())
127 { update(lwr, upr); }
128
129
130 template <typename T>
~RangeVariable()131 RangeVariable<T>::~RangeVariable()
132 { }
133
134
135 template <typename T>
update(T lwr,T upr)136 void RangeVariable<T>::update(T lwr, T upr)
137 { lowerBnd = lwr; upperBnd = upr; }
138 // specializations used for assigning ranVarType, but could also employ
139 // std::is_same for type identification
140
141
142 template <typename T>
pull_parameter(short dist_param,T & val) const143 void RangeVariable<T>::pull_parameter(short dist_param, T& val) const
144 {
145 // could specialize template, but case aggregation seems adequate
146
147 switch (dist_param) {
148 case CR_LWR_BND: case DR_LWR_BND: val = lowerBnd; break;
149 case CR_UPR_BND: case DR_UPR_BND: val = upperBnd; break;
150 default:
151 PCerr << "Error: update failure for distribution parameter " << dist_param
152 << " in RangeVariable::pull_parameter(T)." << std::endl;
153 abort_handler(-1); break;
154 }
155 }
156
157
158 template <typename T>
push_parameter(short dist_param,T val)159 void RangeVariable<T>::push_parameter(short dist_param, T val)
160 {
161 // could specialize template, but case aggregation seems adequate
162
163 switch (dist_param) {
164 case CR_LWR_BND: case DR_LWR_BND: lowerBnd = val; break;
165 case CR_UPR_BND: case DR_UPR_BND: upperBnd = val; break;
166 default:
167 PCerr << "Error: update failure for distribution parameter " << dist_param
168 << " in RangeVariable::push_parameter(T)." << std::endl;
169 abort_handler(-1); break;
170 }
171 }
172
173
174 template <typename T>
copy_parameters(const RandomVariable & rv)175 void RangeVariable<T>::copy_parameters(const RandomVariable& rv)
176 {
177 switch (ranVarType) {
178 case CONTINUOUS_RANGE:
179 rv.pull_parameter(CR_LWR_BND, lowerBnd);
180 rv.pull_parameter(CR_UPR_BND, upperBnd); break;
181 case DISCRETE_RANGE:
182 rv.pull_parameter(DR_LWR_BND, lowerBnd);
183 rv.pull_parameter(DR_UPR_BND, upperBnd); break;
184 }
185 }
186
187
188 template <typename T>
lower_bound(T l_bnd)189 void RangeVariable<T>::lower_bound(T l_bnd)
190 { lowerBnd = l_bnd; }
191
192
193 template <typename T>
upper_bound(T u_bnd)194 void RangeVariable<T>::upper_bound(T u_bnd)
195 { upperBnd = u_bnd; }
196
197
198 template <typename T>
no_template_specialization(String fn) const199 void RangeVariable<T>::no_template_specialization(String fn) const
200 {
201 PCerr << "Error: no template specialization of " << fn << "() for "
202 << "RangeVariable<T>." << std::endl;
203 abort_handler(-1);
204 }
205
206
207 template <typename T>
pdf(Real x) const208 Real RangeVariable<T>::pdf(Real x) const
209 { no_template_specialization("pdf"); return 0.; }
210
211
212 template <typename T>
pdf_gradient(Real x) const213 Real RangeVariable<T>::pdf_gradient(Real x) const
214 { return 0.; }
215
216
217 template <typename T>
pdf_hessian(Real x) const218 Real RangeVariable<T>::pdf_hessian(Real x) const
219 { return 0.; }
220
221
222 template <typename T>
log_pdf_gradient(Real x) const223 Real RangeVariable<T>::log_pdf_gradient(Real x) const
224 { return 0.; }
225
226
227 template <typename T>
log_pdf_hessian(Real x) const228 Real RangeVariable<T>::log_pdf_hessian(Real x) const
229 { return 0.; }
230
231
232 template <typename T>
cdf(Real x) const233 Real RangeVariable<T>::cdf(Real x) const
234 { no_template_specialization("cdf"); return 0.; }
235
236
237 template <typename T>
ccdf(Real x) const238 Real RangeVariable<T>::ccdf(Real x) const
239 { no_template_specialization("ccdf"); return 0.; }
240
241
242 template <typename T>
inverse_cdf(Real p_cdf) const243 Real RangeVariable<T>::inverse_cdf(Real p_cdf) const
244 { no_template_specialization("inverse_cdf"); return 0.; }
245
246
247 template <typename T>
inverse_ccdf(Real p_ccdf) const248 Real RangeVariable<T>::inverse_ccdf(Real p_ccdf) const
249 { no_template_specialization("inverse_ccdf"); return 0.; }
250
251
252 template <typename T>
moments() const253 RealRealPair RangeVariable<T>::moments() const
254 { no_template_specialization("moments"); return RealRealPair(); }
255
256
257 template <typename T>
mean() const258 Real RangeVariable<T>::mean() const
259 { return moments().first; }
260
261
262 //template <typename T>
263 //Real RangeVariable<T>::median() const
264 //{ return inverse_cdf(.5); }
265
266
267 template <typename T>
standard_deviation() const268 Real RangeVariable<T>::standard_deviation() const
269 { return moments().second; }
270
271
272 template <typename T>
variance() const273 Real RangeVariable<T>::variance() const
274 { Real std_dev = moments().second; return std_dev * std_dev; }
275
276
277 //template <typename T>
278 //Real RangeVariable<T>::coefficient_of_variation() const
279 //{ RealRealPair mom = moments(); return mom.second / mom.first; }
280
281
282 template <typename T>
mode() const283 Real RangeVariable<T>::mode() const
284 { return moments().first; } // not well-defined: any value in [L,U] is valid
285
286
287 /*
288 /// for T-valued histogram, return a real-valued mean and std dev
289 template <typename T>
290 void RangeVariable<T>::
291 moments_from_params(const std::set<T>& vals, Real& mean, Real& std_dev)
292 {
293 mean = 0.;
294 Real val, raw2 = 0.; size_t num_vals = vals.size();
295 typename std::set<T>::const_iterator cit;
296 for (cit = vals.begin(); cit != vals.end(); ++cit) {
297 val = (Real)(*cit);
298 mean += val;
299 raw2 += val * val;
300 }
301 mean /= num_vals; raw2 /= num_vals;
302 std_dev = std::sqrt(raw2 - mean * mean);
303 }
304 */
305
306
307 template <typename T>
distribution_bounds() const308 RealRealPair RangeVariable<T>::distribution_bounds() const
309 { return RealRealPair((Real)lowerBnd, (Real)upperBnd); }
310
311
312 template <typename T>
313 Real RangeVariable<T>::
correlation_warping_factor(const RandomVariable & rv,Real corr) const314 correlation_warping_factor(const RandomVariable& rv, Real corr) const
315 { no_template_specialization("correlation_warping_factor"); return 0.; }
316
317
318 template <typename T>
319 Real RangeVariable<T>::
dx_ds(short dist_param,short u_type,Real x,Real z) const320 dx_ds(short dist_param, short u_type, Real x, Real z) const
321 { no_template_specialization("dx_ds"); return 0.; }
322
323
324 template <typename T>
dz_ds_factor(short u_type,Real x,Real z) const325 Real RangeVariable<T>::dz_ds_factor(short u_type, Real x, Real z) const
326 { no_template_specialization("dz_ds_factor"); return 0.; }
327
328
329 //// SPECIALIZATIONS ////
330
331
332 template <>
pdf(Real x) const333 inline Real RangeVariable<Real>::pdf(Real x) const
334 { return UniformRandomVariable::pdf(x, lowerBnd, upperBnd); }
335
336
337 template <>
cdf(Real x) const338 inline Real RangeVariable<Real>::cdf(Real x) const
339 { return UniformRandomVariable::cdf(x, lowerBnd, upperBnd); }
340
341
342 template <>
ccdf(Real x) const343 inline Real RangeVariable<Real>::ccdf(Real x) const
344 { return UniformRandomVariable::ccdf(x, lowerBnd, upperBnd); }
345
346
347 template <>
inverse_cdf(Real p_cdf) const348 inline Real RangeVariable<Real>::inverse_cdf(Real p_cdf) const
349 { return UniformRandomVariable::inverse_cdf(p_cdf, lowerBnd, upperBnd); }
350
351
352 template <>
inverse_ccdf(Real p_ccdf) const353 inline Real RangeVariable<Real>::inverse_ccdf(Real p_ccdf) const
354 { return UniformRandomVariable::inverse_ccdf(p_ccdf, lowerBnd, upperBnd); }
355
356
357 template <>
moments() const358 inline RealRealPair RangeVariable<Real>::moments() const
359 {
360 RealRealPair moms;
361 UniformRandomVariable::
362 moments_from_params(lowerBnd, upperBnd, moms.first, moms.second);
363 return moms;
364 }
365
366
367 template <>
368 inline Real RangeVariable<Real>::
correlation_warping_factor(const RandomVariable & rv,Real corr) const369 correlation_warping_factor(const RandomVariable& rv, Real corr) const
370 { return UniformRandomVariable::corr_warp_fact(rv, corr); }
371
372
373 template <>
374 inline Real RangeVariable<Real>::
dx_ds(short dist_param,short u_type,Real x,Real z) const375 dx_ds(short dist_param, short u_type, Real x, Real z) const
376 {
377 return UniformRandomVariable::
378 dx_ds_fact(dist_param, u_type, ranVarType, x, z);
379 }
380
381
382 template <>
383 inline Real RangeVariable<Real>::
dz_ds_factor(short u_type,Real x,Real z) const384 dz_ds_factor(short u_type, Real x, Real z) const
385 { return UniformRandomVariable::dz_ds_fact(u_type, upperBnd - lowerBnd, x, z); }
386
387 } // namespace Pecos
388
389 #endif
390