Chris@16: /* boost random/uniform_01.hpp header file Chris@16: * Chris@16: * Copyright Jens Maurer 2000-2001 Chris@16: * Distributed under the Boost Software License, Version 1.0. (See Chris@16: * accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: * See http://www.boost.org for most recent version including documentation. Chris@16: * Chris@101: * $Id$ Chris@16: * Chris@16: * Revision history Chris@16: * 2001-02-18 moved to individual header files Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_RANDOM_UNIFORM_01_HPP Chris@16: #define BOOST_RANDOM_UNIFORM_01_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace random { Chris@16: Chris@16: #ifdef BOOST_RANDOM_DOXYGEN Chris@16: Chris@16: /** Chris@16: * The distribution function uniform_01 models a \random_distribution. Chris@16: * On each invocation, it returns a random floating-point value Chris@16: * uniformly distributed in the range [0..1). Chris@16: * Chris@16: * The template parameter RealType shall denote a float-like value type Chris@16: * with support for binary operators +, -, and /. Chris@16: * Chris@16: * Note: The current implementation is buggy, because it may not fill Chris@16: * all of the mantissa with random bits. I'm unsure how to fill a Chris@16: * (to-be-invented) @c boost::bigfloat class with random bits efficiently. Chris@16: * It's probably time for a traits class. Chris@16: */ Chris@16: template Chris@16: class uniform_01 Chris@16: { Chris@16: public: Chris@16: typedef RealType input_type; Chris@16: typedef RealType result_type; Chris@16: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const; Chris@16: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const; Chris@16: void reset(); Chris@16: Chris@16: template Chris@16: result_type operator()(Engine& eng); Chris@16: Chris@16: #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS Chris@16: template Chris@16: friend std::basic_ostream& Chris@16: operator<<(std::basic_ostream& os, const new_uniform_01&) Chris@16: { Chris@16: return os; Chris@16: } Chris@16: Chris@16: template Chris@16: friend std::basic_istream& Chris@16: operator>>(std::basic_istream& is, new_uniform_01&) Chris@16: { Chris@16: return is; Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: #else Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: template Chris@16: class new_uniform_01 Chris@16: { Chris@16: public: Chris@16: typedef RealType input_type; Chris@16: typedef RealType result_type; Chris@16: // compiler-generated copy ctor and copy assignment are fine Chris@16: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); } Chris@16: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); } Chris@16: void reset() { } Chris@16: Chris@16: template Chris@16: result_type operator()(Engine& eng) { Chris@16: for (;;) { Chris@16: typedef typename Engine::result_type base_result; Chris@16: result_type factor = result_type(1) / Chris@16: (result_type((eng.max)()-(eng.min)()) + Chris@16: result_type(std::numeric_limits::is_integer ? 1 : 0)); Chris@16: result_type result = result_type(eng() - (eng.min)()) * factor; Chris@16: if (result < result_type(1)) Chris@16: return result; Chris@16: } Chris@16: } Chris@16: Chris@16: #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS Chris@16: template Chris@16: friend std::basic_ostream& Chris@16: operator<<(std::basic_ostream& os, const new_uniform_01&) Chris@16: { Chris@16: return os; Chris@16: } Chris@16: Chris@16: template Chris@16: friend std::basic_istream& Chris@16: operator>>(std::basic_istream& is, new_uniform_01&) Chris@16: { Chris@16: return is; Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: class backward_compatible_uniform_01 Chris@16: { Chris@16: typedef boost::random::detail::ptr_helper traits; Chris@16: public: Chris@16: typedef UniformRandomNumberGenerator base_type; Chris@16: typedef RealType result_type; Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); Chris@16: Chris@101: #if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) Chris@16: BOOST_STATIC_ASSERT(!std::numeric_limits::is_integer); Chris@16: #endif Chris@16: Chris@16: explicit backward_compatible_uniform_01(typename traits::rvalue_type rng) Chris@16: : _rng(rng), Chris@16: _factor(result_type(1) / Chris@16: (result_type((base().max)()-(base().min)()) + Chris@16: result_type(std::numeric_limits::is_integer ? 1 : 0))) Chris@16: { Chris@16: } Chris@16: // compiler-generated copy ctor and copy assignment are fine Chris@16: Chris@16: result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); } Chris@16: result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); } Chris@16: typename traits::value_type& base() { return traits::ref(_rng); } Chris@16: const typename traits::value_type& base() const { return traits::ref(_rng); } Chris@16: void reset() { } Chris@16: Chris@16: result_type operator()() { Chris@16: for (;;) { Chris@16: result_type result = result_type(base()() - (base().min)()) * _factor; Chris@16: if (result < result_type(1)) Chris@16: return result; Chris@16: } Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) Chris@16: template Chris@16: friend std::basic_ostream& Chris@16: operator<<(std::basic_ostream& os, const backward_compatible_uniform_01& u) Chris@16: { Chris@16: os << u._rng; Chris@16: return os; Chris@16: } Chris@16: Chris@16: template Chris@16: friend std::basic_istream& Chris@16: operator>>(std::basic_istream& is, backward_compatible_uniform_01& u) Chris@16: { Chris@16: is >> u._rng; Chris@16: return is; Chris@16: } Chris@16: #endif Chris@16: Chris@16: private: Chris@16: typedef typename traits::value_type::result_type base_result; Chris@16: UniformRandomNumberGenerator _rng; Chris@16: result_type _factor; Chris@16: }; Chris@16: Chris@16: #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION Chris@16: // A definition is required even for integral static constants Chris@16: template Chris@16: const bool backward_compatible_uniform_01::has_fixed_range; Chris@16: #endif Chris@16: Chris@16: template Chris@16: struct select_uniform_01 Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef backward_compatible_uniform_01 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct select_uniform_01 Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef new_uniform_01 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct select_uniform_01 Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef new_uniform_01 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct select_uniform_01 Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef new_uniform_01 type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: // Because it is so commonly used: uniform distribution on the real [0..1) Chris@16: // range. This allows for specializations to avoid a costly int -> float Chris@16: // conversion plus float multiplication Chris@16: template Chris@16: class uniform_01 Chris@16: : public detail::select_uniform_01::BOOST_NESTED_TEMPLATE apply::type Chris@16: { Chris@16: typedef typename detail::select_uniform_01::BOOST_NESTED_TEMPLATE apply::type impl_type; Chris@16: typedef boost::random::detail::ptr_helper traits; Chris@16: public: Chris@16: Chris@16: uniform_01() {} Chris@16: Chris@16: explicit uniform_01(typename traits::rvalue_type rng) Chris@16: : impl_type(rng) Chris@16: { Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) Chris@16: template Chris@16: friend std::basic_ostream& Chris@16: operator<<(std::basic_ostream& os, const uniform_01& u) Chris@16: { Chris@16: os << static_cast(u); Chris@16: return os; Chris@16: } Chris@16: Chris@16: template Chris@16: friend std::basic_istream& Chris@16: operator>>(std::basic_istream& is, uniform_01& u) Chris@16: { Chris@16: is >> static_cast(u); Chris@16: return is; Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: #endif Chris@16: Chris@16: } // namespace random Chris@16: Chris@16: using random::uniform_01; Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_RANDOM_UNIFORM_01_HPP