242 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			242 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /* boost random/uniform_real_distribution.hpp header file | ||
|  |  * | ||
|  |  * Copyright Jens Maurer 2000-2001 | ||
|  |  * Copyright Steven Watanabe 2011 | ||
|  |  * Distributed under the Boost Software License, Version 1.0. (See | ||
|  |  * accompanying file LICENSE_1_0.txt or copy at | ||
|  |  * http://www.boost.org/LICENSE_1_0.txt) | ||
|  |  * | ||
|  |  * See http://www.boost.org for most recent version including documentation. | ||
|  |  * | ||
|  |  * $Id$ | ||
|  |  * | ||
|  |  */ | ||
|  | 
 | ||
|  | #ifndef BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP | ||
|  | #define BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP | ||
|  | 
 | ||
|  | #include <iosfwd> | ||
|  | #include <ios> | ||
|  | #include <istream> | ||
|  | #include <boost/assert.hpp> | ||
|  | #include <boost/config.hpp> | ||
|  | #include <boost/random/detail/config.hpp> | ||
|  | #include <boost/random/detail/operators.hpp> | ||
|  | #include <boost/random/detail/signed_unsigned_tools.hpp> | ||
|  | #include <boost/type_traits/is_integral.hpp> | ||
|  | #include <boost/mpl/bool.hpp> | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | namespace random { | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | template<class Engine, class T> | ||
|  | T generate_uniform_real( | ||
|  |     Engine& eng, T min_value, T max_value, | ||
|  |     boost::mpl::false_  /** is_integral<Engine::result_type> */) | ||
|  | { | ||
|  |     for(;;) { | ||
|  |         typedef T result_type; | ||
|  |         result_type numerator = static_cast<T>(eng() - (eng.min)()); | ||
|  |         result_type divisor = static_cast<T>((eng.max)() - (eng.min)()); | ||
|  |         BOOST_ASSERT(divisor > 0); | ||
|  |         BOOST_ASSERT(numerator >= 0 && numerator <= divisor); | ||
|  |         T result = numerator / divisor * (max_value - min_value) + min_value; | ||
|  |         if(result < max_value) return result; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | template<class Engine, class T> | ||
|  | T generate_uniform_real( | ||
|  |     Engine& eng, T min_value, T max_value, | ||
|  |     boost::mpl::true_  /** is_integral<Engine::result_type> */) | ||
|  | { | ||
|  |     for(;;) { | ||
|  |         typedef T result_type; | ||
|  |         typedef typename Engine::result_type base_result; | ||
|  |         result_type numerator = static_cast<T>(subtract<base_result>()(eng(), (eng.min)())); | ||
|  |         result_type divisor = static_cast<T>(subtract<base_result>()((eng.max)(), (eng.min)())) + 1; | ||
|  |         BOOST_ASSERT(divisor > 0); | ||
|  |         BOOST_ASSERT(numerator >= 0 && numerator <= divisor); | ||
|  |         T result = numerator / divisor * (max_value - min_value) + min_value; | ||
|  |         if(result < max_value) return result; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | template<class Engine, class T> | ||
|  | inline T generate_uniform_real(Engine& eng, T min_value, T max_value) | ||
|  | { | ||
|  |     if(max_value / 2 - min_value / 2 > (std::numeric_limits<T>::max)() / 2) | ||
|  |         return 2 * generate_uniform_real(eng, T(min_value / 2), T(max_value / 2)); | ||
|  |     typedef typename Engine::result_type base_result; | ||
|  |     return generate_uniform_real(eng, min_value, max_value, | ||
|  |         boost::is_integral<base_result>()); | ||
|  | } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * The class template uniform_real_distribution models a \random_distribution. | ||
|  |  * On each invocation, it returns a random floating-point value uniformly | ||
|  |  * distributed in the range [min..max). | ||
|  |  */ | ||
|  | template<class RealType = double> | ||
|  | class uniform_real_distribution | ||
|  | { | ||
|  | public: | ||
|  |     typedef RealType input_type; | ||
|  |     typedef RealType result_type; | ||
|  | 
 | ||
|  |     class param_type | ||
|  |     { | ||
|  |     public: | ||
|  | 
 | ||
|  |         typedef uniform_real_distribution distribution_type; | ||
|  | 
 | ||
|  |         /** | ||
|  |          * Constructs the parameters of a uniform_real_distribution. | ||
|  |          * | ||
|  |          * Requires min <= max | ||
|  |          */ | ||
|  |         explicit param_type(RealType min_arg = RealType(0.0), | ||
|  |                             RealType max_arg = RealType(1.0)) | ||
|  |           : _min(min_arg), _max(max_arg) | ||
|  |         { | ||
|  |             BOOST_ASSERT(_min < _max); | ||
|  |         } | ||
|  | 
 | ||
|  |         /** Returns the minimum value of the distribution. */ | ||
|  |         RealType a() const { return _min; } | ||
|  |         /** Returns the maximum value of the distribution. */ | ||
|  |         RealType b() const { return _max; } | ||
|  | 
 | ||
|  |         /** Writes the parameters to a @c std::ostream. */ | ||
|  |         BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm) | ||
|  |         { | ||
|  |             os << parm._min << " " << parm._max; | ||
|  |             return os; | ||
|  |         } | ||
|  | 
 | ||
|  |         /** Reads the parameters from a @c std::istream. */ | ||
|  |         BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm) | ||
|  |         { | ||
|  |             RealType min_in, max_in; | ||
|  |             if(is >> min_in >> std::ws >> max_in) { | ||
|  |                 if(min_in <= max_in) { | ||
|  |                     parm._min = min_in; | ||
|  |                     parm._max = max_in; | ||
|  |                 } else { | ||
|  |                     is.setstate(std::ios_base::failbit); | ||
|  |                 } | ||
|  |             } | ||
|  |             return is; | ||
|  |         } | ||
|  | 
 | ||
|  |         /** Returns true if the two sets of parameters are equal. */ | ||
|  |         BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs) | ||
|  |         { return lhs._min == rhs._min && lhs._max == rhs._max; } | ||
|  | 
 | ||
|  |         /** Returns true if the two sets of parameters are different. */ | ||
|  |         BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type) | ||
|  | 
 | ||
|  |     private: | ||
|  | 
 | ||
|  |         RealType _min; | ||
|  |         RealType _max; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Constructs a uniform_real_distribution. @c min and @c max are | ||
|  |      * the parameters of the distribution. | ||
|  |      * | ||
|  |      * Requires: min <= max | ||
|  |      */ | ||
|  |     explicit uniform_real_distribution( | ||
|  |         RealType min_arg = RealType(0.0), | ||
|  |         RealType max_arg = RealType(1.0)) | ||
|  |       : _min(min_arg), _max(max_arg) | ||
|  |     { | ||
|  |         BOOST_ASSERT(min_arg < max_arg); | ||
|  |     } | ||
|  |     /** Constructs a uniform_real_distribution from its parameters. */ | ||
|  |     explicit uniform_real_distribution(const param_type& parm) | ||
|  |       : _min(parm.a()), _max(parm.b()) {} | ||
|  | 
 | ||
|  |     /**  Returns the minimum value of the distribution */ | ||
|  |     RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; } | ||
|  |     /**  Returns the maximum value of the distribution */ | ||
|  |     RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; } | ||
|  | 
 | ||
|  |     /**  Returns the minimum value of the distribution */ | ||
|  |     RealType a() const { return _min; } | ||
|  |     /**  Returns the maximum value of the distribution */ | ||
|  |     RealType b() const { return _max; } | ||
|  | 
 | ||
|  |     /** Returns the parameters of the distribution. */ | ||
|  |     param_type param() const { return param_type(_min, _max); } | ||
|  |     /** Sets the parameters of the distribution. */ | ||
|  |     void param(const param_type& parm) | ||
|  |     { | ||
|  |         _min = parm.a(); | ||
|  |         _max = parm.b(); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Effects: Subsequent uses of the distribution do not depend | ||
|  |      * on values produced by any engine prior to invoking reset. | ||
|  |      */ | ||
|  |     void reset() { } | ||
|  | 
 | ||
|  |     /** Returns a value uniformly distributed in the range [min, max). */ | ||
|  |     template<class Engine> | ||
|  |     result_type operator()(Engine& eng) const | ||
|  |     { return detail::generate_uniform_real(eng, _min, _max); } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns a value uniformly distributed in the range | ||
|  |      * [param.a(), param.b()). | ||
|  |      */ | ||
|  |     template<class Engine> | ||
|  |     result_type operator()(Engine& eng, const param_type& parm) const | ||
|  |     { return detail::generate_uniform_real(eng, parm.a(), parm.b()); } | ||
|  | 
 | ||
|  |     /** Writes the distribution to a @c std::ostream. */ | ||
|  |     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_real_distribution, ud) | ||
|  |     { | ||
|  |         os << ud.param(); | ||
|  |         return os; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** Reads the distribution from a @c std::istream. */ | ||
|  |     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_real_distribution, ud) | ||
|  |     { | ||
|  |         param_type parm; | ||
|  |         if(is >> parm) { | ||
|  |             ud.param(parm); | ||
|  |         } | ||
|  |         return is; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns true if the two distributions will produce identical sequences | ||
|  |      * of values given equal generators. | ||
|  |      */ | ||
|  |     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_real_distribution, lhs, rhs) | ||
|  |     { return lhs._min == rhs._min && lhs._max == rhs._max; } | ||
|  |      | ||
|  |     /** | ||
|  |      * Returns true if the two distributions may produce different sequences | ||
|  |      * of values given equal generators. | ||
|  |      */ | ||
|  |     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_real_distribution) | ||
|  | 
 | ||
|  | private: | ||
|  |     RealType _min; | ||
|  |     RealType _max; | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace random | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | #endif // BOOST_RANDOM_UNIFORM_INT_HPP |