Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /* boost random/uniform_01.hpp header file
0002  *
0003  * Copyright Jens Maurer 2000-2001
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  * Revision history
0013  *  2001-02-18  moved to individual header files
0014  */
0015 
0016 #ifndef BOOST_RANDOM_UNIFORM_01_HPP
0017 #define BOOST_RANDOM_UNIFORM_01_HPP
0018 
0019 #include <iostream>
0020 #include <boost/config.hpp>
0021 #include <boost/limits.hpp>
0022 #include <boost/static_assert.hpp>
0023 #include <boost/random/detail/config.hpp>
0024 #include <boost/random/detail/ptr_helper.hpp>
0025 
0026 #include <boost/random/detail/disable_warnings.hpp>
0027 
0028 namespace boost {
0029 namespace random {
0030 
0031 #ifdef BOOST_RANDOM_DOXYGEN
0032 
0033 /**
0034  * The distribution function uniform_01 models a \random_distribution.
0035  * On each invocation, it returns a random floating-point value
0036  * uniformly distributed in the range [0..1).
0037  *
0038  * The template parameter RealType shall denote a float-like value type
0039  * with support for binary operators +, -, and /.
0040  *
0041  * Note: The current implementation is buggy, because it may not fill
0042  * all of the mantissa with random bits. I'm unsure how to fill a
0043  * (to-be-invented) @c boost::bigfloat class with random bits efficiently.
0044  * It's probably time for a traits class.
0045  */
0046 template<class RealType = double>
0047 class uniform_01
0048 {
0049 public:
0050   typedef RealType input_type;
0051   typedef RealType result_type;
0052   result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const;
0053   result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const;
0054   void reset();
0055 
0056   template<class Engine>
0057   result_type operator()(Engine& eng);
0058 
0059 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
0060   template<class CharT, class Traits>
0061   friend std::basic_ostream<CharT,Traits>&
0062   operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
0063   {
0064     return os;
0065   }
0066 
0067   template<class CharT, class Traits>
0068   friend std::basic_istream<CharT,Traits>&
0069   operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
0070   {
0071     return is;
0072   }
0073 #endif
0074 };
0075 
0076 #else
0077 
0078 namespace detail {
0079 
0080 template<class RealType>
0081 class new_uniform_01
0082 {
0083 public:
0084   typedef RealType input_type;
0085   typedef RealType result_type;
0086   // compiler-generated copy ctor and copy assignment are fine
0087   result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
0088   result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
0089   void reset() { }
0090 
0091   template<class Engine>
0092   result_type operator()(Engine& eng) {
0093     for (;;) {
0094       typedef typename Engine::result_type base_result;
0095       result_type factor = result_type(1) /
0096               (result_type(base_result((eng.max)()-(eng.min)())) +
0097                result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0));
0098       result_type result = result_type(base_result(eng() - (eng.min)())) * factor;
0099       if (result < result_type(1))
0100         return result;
0101     }
0102   }
0103 
0104 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
0105   template<class CharT, class Traits>
0106   friend std::basic_ostream<CharT,Traits>&
0107   operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
0108   {
0109     return os;
0110   }
0111 
0112   template<class CharT, class Traits>
0113   friend std::basic_istream<CharT,Traits>&
0114   operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
0115   {
0116     return is;
0117   }
0118 #endif
0119 };
0120 
0121 template<class UniformRandomNumberGenerator, class RealType>
0122 class backward_compatible_uniform_01
0123 {
0124   typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
0125 public:
0126   typedef UniformRandomNumberGenerator base_type;
0127   typedef RealType result_type;
0128 
0129   BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
0130 
0131 #if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
0132   BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
0133 #endif
0134 
0135   explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)
0136     : _rng(rng),
0137       _factor(result_type(1) /
0138               (result_type((base().max)()-(base().min)()) +
0139                result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
0140   {
0141   }
0142   // compiler-generated copy ctor and copy assignment are fine
0143 
0144   result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
0145   result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
0146   typename traits::value_type& base() { return traits::ref(_rng); }
0147   const typename traits::value_type& base() const { return traits::ref(_rng); }
0148   void reset() { }
0149 
0150   result_type operator()() {
0151     for (;;) {
0152       result_type result = result_type(base()() - (base().min)()) * _factor;
0153       if (result < result_type(1))
0154         return result;
0155     }
0156   }
0157 
0158 #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
0159   template<class CharT, class Traits>
0160   friend std::basic_ostream<CharT,Traits>&
0161   operator<<(std::basic_ostream<CharT,Traits>& os, const backward_compatible_uniform_01& u)
0162   {
0163     os << u._rng;
0164     return os;
0165   }
0166 
0167   template<class CharT, class Traits>
0168   friend std::basic_istream<CharT,Traits>&
0169   operator>>(std::basic_istream<CharT,Traits>& is, backward_compatible_uniform_01& u)
0170   {
0171     is >> u._rng;
0172     return is;
0173   }
0174 #endif
0175 
0176 private:
0177   typedef typename traits::value_type::result_type base_result;
0178   UniformRandomNumberGenerator _rng;
0179   result_type _factor;
0180 };
0181 
0182 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
0183 //  A definition is required even for integral static constants
0184 template<class UniformRandomNumberGenerator, class RealType>
0185 const bool backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;
0186 #endif
0187 
0188 template<class UniformRandomNumberGenerator, bool is_number = std::numeric_limits<UniformRandomNumberGenerator>::is_specialized>
0189 struct select_uniform_01
0190 {
0191   template<class RealType>
0192   struct apply
0193   {
0194     typedef backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType> type;
0195   };
0196 };
0197 
0198 template<class Num>
0199 struct select_uniform_01<Num, true>
0200 {
0201   template<class RealType>
0202   struct apply
0203   {
0204     typedef new_uniform_01<Num> type;
0205   };
0206 };
0207 
0208 }
0209 
0210 // Because it is so commonly used: uniform distribution on the real [0..1)
0211 // range.  This allows for specializations to avoid a costly int -> float
0212 // conversion plus float multiplication
0213 template<class UniformRandomNumberGenerator = double, class RealType = double>
0214 class uniform_01
0215   : public detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type
0216 {
0217   typedef typename detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type impl_type;
0218   typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
0219 public:
0220 
0221   uniform_01() {}
0222 
0223   explicit uniform_01(typename traits::rvalue_type rng)
0224     : impl_type(rng)
0225   {
0226   }
0227 
0228 #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
0229   template<class CharT, class Traits>
0230   friend std::basic_ostream<CharT,Traits>&
0231   operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)
0232   {
0233     os << static_cast<const impl_type&>(u);
0234     return os;
0235   }
0236 
0237   template<class CharT, class Traits>
0238   friend std::basic_istream<CharT,Traits>&
0239   operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)
0240   {
0241     is >> static_cast<impl_type&>(u);
0242     return is;
0243   }
0244 #endif
0245 };
0246 
0247 #endif
0248 
0249 } // namespace random
0250 
0251 using random::uniform_01;
0252 
0253 } // namespace boost
0254 
0255 #include <boost/random/detail/enable_warnings.hpp>
0256 
0257 #endif // BOOST_RANDOM_UNIFORM_01_HPP