ExRandom  3.0
unit_exponential_distribution.hpp
Go to the documentation of this file.
1 /**
2  * @file unit_exponential_distribution.hpp
3  * @author Charles Karney <charles.karney@sri.com>
4  * @brief Definition of unit_exponential_distribution
5  *
6  * Copyright (c) Charles Karney (2014) and licensed under the MIT/X11 License.
7  * For more information, see http://exrandom.sourceforge.net/
8  */
9 
10 #if !defined(EXRANDOM_UNIT_EXPONENTIAL_DISTRIBUTION_HPP)
11 #define EXRANDOM_UNIT_EXPONENTIAL_DISTRIBUTION_HPP 1
12 
13 #include <iostream> // for std::ostream, etc.
14 #include <limits>
15 
16 #include <exrandom/rand_digit.hpp>
18 
19 namespace exrandom {
20 
21  /**
22  * @brief Sample exactly from the unit exponential distribution.
23  *
24  * This samples from the unit exponential distribution P(x) = exp(&minus;x)
25  * for x &gt; 0. This is a replacement for std::exponential_distribution
26  * (with no parameters). It is equivalent to sampling a real number exactly
27  * from the distribution and rounding it to a floating point number. This
28  * implements Algorithm V.
29  *
30  * @tparam RealType the floating point type of the resulting deviates. This
31  * can include various multi-precision floating point types; see
32  * u_rand::value of details.
33  *
34  * This is a wrapper for unit_exponential_dist to turn it into a C++11 style
35  * random distribution. If the radix of RealType is 2 (the usual case), then
36  * the base for unit_exponential_dist is set to 2<sup>32</sup>; otherwise
37  * (e.g., RealType is a decimal system), the base is set to the radix.
38  */
39  template<typename RealType = double>
41  public:
42  /**
43  * The type of the range of the distribution.
44  */
45  typedef RealType result_type;
46  /**
47  * @brief Parameter type for unit_exponential_distribution.
48  *
49  * This holds no information because this distribution takes no parameters.
50  */
51  struct param_type {
52  /**
53  * The type of the random number distribution.
54  */
56  };
57 
58  /**
59  * Constructs an exponential distribution.
60  */
61  explicit
62  unit_exponential_distribution() : _exponential_dist(_D) {}
63 
64  /**
65  * Constructs an exponential distribution with a parameter.
66  *
67  * The parameter is ignored because it has no state.
68  */
69  explicit
71  : _exponential_dist(_D) {}
72 
73  /**
74  * Resets the distribution state.
75  */
76  void reset() {}
77 
78  /**
79  * @return the parameter set of the distribution.
80  */
81  param_type param() const { return param_type(); }
82 
83  /**
84  * Sets the parameter set of the distribution.
85  *
86  * The function does not because a param_type has no state.
87  */
88  void param(const param_type& /*param*/) {}
89 
90  /**
91  * @return the greatest lower bound value of the distribution.
92  */
93  result_type min() const { return result_type(0); }
94 
95  /**
96  * @return the least upper bound value of the distribution.
97  */
98  result_type max() const { return std::numeric_limits<result_type>::max(); }
99 
100  /**
101  * @tparam Generator the type of g.
102  * @param g the random generator engine.
103  * @return an exponential exponential deviate.
104  */
105  template<typename Generator>
107  operator()(Generator& g)
108  { return _exponential_dist.template value<result_type>(g); }
109 
110  /**
111  * @tparam Generator the type of g.
112  * @param g the random generator engine.
113  * @return an exponential exponential deviate.
114  */
115  template<typename Generator>
117  operator()(Generator& g, const param_type& /*p*/)
118  { return this->operator()(g); }
119 
120  /**
121  * Compare two unit_exponential_distributions.
122  * @return true.
123  */
124  friend bool
127  { return true; }
128 
129  /**
130  * Contrast two unit_exponential_distributions.
131  * @return false.
132  */
133  friend bool
136  { return false; }
137 
138  /**
139  * Inserts a unit_exponential_distribution random number distribution into the
140  * output stream @e os.
141  *
142  * @param os an output stream.
143  * @return os.
144  *
145  * This function does nothing because this distribution has no state.
146  */
147  friend std::ostream&
148  operator<<(std::ostream& os,
150  { return os; }
151 
152  /**
153  * Extracts a unit_exponential_distribution random number distribution from
154  * the input stream @e is.
155  *
156  * @param is an input stream.
157  * @return is.
158  *
159  * This function does nothing because this distribution has no state.
160  */
161  friend std::istream&
162  operator>>(std::istream& is, unit_exponential_distribution& /*x*/)
163  { return is; }
164 
165  private:
166  static_assert(!std::numeric_limits<RealType>::is_integer,
167  "template argument not a floating point type");
168  param_type _param;
169  static const uint_t _base = std::numeric_limits<RealType>::radix == 2 ?
170  0UL : std::numeric_limits<RealType>::radix;
172  // Setting bit_optimized ends up being slightly slower with base = 2^32
173  unit_exponential_dist<rand_digit<_base>, _base != 0UL> _exponential_dist;
174  };
175 
176 }
177 
178 #endif // EXRANDOM_UNIT_EXPONENTIAL_DISTRIBUTION_HPP
friend bool operator!=(const unit_exponential_distribution< RealType > &, const unit_exponential_distribution< RealType > &)
Parameter type for unit_exponential_distribution.
friend std::ostream & operator<<(std::ostream &os, const unit_exponential_distribution< RealType > &)
result_type operator()(Generator &g, const param_type &)
Definition of rand_digit.
unit_exponential_distribution< RealType > distribution_type
Sample u-rands exactly from the unit exponential distribution.
The common namespace.
Definition: aux_info.hpp:18
Definition of unit_exponential_dist.
Sample exactly from the unit exponential distribution.
friend std::istream & operator>>(std::istream &is, unit_exponential_distribution &)
friend bool operator==(const unit_exponential_distribution< RealType > &, const unit_exponential_distribution< RealType > &)