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: RandomVariable
10 //- Description:
11 //- Owner: Mike Eldred
12 //- Revised by:
13 //- Version:
14
15 #ifndef RANDOM_VARIABLE_HPP
16 #define RANDOM_VARIABLE_HPP
17
18 #include "pecos_stat_util.hpp"
19
20 namespace Pecos {
21
22
23 /// base class for random variable hierarchy
24
25 /** This class enables cdf(), ccdf(), inverse_cdf(), inverse_ccdf(),
26 pdf(), pdf_gradient(), pdf_hessian(), and related random variable
27 utilities from contained distribution parameters. */
28
29 // ExtremeValueBase: Gumbel, Frechet, Weibull -> alpha, beta, no bounds
30 // EmpiricalBase: histogram bin, KDE, ...
31
32 class RandomVariable
33 {
34 public:
35
36 //
37 //- Heading: Constructors, destructor, and operator=
38 //
39
40 /// default constructor
41 RandomVariable();
42 /// standard constructor for envelope
43 RandomVariable(short ran_var_type);
44 /// copy constructor
45 RandomVariable(const RandomVariable& ran_var);
46
47 /// destructor
48 virtual ~RandomVariable();
49
50 /// assignment operator
51 RandomVariable operator=(const RandomVariable& ran_var);
52
53 //
54 //- Heading: Virtual functions
55 //
56
57 /// return the cumulative distribution function value of the random
58 /// variable at x
59 virtual Real cdf(Real x) const;
60 /// return the x value corresponding to a cumulative probability
61 virtual Real inverse_cdf(Real p_cdf) const;
62
63 /// return the complementary cumulative distribution function value
64 /// of the random variable at x
65 virtual Real ccdf(Real x) const;
66 /// return the x value corresponding to a complementary cumulative probability
67 virtual Real inverse_ccdf(Real p_ccdf) const;
68
69 /// return the value of the random variable's probability density
70 /// function at x
71 virtual Real pdf(Real x) const;
72 /// return the gradient of the random variable's probability density
73 /// function at x
74 virtual Real pdf_gradient(Real x) const;
75 /// return the hessian of the random variable's probability density
76 /// function at x
77 virtual Real pdf_hessian(Real x) const;
78 /// return the value of the natural log of the random variable's probability
79 /// density function at x (useful for calculations of log density in Bayesian
80 /// methods)
81 virtual Real log_pdf(Real x) const;
82 /// return the gradient of the natural log of the random variable's
83 /// probability density function at x (useful for defining MCMC proposal
84 /// distributions in Bayesian methods)
85 virtual Real log_pdf_gradient(Real x) const;
86 /// return the Hessian of the natural log of the random variable's probability
87 /// density function at x (useful for defining MCMC proposal distributions in
88 /// Bayesian methods)
89 virtual Real log_pdf_hessian(Real x) const;
90
91 /// return the x value for a standardized probability distribution
92 /// corresponding to a cumulative probability
93 virtual Real inverse_standard_cdf(Real p_cdf) const;
94
95 /// return the value of a standardized random variable's probability density
96 /// function at x
97 virtual Real standard_pdf(Real z) const;
98 /// return the natural log of a standardized random variable's probability
99 /// density function at x (useful for calculations of log density in
100 /// Bayesian methods)
101 virtual Real log_standard_pdf(Real z) const;
102 /// return the gradient of the natural log of a standardized random
103 /// variable's probability density function at x (useful for
104 /// calculations of log density in Bayesian methods)
105 virtual Real log_standard_pdf_gradient(Real z) const;
106 /// return the Hessian of the natural log of a standardized random
107 /// variable's probability density function at x (useful for
108 /// calculations of log density in Bayesian methods)
109 virtual Real log_standard_pdf_hessian(Real z) const;
110
111 /// scale variable value x from current to standardized distribution
112 virtual Real to_standard(Real x) const;
113 /// scale variable value z from standardized to current distribution
114 virtual Real from_standard(Real z) const;
115
116 /// return the value of the named distribution parameter
117 virtual void pull_parameter(short dist_param, Real& val) const;
118 /// return the value of the named distribution parameter
119 virtual void pull_parameter(short dist_param, int& val) const;
120 /// return the value of the named distribution parameter
121 virtual void pull_parameter(short dist_param, unsigned int& val) const;
122 /// return the value of the named distribution parameter
123 virtual void pull_parameter(short dist_param, IntSet& val) const;
124 /// return the value of the named distribution parameter
125 virtual void pull_parameter(short dist_param, StringSet& val) const;
126 /// return the value of the named distribution parameter
127 virtual void pull_parameter(short dist_param, RealSet& val) const;
128 /// return the value of the named distribution parameter
129 virtual void pull_parameter(short dist_param, IntRealMap& val) const;
130 /// return the value of the named distribution parameter
131 virtual void pull_parameter(short dist_param, StringRealMap& val) const;
132 /// return the value of the named distribution parameter
133 virtual void pull_parameter(short dist_param, RealRealMap& val) const;
134 /// return the value of the named distribution parameter
135 virtual void pull_parameter(short dist_param, IntIntPairRealMap& val) const;
136 /// return the value of the named distribution parameter
137 virtual void pull_parameter(short dist_param, RealRealPairRealMap& val) const;
138
139 /// update the value of the named distribution parameter
140 virtual void push_parameter(short dist_param, Real val);
141 /// update the value of the named distribution parameter
142 virtual void push_parameter(short dist_param, int val);
143 /// update the value of the named distribution parameter
144 virtual void push_parameter(short dist_param, unsigned int val);
145 /// update the value of the named distribution parameter
146 virtual void push_parameter(short dist_param, const IntSet& val);
147 /// update the value of the named distribution parameter
148 virtual void push_parameter(short dist_param, const StringSet& val);
149 /// update the value of the named distribution parameter
150 virtual void push_parameter(short dist_param, const RealSet& val);
151 /// update the value of the named distribution parameter
152 virtual void push_parameter(short dist_param, const IntRealMap& val);
153 /// update the value of the named distribution parameter
154 virtual void push_parameter(short dist_param, const StringRealMap& val);
155 /// update the value of the named distribution parameter
156 virtual void push_parameter(short dist_param, const RealRealMap& val);
157 /// update the value of the named distribution parameter
158 virtual void push_parameter(short dist_param, const IntIntPairRealMap& val);
159 /// update the value of the named distribution parameter
160 virtual void push_parameter(short dist_param, const RealRealPairRealMap& val);
161
162 /// copy the distribution parameter values from rv into *this
163 virtual void copy_parameters(const RandomVariable& rv);
164
165 /// return the distribution mean
166 virtual Real mean() const;
167 /// return the distribution mode
168 virtual Real median() const;
169 /// return the distribution mode
170 virtual Real mode() const;
171 /// return the distribution variance
172 virtual Real standard_deviation() const;
173 /// return the distribution variance
174 virtual Real variance() const;
175
176 /// return the distribution mean and standard deviation as a pair
177 /** default is only overridden when more efficient to compute together */
178 virtual RealRealPair moments() const;
179
180 /// return the distribution lower and upper bounds as a pair
181 virtual RealRealPair distribution_bounds() const;
182
183 //virtual Real pull_lower_bound() const;
184 //virtual int pull_lower_bound() const;
185 //virtual void push_lower_bound(Real l_bnd);
186 //virtual void push_lower_bound(int l_bnd);
187 virtual void lower_bound(Real l_bnd);
188 virtual void lower_bound(int l_bnd);
189 virtual void upper_bound(Real l_bnd);
190 virtual void upper_bound(int l_bnd);
191
192 /// compute the coefficient of variation (used to compute selected
193 /// correlation warping factors); defined for semi-infinite distributions
194 /// with nonzero mean (lognormal, exponential, gamma, frechet, weibull)
195 /** default is only overridden when more efficient to compute together */
196 virtual Real coefficient_of_variation() const;
197 /// compute the warping factor for correlation between the current
198 /// variable and the one passed in (used in NatafTransformation)
199 virtual Real correlation_warping_factor(const RandomVariable& rv,
200 Real corr) const;
201
202 /// compute the design Jacobian from differentiating the X->Z mapping with
203 /// respect to the distibution parameter s
204 virtual Real dx_ds(short dist_param, short u_type, Real x, Real z) const;
205 /// compute the mapping-specific factor that is multiplied by dz/ds for
206 /// contributions to the dx/ds design Jacobian in the case of correlated
207 /// random variables (dz/ds is evaluated numerically and multiplied by
208 /// this analytic factor)
209 virtual Real dz_ds_factor(short u_type, Real x, Real z) const;
210
211 //
212 //- Heading: Member functions
213 //
214
215 // Invoke virtual pull_parameter(short, T) and return result
216 //template <typename T>
217 //T return_parameter(short dist_param) const;
218
219 /// Draw a sample from the distribution using inverse_cdf on uniform[0,1]
220 template <typename Engine>
221 Real draw_sample(Engine& rng) const;
222 /// Draw a sample from the distribution using inverse_cdf on uniform[0,1]
223 template <typename Engine>
224 Real draw_standard_sample(Engine& rng) const;
225
226 /// set ranVarType
227 void type(short ran_var_type);
228 /// get ranVarType
229 short type() const;
230
231 /// returns ranVarRep for access to derived class member functions
232 /// that are not mapped to the base level
233 std::shared_ptr<RandomVariable> random_variable_rep() const;
234 /// function to check modelRep (does this envelope contain a letter)
235 bool is_null() const;
236
237 protected:
238
239 //
240 //- Heading: Constructors
241 //
242
243 /// constructor initializes the base class part of letter classes
244 /// (BaseConstructor overloading avoids infinite recursion in the
245 /// derived class constructors - Coplien, p. 139)
246 RandomVariable(BaseConstructor);
247
248 //
249 //- Heading: Member functions
250 //
251
252 //
253 //- Heading: Data
254 //
255
256 /// enumeration value indicating type of random variable
257 short ranVarType;
258
259 private:
260
261 //
262 //- Heading: Member functions
263 //
264
265 /// Used only by the standard envelope constructor to initialize
266 /// ranVarRep to the appropriate derived type.
267 std::shared_ptr<RandomVariable> get_random_variable(short ran_var_type);
268
269 //
270 //- Heading: Data members
271 //
272
273 /// draws real samples on [0,1]
274 boost::uniform_real<Real> uniformSampler;
275
276 /// pointer to the letter (initialized only for the envelope)
277 std::shared_ptr<RandomVariable> ranVarRep;
278 };
279
280
281 /*
282 template <typename T>
283 T RandomVariable::return_parameter(short dist_param) const
284 {
285 T val;
286 pull_parameter(dist_param, val);
287 return val;
288 }
289 */
290
291
292 template <typename Engine>
draw_sample(Engine & rng) const293 Real RandomVariable::draw_sample(Engine& rng) const
294 {
295 if (ranVarRep)
296 return ranVarRep->draw_sample(rng);
297 else {
298 // draw random number on [0,1] from a persistent RNG sequence
299 Real u01 = uniformSampler(rng);
300 return inverse_cdf(u01);
301 }
302 }
303
304
305 template <typename Engine>
draw_standard_sample(Engine & rng) const306 Real RandomVariable::draw_standard_sample(Engine& rng) const
307 {
308 if (ranVarRep)
309 return ranVarRep->draw_standard_sample(rng);
310 else {
311 // draw random number on [0,1] from a persistent RNG sequence
312 Real u01 = uniformSampler(rng);
313 return inverse_standard_cdf(u01);
314 }
315 }
316
317
type(short ran_var_type)318 inline void RandomVariable::type(short ran_var_type)
319 {
320 if (ranVarRep) ranVarRep->ranVarType = ran_var_type;
321 else ranVarType = ran_var_type;
322 }
323
324
type() const325 inline short RandomVariable::type() const
326 { return (ranVarRep) ? ranVarRep->ranVarType : ranVarType; }
327
328
329 inline std::shared_ptr<RandomVariable>
random_variable_rep() const330 RandomVariable::random_variable_rep() const
331 { return ranVarRep; }
332
333
is_null() const334 inline bool RandomVariable::is_null() const
335 { return (ranVarRep) ? false : true; }
336
337 } // namespace Pecos
338
339 #endif
340