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