Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:13

0001 /* boost random/uniform_real_distribution.hpp header file
0002  *
0003  * Copyright Jens Maurer 2000-2001
0004  * Copyright Steven Watanabe 2011
0005  * Distributed under the Boost Software License, Version 1.0. (See
0006  * accompanying file LICENSE_1_0.txt or copy at
0007  * http://www.boost.org/LICENSE_1_0.txt)
0008  *
0009  * See http://www.boost.org for most recent version including documentation.
0010  *
0011  * $Id$
0012  *
0013  */
0014 
0015 #ifndef BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
0016 #define BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
0017 
0018 #include <iosfwd>
0019 #include <ios>
0020 #include <istream>
0021 #include <boost/assert.hpp>
0022 #include <boost/config.hpp>
0023 #include <boost/random/detail/config.hpp>
0024 #include <boost/random/detail/operators.hpp>
0025 #include <boost/random/detail/signed_unsigned_tools.hpp>
0026 #include <boost/type_traits/is_integral.hpp>
0027 
0028 namespace boost {
0029 namespace random {
0030 namespace detail {
0031 
0032 template<class Engine, class T>
0033 T generate_uniform_real(
0034     Engine& eng, T min_value, T max_value,
0035     boost::false_type  /** is_integral<Engine::result_type> */)
0036 {
0037     for(;;) {
0038         typedef T result_type;
0039         result_type numerator = static_cast<T>(eng() - (eng.min)());
0040         result_type divisor = static_cast<T>((eng.max)() - (eng.min)());
0041         BOOST_ASSERT(divisor > 0);
0042         BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
0043         T result = numerator / divisor * (max_value - min_value) + min_value;
0044         if(result < max_value) return result;
0045     }
0046 }
0047 
0048 template<class Engine, class T>
0049 T generate_uniform_real(
0050     Engine& eng, T min_value, T max_value,
0051     boost::true_type  /** is_integral<Engine::result_type> */)
0052 {
0053     for(;;) {
0054         typedef T result_type;
0055         typedef typename Engine::result_type base_result;
0056         result_type numerator = static_cast<T>(subtract<base_result>()(eng(), (eng.min)()));
0057         result_type divisor = static_cast<T>(subtract<base_result>()((eng.max)(), (eng.min)())) + 1;
0058         BOOST_ASSERT(divisor > 0);
0059         BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
0060         T result = numerator / divisor * (max_value - min_value) + min_value;
0061         if(result < max_value) return result;
0062     }
0063 }
0064 
0065 template<class Engine, class T>
0066 inline T generate_uniform_real(Engine& eng, T min_value, T max_value)
0067 {
0068     if(max_value / 2 - min_value / 2 > (std::numeric_limits<T>::max)() / 2)
0069         return 2 * generate_uniform_real(eng, T(min_value / 2), T(max_value / 2));
0070     typedef typename Engine::result_type base_result;
0071     return generate_uniform_real(eng, min_value, max_value,
0072         boost::is_integral<base_result>());
0073 }
0074 
0075 }
0076 
0077 /**
0078  * The class template uniform_real_distribution models a \random_distribution.
0079  * On each invocation, it returns a random floating-point value uniformly
0080  * distributed in the range [min..max).
0081  */
0082 template<class RealType = double>
0083 class uniform_real_distribution
0084 {
0085 public:
0086     typedef RealType input_type;
0087     typedef RealType result_type;
0088 
0089     class param_type
0090     {
0091     public:
0092 
0093         typedef uniform_real_distribution distribution_type;
0094 
0095         /**
0096          * Constructs the parameters of a uniform_real_distribution.
0097          *
0098          * Requires min < max
0099          */
0100         explicit param_type(RealType min_arg = RealType(0.0),
0101                             RealType max_arg = RealType(1.0))
0102           : _min(min_arg), _max(max_arg)
0103         {
0104             BOOST_ASSERT(_min < _max);
0105         }
0106 
0107         /** Returns the minimum value of the distribution. */
0108         RealType a() const { return _min; }
0109         /** Returns the maximum value of the distribution. */
0110         RealType b() const { return _max; }
0111 
0112         /** Writes the parameters to a @c std::ostream. */
0113         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
0114         {
0115             os << parm._min << " " << parm._max;
0116             return os;
0117         }
0118 
0119         /** Reads the parameters from a @c std::istream. */
0120         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
0121         {
0122             RealType min_in, max_in;
0123             if(is >> min_in >> std::ws >> max_in) {
0124                 if(min_in <= max_in) {
0125                     parm._min = min_in;
0126                     parm._max = max_in;
0127                 } else {
0128                     is.setstate(std::ios_base::failbit);
0129                 }
0130             }
0131             return is;
0132         }
0133 
0134         /** Returns true if the two sets of parameters are equal. */
0135         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
0136         { return lhs._min == rhs._min && lhs._max == rhs._max; }
0137 
0138         /** Returns true if the two sets of parameters are different. */
0139         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
0140 
0141     private:
0142 
0143         RealType _min;
0144         RealType _max;
0145     };
0146 
0147     /**
0148      * Constructs a uniform_real_distribution. @c min and @c max are
0149      * the parameters of the distribution.
0150      *
0151      * Requires: min < max
0152      */
0153     explicit uniform_real_distribution(
0154         RealType min_arg = RealType(0.0),
0155         RealType max_arg = RealType(1.0))
0156       : _min(min_arg), _max(max_arg)
0157     {
0158         BOOST_ASSERT(min_arg < max_arg);
0159     }
0160     /** Constructs a uniform_real_distribution from its parameters. */
0161     explicit uniform_real_distribution(const param_type& parm)
0162       : _min(parm.a()), _max(parm.b()) {}
0163 
0164     /**  Returns the minimum value of the distribution */
0165     RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
0166     /**  Returns the maximum value of the distribution */
0167     RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
0168 
0169     /**  Returns the minimum value of the distribution */
0170     RealType a() const { return _min; }
0171     /**  Returns the maximum value of the distribution */
0172     RealType b() const { return _max; }
0173 
0174     /** Returns the parameters of the distribution. */
0175     param_type param() const { return param_type(_min, _max); }
0176     /** Sets the parameters of the distribution. */
0177     void param(const param_type& parm)
0178     {
0179         _min = parm.a();
0180         _max = parm.b();
0181     }
0182 
0183     /**
0184      * Effects: Subsequent uses of the distribution do not depend
0185      * on values produced by any engine prior to invoking reset.
0186      */
0187     void reset() { }
0188 
0189     /** Returns a value uniformly distributed in the range [min, max). */
0190     template<class Engine>
0191     result_type operator()(Engine& eng) const
0192     { return detail::generate_uniform_real(eng, _min, _max); }
0193 
0194     /**
0195      * Returns a value uniformly distributed in the range
0196      * [param.a(), param.b()).
0197      */
0198     template<class Engine>
0199     result_type operator()(Engine& eng, const param_type& parm) const
0200     { return detail::generate_uniform_real(eng, parm.a(), parm.b()); }
0201 
0202     /** Writes the distribution to a @c std::ostream. */
0203     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_real_distribution, ud)
0204     {
0205         os << ud.param();
0206         return os;
0207     }
0208 
0209     /** Reads the distribution from a @c std::istream. */
0210     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_real_distribution, ud)
0211     {
0212         param_type parm;
0213         if(is >> parm) {
0214             ud.param(parm);
0215         }
0216         return is;
0217     }
0218 
0219     /**
0220      * Returns true if the two distributions will produce identical sequences
0221      * of values given equal generators.
0222      */
0223     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_real_distribution, lhs, rhs)
0224     { return lhs._min == rhs._min && lhs._max == rhs._max; }
0225     
0226     /**
0227      * Returns true if the two distributions may produce different sequences
0228      * of values given equal generators.
0229      */
0230     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_real_distribution)
0231 
0232 private:
0233     RealType _min;
0234     RealType _max;
0235 };
0236 
0237 } // namespace random
0238 } // namespace boost
0239 
0240 #endif // BOOST_RANDOM_UNIFORM_INT_HPP