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:	 SetVariable
10 //- Description: A random variable described by discrete values without
11 //-              associated probabilities
12 //- Owner:       Mike Eldred
13 //- Revised by:
14 //- Version:
15 
16 #ifndef SET_VARIABLE_HPP
17 #define SET_VARIABLE_HPP
18 
19 #include "RandomVariable.hpp"
20 
21 namespace Pecos {
22 
23 
24 /// Derived random variable class for discrete set random variables.
25 
26 /** Manages a set of discrete values without associated probability pairings
27     (refer to DiscreteSetRandomVariable for pairings) for types int, string,
28     and real.  String values are managed by index rather than value,
29     requiring template specializations. */
30 
31 template <typename T>
32 class SetVariable: public RandomVariable
33 {
34 public:
35 
36   //
37   //- Heading: Constructors and destructor
38   //
39 
40   /// default constructor
41   SetVariable();
42   /// alternate constructor
43   SetVariable(const std::set<T>& vals);
44   /// destructor
45   ~SetVariable();
46 
47   //
48   //- Heading: Virtual function redefinitions
49   //
50 
51   /*
52   Real mean() const;
53   //Real median() const;
54   Real mode() const;
55   Real standard_deviation() const;
56   Real variance() const;
57 
58   RealRealPair moments() const;
59   Real coefficient_of_variation() const;
60   */
61   RealRealPair distribution_bounds() const;
62 
63   void pull_parameter(short dist_param, std::set<T>& vals) const;
64   void push_parameter(short dist_param, const std::set<T>& vals);
65 
66   void copy_parameters(const RandomVariable& rv);
67 
68   //
69   //- Heading: Member functions
70   //
71 
72   void update(const std::set<T>& vals);
73 
74   //
75   //- Heading: Static member functions (global utilities)
76   //
77 
78   static void moments_from_params(const std::set<T>& vals,
79 				  Real& mean, Real& std_dev);
80 
81 protected:
82 
83   //
84   //- Heading: Data
85   //
86 
87   /// value-prob pairs for int values within a set
88   std::set<T> setValues;
89 };
90 
91 
92 //// GENERIC ////
93 
94 
95 template <typename T>
SetVariable()96 SetVariable<T>::SetVariable():
97   RandomVariable(BaseConstructor())
98 { }
99 
100 
101 template <typename T>
SetVariable(const std::set<T> & vals)102 SetVariable<T>::SetVariable(const std::set<T>& vals):
103   RandomVariable(BaseConstructor()), setValues(vals)
104 { }
105 
106 
107 template <typename T>
~SetVariable()108 SetVariable<T>::~SetVariable()
109 { }
110 
111 
112 template <typename T>
update(const std::set<T> & vals)113 void SetVariable<T>::update(const std::set<T>& vals)
114 { setValues = vals; }
115 // specializations could be used for assigning ranVarType, or could employ
116 // std::is_same for type identification.  Simplest: ranVarType assigned at
117 // bottom of RandomVariable::get_random_variable().
118 
119 
120 template <typename T>
pull_parameter(short dist_param,std::set<T> & vals) const121 void SetVariable<T>::pull_parameter(short dist_param, std::set<T>& vals) const
122 {
123   // could specialize template, but case aggregation seems adequate
124 
125   switch (dist_param) {
126   case DSI_VALUES: case DSS_VALUES: case DSR_VALUES:
127     vals = setValues; break;
128   default:
129     PCerr << "Error: update failure for distribution parameter " << dist_param
130 	  << " in SetVariable::pull_parameter(T)." << std::endl;
131     abort_handler(-1); break;
132   }
133 }
134 
135 
136 template <typename T>
push_parameter(short dist_param,const std::set<T> & vals)137 void SetVariable<T>::push_parameter(short dist_param, const std::set<T>& vals)
138 {
139   // could specialize template, but case aggregation seems adequate
140 
141   switch (dist_param) {
142   case DSI_VALUES: case DSS_VALUES: case DSR_VALUES:
143     setValues = vals; break;
144   default:
145     PCerr << "Error: update failure for distribution parameter " << dist_param
146 	  << " in SetVariable::push_parameter(T)." << std::endl;
147     abort_handler(-1); break;
148   }
149 }
150 
151 
152 template <typename T>
copy_parameters(const RandomVariable & rv)153 void SetVariable<T>::copy_parameters(const RandomVariable& rv)
154 {
155   switch (ranVarType) {
156   case DISCRETE_SET_INT:     rv.pull_parameter(DSI_VALUES, setValues);  break;
157   case DISCRETE_SET_STRING:  rv.pull_parameter(DSS_VALUES, setValues);  break;
158   case DISCRETE_SET_REAL:    rv.pull_parameter(DSR_VALUES, setValues);  break;
159   }
160 }
161 
162 
163 /*
164 template <typename T>
165 RealRealPair SetVariable<T>::moments() const
166 {
167   RealRealPair moms;
168   moments_from_params(setValues, moms.first, moms.second);
169   return moms;
170 }
171 
172 
173 template <typename T>
174 Real SetVariable<T>::mean() const
175 { return moments().first; }
176 
177 
178 //template <typename T>
179 //Real SetVariable<T>::median() const
180 //{ return inverse_cdf(.5); } // default
181 
182 
183 template <typename T>
184 Real SetVariable<T>::standard_deviation() const
185 { return moments().second; }
186 
187 
188 template <typename T>
189 Real SetVariable<T>::variance() const
190 { Real std_dev = moments().second; return std_dev * std_dev; }
191 
192 
193 template <typename T>
194 Real SetVariable<T>::coefficient_of_variation() const
195 { RealRealPair mom = moments(); return mom.second / mom.first; }
196 
197 
198 template <typename T>
199 Real SetVariable<T>::mode() const
200 {
201   Real mode, mode_prob;
202   typename std::set<T>::const_iterator cit = setValues.begin();
203   mode = (Real)cit->first;  mode_prob = cit->second;  ++cit;
204   for (; cit != setValues.end(); ++cit)
205     if (cit->second > mode_prob)
206       { mode = (Real)cit->first;  mode_prob = cit->second; }
207   return mode;
208 }
209 */
210 
211 
212 template <typename T>
distribution_bounds() const213 RealRealPair SetVariable<T>::distribution_bounds() const
214 {
215   // set values are sorted
216   T l_bnd = *setValues.begin(), u_bnd = *(--setValues.end());
217   return RealRealPair((Real)l_bnd, (Real)u_bnd);
218 }
219 
220 
221 /*
222 /// for T-valued histogram, return a real-valued mean and std dev
223 template <typename T>
224 void SetVariable<T>::
225 moments_from_params(const std::set<T>& vals, Real& mean, Real& std_dev)
226 {
227   // In point histogram case, (x,y) and (x,c) are equivalent since bins
228   // have zero-width.  Assume normalization (prob values sum to 1.).
229   mean = 0.;
230   Real val, prod, raw2 = 0.;
231   typename std::set<T>::const_iterator cit;
232   for (cit = vals.begin(); cit != vals.end(); ++cit) {
233     val   = (Real)cit->first;
234     prod  = cit->second * val; // prob * val
235     mean += prod;
236     raw2 += prod * val;        // prob * val^2
237   }
238   std_dev = std::sqrt(raw2 - mean * mean);
239 }
240 */
241 
242 
243 //// SPECIALIZATIONS ////
244 // for string vars, moments/bounds are based on weighting of set indices
245 
246 
247 /*
248 template <>
249 inline Real SetVariable<String>::mode() const
250 {
251   Real mode, mode_prob;
252   SRMCIter cit = setValues.begin();
253   mode = 0.;  mode_prob = cit->second;  ++cit;
254   for (size_t index=1; cit!=setValues.end(); ++cit, ++index)
255     if (cit->second > mode_prob)
256       { mode = (Real)index;  mode_prob = cit->second; }
257   return mode;
258 }
259 */
260 
261 
262 template <>
distribution_bounds() const263 inline RealRealPair SetVariable<String>::distribution_bounds() const
264 {
265   size_t last_index = setValues.size() - 1;
266   return RealRealPair(0., (Real)last_index);
267 }
268 
269 
270 /*
271 template <>
272 void SetVariable<String>::
273 inline moments_from_params(const StringRealMap& s_prs,
274                            Real& mean, Real& std_dev)
275 {
276   // in point case, (x,y) and (x,c) are equivalent since bins have zero-width.
277   // assume normalization (probs sum to 1.).
278   mean = 0.;
279   Real val, prod, raw2 = 0.;  size_t index = 0;  SRMCIter cit;
280   for (cit = s_prs.begin(); cit != s_prs.end(); ++cit, ++index) {
281     val   = (Real)index;
282     prod  = cit->second * val; // normalized prob * val
283     mean += prod;
284     raw2 += prod * val;        // normalized prob * val^2
285   }
286   std_dev = std::sqrt(raw2 - mean * mean);
287 }
288 */
289 
290 } // namespace Pecos
291 
292 #endif
293