OpenMPCD
Gamma_shape_ge_1.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the `OpenMPCD::CUDA::Random::Distributions::Gamma_shape_ge_1` class.
4  */
5 
6 #ifndef OPENMPCD_CUDA_RANDOM_DISTRIBUTIONS_GAMMA_SHAPE_GE_1_HPP
7 #define OPENMPCD_CUDA_RANDOM_DISTRIBUTIONS_GAMMA_SHAPE_GE_1_HPP
8 
12 #include <OpenMPCD/Exceptions.hpp>
14 
15 #include <boost/static_assert.hpp>
16 #include <boost/type_traits/is_floating_point.hpp>
17 
18 
19 namespace OpenMPCD
20 {
21 namespace CUDA
22 {
23 namespace Random
24 {
25 namespace Distributions
26 {
27 
28 /**
29  * The gamma distribution, with shape parameter \f$ k \f$ assumed to satisfy
30  * \f$ k \ge 1 \f$.
31  *
32  * This is the distribution which has the probability density function
33  * \f[
34  * f \left(x ; k, \theta \right)
35  * =
36  * \frac
37  * {
38  * x^{k-1}
39  * \exp \left( - \frac{ x }{ \theta } \right)
40  * }
41  * {
42  * \Gamma \left( k \right)
43  * \theta^k
44  * }
45  * \f]
46  * where the parameters \f$ k \ge 1 \f$ and \f$ \theta \f$ are called `shape`
47  * and `scale`, respectively, and \f$ \Gamma \f$ is the gamma function.
48  *
49  * For further information, see e.g. @cite Devroye1986, chapter IX.3.
50  *
51  * @tparam T The underlying data type, which must be a floating-point type.
52  */
53 template<typename T>
55 {
56 public:
57  /**
58  * The constructor.
59  *
60  * @throw OpenMPCD::InvalidArgumentError
61  * If `OPENMPCD_DEBUG` is defined, throws if `shape < 1` or
62  * `scale < 0`.
63  *
64  * @param[in] shape The shape parameter \f$ k \ge 1 \f$.
65  * @param[in] scale The scale parameter \f$ \theta > 0 \f$.
66  */
68  Gamma_shape_ge_1(const T shape, const T scale)
69  : k(shape), theta(scale),
70  d(k - T(1.0)/3), c(1 / sqrt(9 * d))
71  {
72  BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value);
73 
76 
77  OPENMPCD_DEBUG_ASSERT(d == shape - T(1.0) / 3);
78  OPENMPCD_DEBUG_ASSERT(c == 1 / sqrt(9 * d));
79  }
80 
81 public:
82  /**
83  * Generates a random value sampled from the distribution.
84  *
85  * This function implements the algorithm in @cite Marsaglia2000, and
86  * additionally making use of the scaling property of the gamma
87  * distribution, i.e. the fact that if \f$ X \f$ is gamma-distributed with
88  * shape \f$ k \f$ and scale \f$ \theta \f$, then \f$ cX \f$ is
89  * gamma-distributed with shape \f$ k \f$ and scale \f$ c \theta \f$, given
90  * that \f$ c > 0 \f$ (see @cite Devroye1986, chapter IX.3).
91  *
92  * @tparam RNG The random number generator type.
93  *
94  * @param[in] rng The random number generator instance.
95  */
96  template<typename RNG>
98  T operator()(RNG& rng) const
99  {
100  Distributions::Uniform0e1e<T> uniform0e1e;
101  Distributions::StandardNormal<T> standardNormal;
102 
103  for(;;)
104  {
105  T x;
106  T v;
107  do
108  {
109  x = standardNormal(rng);
110  v = 1 + c * x;
111  }
112  while(v <= 0);
113 
114  v = v * v * v;
115 
116  const T u = uniform0e1e(rng);
117 
118  if(u < 1 - 0.0331 * x * x * x * x)
119  return theta * d * v;
120 
121  const T criterion = 0.5 * x * x + d * ( 1 - v + log(v) );
122  if(log(u) < criterion)
123  return theta * d * v;
124  }
125  }
126 
127 private:
128  const T k; ///< The shape parameter.
129  const T theta; ///< The scale parameter.
130 
131  const T d; ///< Precomputed parameter for the implementation.
132  const T c; ///< Precomputed parameter for the implementation.
133 }; //class Gamma_shape_ge_1
134 
135 } //namespace Distributions
136 } //namespace Random
137 } //namespace CUDA
138 } //namespace OpenMPCD
139 
140 
141 #endif //OPENMPCD_CUDA_RANDOM_DISTRIBUTIONS_GAMMA_SHAPE_GE_1_HPP
OpenMPCD::CUDA::Random::Distributions::Gamma_shape_ge_1::Gamma_shape_ge_1
OPENMPCD_CUDA_DEVICE Gamma_shape_ge_1(const T shape, const T scale)
The constructor.
Definition: Gamma_shape_ge_1.hpp:68
OpenMPCD::CUDA::Random::Distributions::StandardNormal
The standard normal distribution.
Definition: StandardNormal.hpp:29
Exceptions.hpp
StandardNormal.hpp
OPENMPCD_DEBUG_ASSERT
#define OPENMPCD_DEBUG_ASSERT(assertion)
Asserts that the given expression evaluates to true, but only if OPENMPCD_DEBUG is defined.
Definition: OPENMPCD_DEBUG_ASSERT.hpp:88
Uniform0e1e.hpp
OpenMPCD::CUDA::Random::Distributions::Uniform0e1e
The uniform distribution in the open interval .
Definition: Uniform0e1e.hpp:30
OPENMPCD_CUDA_DEVICE
#define OPENMPCD_CUDA_DEVICE
Denotes a function to be callable from a CUDA Device.
Definition: Macros.hpp:25
OpenMPCD::CUDA::Random::Distributions::Gamma_shape_ge_1::operator()
OPENMPCD_CUDA_DEVICE T operator()(RNG &rng) const
Generates a random value sampled from the distribution.
Definition: Gamma_shape_ge_1.hpp:98
OpenMPCD::RNG
boost::mt11213b RNG
The random number generator type.
Definition: Types.hpp:18
OPENMPCD_DEBUG_ASSERT.hpp
OPENMPCD_DEBUG_ASSERT_EXCEPTIONTYPE
#define OPENMPCD_DEBUG_ASSERT_EXCEPTIONTYPE(assertion, ExceptionType)
Definition: OPENMPCD_DEBUG_ASSERT.hpp:76
Macros.hpp
OpenMPCD::Utility::MathematicalFunctions::sqrt
OPENMPCD_CUDA_HOST_AND_DEVICE T sqrt(const T x)
Returns the sqaure root of the argument.
OpenMPCD::CUDA::Random::Distributions::Gamma_shape_ge_1
The gamma distribution, with shape parameter assumed to satisfy .
Definition: Gamma_shape_ge_1.hpp:54
OpenMPCD::InvalidArgumentException
Invalid argument exception.
Definition: Exceptions.hpp:128