Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/random/inverse_gaussian_distribution.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* boost random/inverse_gaussian_distribution.hpp header file
0002  *
0003  * Copyright Young Geun Kim 2025
0004  * Distributed under the Boost Software License, Version 1.0. (See
0005  * accompanying file LICENSE_1_0.txt or copy at
0006  * http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  * See http://www.boost.org for most recent version including documentation.
0009  *
0010  * $Id$
0011  */
0012 
0013 #ifndef BOOST_RANDOM_INVERSE_GAUSSIAN_DISTRIBUTION_HPP
0014 #define BOOST_RANDOM_INVERSE_GAUSSIAN_DISTRIBUTION_HPP
0015 
0016 #include <boost/config/no_tr1/cmath.hpp>
0017 #include <istream>
0018 #include <iosfwd>
0019 #include <limits>
0020 #include <boost/assert.hpp>
0021 #include <boost/limits.hpp>
0022 #include <boost/random/detail/config.hpp>
0023 #include <boost/random/detail/operators.hpp>
0024 #include <boost/random/uniform_01.hpp>
0025 #include <boost/random/chi_squared_distribution.hpp>
0026 
0027 namespace boost {
0028 namespace random {
0029 
0030 /**
0031  * The inverse gaussian distribution is a real-valued distribution with
0032  * two parameters alpha (mean) and beta (shape). It produced values > 0.
0033  *
0034  * It has
0035  * \f$\displaystyle p(x) = \sqrt{\beta / (2 \pi x^3)} \exp(-\frac{\beta (x - \alpha)^2}{2 \alpha^2 x})$.
0036  *
0037  * The algorithm used is from
0038  *
0039  * @blockquote
0040  * "Generating Random Variates Using Transformations with Multiple Roots",
0041  * Michael, J. R., Schucany, W. R. and Haas, R. W.,
0042  * The American Statistician,
0043  * Volume 30, Issue 2, 1976, Pages 88 - 90
0044  * @endblockquote
0045  */
0046 template<class RealType = double>
0047 class inverse_gaussian_distribution
0048 {
0049 public:
0050     typedef RealType result_type;
0051     typedef RealType input_type;
0052 
0053     class param_type {
0054     public:
0055         typedef inverse_gaussian_distribution distribution_type;
0056 
0057         /**
0058          * Constructs a @c param_type object from the "alpha" and "beta"
0059          * parameters.
0060          *
0061          * Requires: alpha > 0 && beta > 0
0062          */
0063         explicit param_type(RealType alpha_arg = RealType(1.0),
0064                                              RealType beta_arg = RealType(1.0))
0065             : _alpha(alpha_arg), _beta(beta_arg)
0066         {
0067             BOOST_ASSERT(alpha_arg > 0);
0068             BOOST_ASSERT(beta_arg > 0);
0069         }
0070 
0071         /** Returns the "alpha" parameter of the distribution. */
0072         RealType alpha() const { return _alpha; }
0073         /** Returns the "beta" parameter of the distribution. */
0074         RealType beta() const { return _beta; }
0075 
0076         /** Writes a @c param_type to a @c std::ostream. */
0077         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
0078         { os << parm._alpha << ' ' << parm._beta; return os; }
0079 
0080         /** Reads a @c param_type from a @c std::istream. */
0081         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
0082         { is >> parm._alpha >> std::ws >> parm._beta; return is; }
0083 
0084         /** Returns true if the two sets of parameters are the same. */
0085         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
0086         { return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta; }
0087 
0088         /** Returns true if the two sets fo parameters are different. */
0089         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
0090 
0091         private:
0092             RealType _alpha;
0093             RealType _beta;
0094     };
0095 
0096 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0097     BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
0098 #endif
0099 
0100     /**
0101      * Constructs an @c inverse_gaussian_distribution from its "alpha" and "beta" parameters.
0102      *
0103      * Requires: alpha > 0, beta > 0
0104      */
0105     explicit inverse_gaussian_distribution(RealType alpha_arg = RealType(1.0),
0106                                                                                  RealType beta_arg = RealType(1.0))
0107         : _alpha(alpha_arg), _beta(beta_arg)
0108     {
0109         BOOST_ASSERT(alpha_arg > 0);
0110         BOOST_ASSERT(beta_arg > 0);
0111         init();
0112     }
0113 
0114     /** Constructs an @c inverse_gaussian_distribution from its parameters. */
0115     explicit inverse_gaussian_distribution(const param_type& parm)
0116         : _alpha(parm.alpha()), _beta(parm.beta())
0117     {
0118         init();
0119     }
0120 
0121     /**
0122      * Returns a random variate distributed according to the
0123      * inverse gaussian distribution.
0124      */
0125     template<class URNG>
0126     RealType operator()(URNG& urng) const
0127     {
0128 #ifndef BOOST_NO_STDC_NAMESPACE
0129         using std::sqrt;
0130 #endif
0131         RealType w = _alpha * chi_squared_distribution<RealType>(result_type(1))(urng);
0132         RealType cand = _alpha + _c * (w - sqrt(w * (result_type(4) * _beta + w)));
0133         RealType u = uniform_01<RealType>()(urng);
0134         if (u < _alpha / (_alpha + cand)) {
0135             return cand;
0136         }
0137     return _alpha * _alpha / cand;
0138     }
0139 
0140     /**
0141      * Returns a random variate distributed accordint to the beta
0142      * distribution with parameters specified by @c param.
0143      */
0144     template<class URNG>
0145     RealType operator()(URNG& urng, const param_type& parm) const
0146     {
0147         return inverse_gaussian_distribution(parm)(urng);
0148     }
0149 
0150     /** Returns the "alpha" parameter of the distribution. */
0151     RealType alpha() const { return _alpha; }
0152     /** Returns the "beta" parameter of the distribution. */
0153     RealType beta() const { return _beta; }
0154 
0155     /** Returns the smallest value that the distribution can produce. */
0156     RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
0157     { return RealType(0.0); }
0158     /** Returns the largest value that the distribution can produce. */
0159     RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
0160     { return (std::numeric_limits<RealType>::infinity)(); }
0161 
0162     /** Returns the parameters of the distribution. */
0163     param_type param() const { return param_type(_alpha, _beta); }
0164     /** Sets the parameters of the distribution. */
0165     void param(const param_type& parm)
0166     {
0167         _alpha = parm.alpha();
0168         _beta = parm.beta();
0169         init();
0170     }
0171 
0172     /**
0173      * Effects: Subsequent uses of the distribution do not depend
0174      * on values produced by any engine prior to invoking reset.
0175      */
0176     void reset() { }
0177 
0178     /** Writes an @c inverse_gaussian_distribution to a @c std::ostream. */
0179     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, inverse_gaussian_distribution, wd)
0180     {
0181         os << wd.param();
0182         return os;
0183     }
0184 
0185     /** Reads an @c inverse_gaussian_distribution from a @c std::istream. */
0186     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, inverse_gaussian_distribution, wd)
0187     {
0188         param_type parm;
0189         if(is >> parm) {
0190             wd.param(parm);
0191         }
0192         return is;
0193     }
0194 
0195     /**
0196      * Returns true if the two instances of @c inverse_gaussian_distribution will
0197      * return identical sequences of values given equal generators.
0198      */
0199     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(inverse_gaussian_distribution, lhs, rhs)
0200     { return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta; }
0201 
0202     /**
0203      * Returns true if the two instances of @c inverse_gaussian_distribution will
0204      * return different sequences of values given equal generators.
0205      */
0206     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(inverse_gaussian_distribution)
0207 
0208 private:
0209     result_type _alpha;
0210     result_type _beta;
0211     // some data precomputed from the parameters
0212     result_type _c;
0213 
0214     void init()
0215     {
0216         _c = _alpha / (result_type(2) * _beta);
0217     }
0218 };
0219 
0220 } // namespace random
0221 
0222 using random::inverse_gaussian_distribution;
0223 
0224 } // namespace boost
0225 
0226 #endif // BOOST_RANDOM_INVERSE_GAUSSIAN_DISTRIBUTION_HPP