| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 | /* boost random/uniform_01.hpp header file * * Copyright Jens Maurer 2000-2001 * 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$ * * Revision history *  2001-02-18  moved to individual header files */#ifndef BOOST_RANDOM_UNIFORM_01_HPP#define BOOST_RANDOM_UNIFORM_01_HPP#include <iostream>#include <boost/config.hpp>#include <boost/limits.hpp>#include <boost/static_assert.hpp>#include <boost/random/detail/config.hpp>#include <boost/random/detail/ptr_helper.hpp>#include <boost/random/detail/disable_warnings.hpp>namespace boost {namespace random {#ifdef BOOST_RANDOM_DOXYGEN/** * The distribution function uniform_01 models a \random_distribution. * On each invocation, it returns a random floating-point value * uniformly distributed in the range [0..1). * * The template parameter RealType shall denote a float-like value type * with support for binary operators +, -, and /. * * Note: The current implementation is buggy, because it may not fill * all of the mantissa with random bits. I'm unsure how to fill a * (to-be-invented) @c boost::bigfloat class with random bits efficiently. * It's probably time for a traits class. */template<class RealType = double>class uniform_01{public:  typedef RealType input_type;  typedef RealType result_type;  result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const;  result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const;  void reset();  template<class Engine>  result_type operator()(Engine& eng);#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS  template<class CharT, class Traits>  friend std::basic_ostream<CharT,Traits>&  operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)  {    return os;  }  template<class CharT, class Traits>  friend std::basic_istream<CharT,Traits>&  operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)  {    return is;  }#endif};#elsenamespace detail {template<class RealType>class new_uniform_01{public:  typedef RealType input_type;  typedef RealType result_type;  // compiler-generated copy ctor and copy assignment are fine  result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }  result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }  void reset() { }  template<class Engine>  result_type operator()(Engine& eng) {    for (;;) {      typedef typename Engine::result_type base_result;      result_type factor = result_type(1) /              (result_type(base_result((eng.max)()-(eng.min)())) +               result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0));      result_type result = result_type(base_result(eng() - (eng.min)())) * factor;      if (result < result_type(1))        return result;    }  }#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS  template<class CharT, class Traits>  friend std::basic_ostream<CharT,Traits>&  operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)  {    return os;  }  template<class CharT, class Traits>  friend std::basic_istream<CharT,Traits>&  operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)  {    return is;  }#endif};template<class UniformRandomNumberGenerator, class RealType>class backward_compatible_uniform_01{  typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;public:  typedef UniformRandomNumberGenerator base_type;  typedef RealType result_type;  BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)  BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);#endif  explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)    : _rng(rng),      _factor(result_type(1) /              (result_type((base().max)()-(base().min)()) +               result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))  {  }  // compiler-generated copy ctor and copy assignment are fine  result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }  result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }  typename traits::value_type& base() { return traits::ref(_rng); }  const typename traits::value_type& base() const { return traits::ref(_rng); }  void reset() { }  result_type operator()() {    for (;;) {      result_type result = result_type(base()() - (base().min)()) * _factor;      if (result < result_type(1))        return result;    }  }#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)  template<class CharT, class Traits>  friend std::basic_ostream<CharT,Traits>&  operator<<(std::basic_ostream<CharT,Traits>& os, const backward_compatible_uniform_01& u)  {    os << u._rng;    return os;  }  template<class CharT, class Traits>  friend std::basic_istream<CharT,Traits>&  operator>>(std::basic_istream<CharT,Traits>& is, backward_compatible_uniform_01& u)  {    is >> u._rng;    return is;  }#endifprivate:  typedef typename traits::value_type::result_type base_result;  UniformRandomNumberGenerator _rng;  result_type _factor;};#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION//  A definition is required even for integral static constantstemplate<class UniformRandomNumberGenerator, class RealType>const bool backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;#endiftemplate<class UniformRandomNumberGenerator, bool is_number = std::numeric_limits<UniformRandomNumberGenerator>::is_specialized>struct select_uniform_01{  template<class RealType>  struct apply  {    typedef backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType> type;  };};template<class Num>struct select_uniform_01<Num, true>{  template<class RealType>  struct apply  {    typedef new_uniform_01<Num> type;  };};}// Because it is so commonly used: uniform distribution on the real [0..1)// range.  This allows for specializations to avoid a costly int -> float// conversion plus float multiplicationtemplate<class UniformRandomNumberGenerator = double, class RealType = double>class uniform_01  : public detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type{  typedef typename detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type impl_type;  typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;public:  uniform_01() {}  explicit uniform_01(typename traits::rvalue_type rng)    : impl_type(rng)  {  }#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)  template<class CharT, class Traits>  friend std::basic_ostream<CharT,Traits>&  operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)  {    os << static_cast<const impl_type&>(u);    return os;  }  template<class CharT, class Traits>  friend std::basic_istream<CharT,Traits>&  operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)  {    is >> static_cast<impl_type&>(u);    return is;  }#endif};#endif} // namespace randomusing random::uniform_01;} // namespace boost#include <boost/random/detail/enable_warnings.hpp>#endif // BOOST_RANDOM_UNIFORM_01_HPP
 |