From deb23ecdf93ba373747f2ec91f28672758d40ae1 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 11 May 2010 23:26:59 +0000 Subject: [PATCH] [rand.dist.bern.bin]. The evaluation function for this binomial distribution is hopefully just a placeholder. It is using the simplest and slowest method for computing the distribution and needs to be upgraded. llvm-svn: 103524 --- libcxx/include/__split_buffer | 2 - libcxx/include/memory | 2 - libcxx/include/random | 173 +++++++++++++++++- libcxx/include/string | 2 - .../rand.dist.bern.bernoulli/eval.pass.cpp | 2 +- 5 files changed, 168 insertions(+), 13 deletions(-) diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer index 5eb04b6003d0..1a7c623204f7 100644 --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -642,5 +642,3 @@ __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_SPLIT_BUFFER - -// hh 080222 Created diff --git a/libcxx/include/memory b/libcxx/include/memory index 812de80652aa..10122c7a0baa 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -3820,5 +3820,3 @@ void* align(size_t, size_t, void*&, size_t&); _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MEMORY - -// hh 060228 Created diff --git a/libcxx/include/random b/libcxx/include/random index 811bc26e1794..0f2c6eae24ff 100644 --- a/libcxx/include/random +++ b/libcxx/include/random @@ -608,7 +608,62 @@ public: }; template - class binomial_distribution; +class binomial_distribution +{ +public: + // types + typedef IntType result_type; + + class param_type + { + public: + typedef binomial_distribution distribution_type; + + explicit param_type(IntType t = 1, double p = 0.5); + + IntType t() const; + double p() const; + + friend bool operator==(const param_type& x, const param_type& y); + friend bool operator!=(const param_type& x, const param_type& y); + }; + + // constructors and reset functions + explicit binomial_distribution(IntType t = 1, double p = 0.5); + explicit binomial_distribution(const param_type& parm); + void reset(); + + // generating functions + template result_type operator()(URNG& g); + template result_type operator()(URNG& g, const param_type& parm); + + // property functions + IntType t() const; + double p() const; + + param_type param() const; + void param(const param_type& parm); + + result_type min() const; + result_type max() const; + + friend bool operator==(const binomial_distribution& x, + const binomial_distribution& y); + friend bool operator!=(const binomial_distribution& x, + const binomial_distribution& y); + + template + friend + basic_ostream& + operator<<(basic_ostream& os, + const binomial_distribution& x); + + template + friend + basic_istream& + operator>>(basic_istream& is, + binomial_distribution& x); +}; template class geometric_distribution; @@ -2797,11 +2852,7 @@ public: // generating functions template result_type operator()(_URNG& __g) {return (*this)(__g, __p_);} - template result_type operator()(_URNG& __g, const param_type& __p) - { - return _STD::generate_canonical::digits>(__g) - < __p.p(); - } + template result_type operator()(_URNG& __g, const param_type& __p); // property functions double p() const {return __p_.p();} @@ -2820,6 +2871,14 @@ public: {return !(__x == __y);} }; +template +inline +bernoulli_distribution::result_type +bernoulli_distribution::operator()(_URNG& __g, const param_type& __p) +{ + return (__g() - __g.min()) < __p.p() * (__g.max() - __g.min() + 1.); +} + template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) @@ -2846,6 +2905,108 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x) return __is; } +template +class binomial_distribution +{ +public: + // types + typedef _IntType result_type; + + class param_type + { + result_type __t_; + double __p_; + public: + typedef binomial_distribution distribution_type; + + explicit param_type(result_type __t = 1, double __p = 0.5) + : __t_(__t), __p_(__p) {} + + result_type t() const {return __t_;} + double p() const {return __p_;} + + friend bool operator==(const param_type& __x, const param_type& __y) + {return __x.__t_ == __y.__t_ && __x.__p_ == __y.__p_;} + friend bool operator!=(const param_type& __x, const param_type& __y) + {return !(__x == __y);} + }; + +private: + param_type __p_; + +public: + // constructors and reset functions + explicit binomial_distribution(result_type __t = 1, double __p = 0.5) + : __p_(param_type(__t, __p)) {} + explicit binomial_distribution(const param_type& __p) : __p_(__p) {} + void reset() {} + + // generating functions + template result_type operator()(_URNG& __g) + {return (*this)(__g, __p_);} + template result_type operator()(_URNG& __g, const param_type& __p); + + // property functions + result_type t() const {return __p_.t();} + double p() const {return __p_.p();} + + param_type param() const {return __p_;} + void param(const param_type& __p) {__p_ = __p;} + + result_type min() const {return 0;} + result_type max() const {return t();} + + friend bool operator==(const binomial_distribution& __x, + const binomial_distribution& __y) + {return __x.__p_ == __y.__p_;} + friend bool operator!=(const binomial_distribution& __x, + const binomial_distribution& __y) + {return !(__x == __y);} +}; + +template +template +_IntType +binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) +{ + bernoulli_distribution __bd(__p.p()); + _IntType __r = 0; + _IntType __t = __p.t(); + for (_IntType __i = 0; __i < __t; ++__i) + __r += __bd(__g); + return __r; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const binomial_distribution<_IntType>& __x) +{ + __save_flags<_CharT, _Traits> _(__os); + __os.flags(ios_base::dec | ios_base::left); + _CharT __sp = __os.widen(' '); + __os.fill(__sp); + return __os << __x.t() << __sp << __x.p(); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + binomial_distribution<_IntType>& __x) +{ + typedef binomial_distribution<_IntType> _Eng; + typedef typename _Eng::result_type result_type; + typedef typename _Eng::param_type param_type; + __save_flags<_CharT, _Traits> _(__is); + __is.flags(ios_base::dec | ios_base::skipws); + result_type __t; + double __p; + __is >> __t >> __p; + if (!__is.fail()) + __x.param(param_type(__t, __p)); + return __is; +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_RANDOM diff --git a/libcxx/include/string b/libcxx/include/string index 2e041c63ff88..6b11e02bc2be 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -3539,5 +3539,3 @@ extern template _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STRING - -// hh 060525 Created diff --git a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp index f37dd3ed699b..2c82a4fc67b4 100644 --- a/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp +++ b/libcxx/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/eval.pass.cpp @@ -19,7 +19,7 @@ int main() { { - typedef std::uniform_int_distribution<> D; + typedef std::bernoulli_distribution D; typedef std::minstd_rand0 G; G g; D d(.75);