From 7f09067fef14f06c19e4625d089de69d05fef232 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sun, 25 Jun 2006 01:23:17 +0000 Subject: [PATCH] random (class normal_distribution<>): Add. 2006-06-24 Paolo Carlini * include/tr1/random (class normal_distribution<>): Add. * include/tr1/random.tcc (normal_distribution<>::operator()): Define. * include/tr1/random.tcc (struct _Max): Remove, "inline" in the only user, mersenne_twister<>::max(). * include/tr1/random.tcc (struct _Shift): Move... * include/tr1/random: ... here. * include/tr1/random.tcc (linear_congruential<>:: linear_congruential(unsigned long), linear_congruential<>:: linear_congruential(_Gen&), mersenne_twister<>::max())): Move inline... * include/tr1/random: ... here. * include/tr1/random (exponential_distribution<>:: exponential_distribution(const result_type&)): Add missing _GLIBCXX_DEBUG_ASSERT. * testsuite/tr1/5_numerical_facilities/random/ exponential_distribution/requirements/typedefs.cc: New. * testsuite/tr1/5_numerical_facilities/random/ normal_distribution/requirements/typedefs.cc: Likewise. * testsuite/tr1/5_numerical_facilities/random/ bernoulli_distribution/requirements/typedefs.cc: Likewise. * testsuite/tr1/5_numerical_facilities/random/ geometric_distribution/requirements/typedefs.cc: Likewise. From-SVN: r114982 --- libstdc++-v3/ChangeLog | 29 +++++ libstdc++-v3/include/tr1/random | 122 +++++++++++++++++- libstdc++-v3/include/tr1/random.tcc | 86 ++++++------ .../requirements/typedefs.cc | 37 ++++++ .../requirements/typedefs.cc | 37 ++++++ .../requirements/typedefs.cc | 37 ++++++ .../requirements/typedefs.cc | 37 ++++++ .../uniform_real/requirements/typedefs.cc | 2 +- 8 files changed, 338 insertions(+), 49 deletions(-) create mode 100644 libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc create mode 100644 libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc create mode 100644 libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc create mode 100644 libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a16f9044207..6979a436842 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,32 @@ +2006-06-24 Paolo Carlini + + * include/tr1/random (class normal_distribution<>): Add. + * include/tr1/random.tcc (normal_distribution<>::operator()): Define. + + * include/tr1/random.tcc (struct _Max): Remove, "inline" in the + only user, mersenne_twister<>::max(). + + * include/tr1/random.tcc (struct _Shift): Move... + * include/tr1/random: ... here. + + * include/tr1/random.tcc (linear_congruential<>:: + linear_congruential(unsigned long), linear_congruential<>:: + linear_congruential(_Gen&), mersenne_twister<>::max())): Move inline... + * include/tr1/random: ... here. + + * include/tr1/random (exponential_distribution<>:: + exponential_distribution(const result_type&)): Add missing + _GLIBCXX_DEBUG_ASSERT. + + * testsuite/tr1/5_numerical_facilities/random/ + exponential_distribution/requirements/typedefs.cc: New. + * testsuite/tr1/5_numerical_facilities/random/ + normal_distribution/requirements/typedefs.cc: Likewise. + * testsuite/tr1/5_numerical_facilities/random/ + bernoulli_distribution/requirements/typedefs.cc: Likewise. + * testsuite/tr1/5_numerical_facilities/random/ + geometric_distribution/requirements/typedefs.cc: Likewise. + 2006-06-23 Benjamin Kosnik PR libstdc++/27984 diff --git a/libstdc++-v3/include/tr1/random b/libstdc++-v3/include/tr1/random index 69bda57b663..7eb8f670b75 100644 --- a/libstdc++-v3/include/tr1/random +++ b/libstdc++-v3/include/tr1/random @@ -124,6 +124,15 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) return __return_value; } + template::digits> + struct _Shift + { static const _UIntType __value = 0; }; + + template + struct _Shift<_UIntType, __w, true> + { static const _UIntType __value = _UIntType(1) << __w; }; + } // namespace std::tr1::_Private @@ -301,7 +310,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) * * @param __s The initial seed value. */ - explicit linear_congruential(unsigned long __s = 1); + explicit + linear_congruential(unsigned long __x0 = 1) + { this->seed(__x0); } /** * Constructs a %linear_congruential random number generator engine @@ -310,7 +321,8 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) * @param __g The seed generator function. */ template - linear_congruential(_Gen& __g); + linear_congruential(_Gen& __g) + { this->seed(__g); } /** * Reseeds the %linear_congruential random number generator engine @@ -513,7 +525,8 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) { return 0; }; result_type - max() const; + max() const + { return _Private::_Shift<_UIntType, __w>::__value - 1; } result_type operator()(); @@ -1657,7 +1670,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) */ explicit exponential_distribution(const result_type& __lambda = result_type(1)) - : _M_lambda(__lambda) { } + : _M_lambda(__lambda) + { + _GLIBCXX_DEBUG_ASSERT(_M_lambda > 0); + } /** * Gets the inverse scale parameter of the distribution. @@ -1714,6 +1730,104 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) result_type _M_lambda; }; + + /** + * @brief A normal continuous distribution for random numbers. + * + * The formula for the normal probability mass function is + * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}} + * e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$. + */ + template + class normal_distribution + { + public: + // types + typedef _RealType input_type; + typedef _RealType result_type; + + public: + /** + * Constructs a normal distribution with parameters @f$ mean @f$ and + * @f$ \sigma @f$. + */ + explicit + normal_distribution(const result_type& __mean = result_type(0), + const result_type& __sigma = result_type(1)) + : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false) + { + _GLIBCXX_DEBUG_ASSERT(_M_sigma > 0); + } + + /** + * Gets the mean of the distribution. + */ + _RealType + mean() const + { return _M_mean; } + + /** + * Gets the @f$ \sigma @f$ of the distribution. + */ + _RealType + sigma() const + { return _M_sigma; } + + /** + * Resets the distribution. + */ + void + reset() + { _M_saved_available = false; } + + template + result_type + operator()(_UniformRandomNumberGenerator& __urng); + + /** + * Inserts a %normal_distribution random number distribution + * @p __x into the output stream @p __os. + * + * @param __os An output stream. + * @param __x A %normal_distribution random number distribution. + * + * @returns The output stream with the state of @p __x inserted or in + * an error state. + */ + template + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const normal_distribution& __x) + { + return __os << __x.mean() << " " << __x.sigma() + << " " << __x._M_saved << " " << __x._M_saved_available; + } + + /** + * Extracts a %normal_distribution random number distribution + * @p __u from the input stream @p __is. + * + * @param __is An input stream. + * @param __u A %normal_distribution random number generator engine. + * + * @returns The input stream with @p __u extracted or in an error state. + */ + template + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + normal_distribution& __u) + { + return __is >> __u._M_mean >> __u._M_sigma + >> __u._M_saved >> __u._M_saved_available; + } + + private: + result_type _M_mean; + result_type _M_sigma; + result_type _M_saved; + bool _M_saved_available; + }; + /* @} */ // group tr1_random_distributions_continuous /* @} */ // group tr1_random_distributions /* @} */ // group tr1_random diff --git a/libstdc++-v3/include/tr1/random.tcc b/libstdc++-v3/include/tr1/random.tcc index 93bc498c67e..d4f2464b90d 100644 --- a/libstdc++-v3/include/tr1/random.tcc +++ b/libstdc++-v3/include/tr1/random.tcc @@ -27,8 +27,6 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include - namespace std { _GLIBCXX_BEGIN_NAMESPACE(tr1) @@ -96,40 +94,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) __mod(_Tp __x) { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); } - template::digits> - struct _Shift - { static const _UIntType __value = 0; }; - - template - struct _Shift<_UIntType, __w, true> - { static const _UIntType __value = _UIntType(1) << __w; }; - - // The maximum value that will fit in @p __w bits of @p _UIntType. - template - struct _Max - { static const _UIntType __value = _Shift<_UIntType, __w>::__value - 1; }; - } // namespace _Private - /** - * Constructs the LCR engine with integral seed @p __x0. - */ - template - linear_congruential<_UIntType, __a, __c, __m>:: - linear_congruential(unsigned long __x0) - { this->seed(__x0); } - - /** - * Constructs the LCR engine with seed generated from @p __g. - */ - template - template - linear_congruential<_UIntType, __a, __c, __m>:: - linear_congruential(_Gen& __g) - { this->seed(__g); } - /** * Seeds the LCR with integral value @p __x0, adjusted so that the * ring identity is never a member of the convergence set. @@ -239,17 +206,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _M_p = state_size; } - template - typename - mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, - __b, __t, __c, __l>::result_type - mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, - __b, __t, __c, __l>:: - max() const - { return _Private::_Max<_UIntType, __w>::__value; } - template @@ -396,5 +352,47 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) return _M_b(); } + + /** + * Classic Box-Muller method. + * + * Reference: + * Box, G. E. P. and Muller, M. E. "A Note on the Generation of + * Random Normal Deviates." Ann. Math. Stat. 29, 610-611, 1958. + */ + template + template + typename normal_distribution<_RealType>::result_type + normal_distribution<_RealType>:: + operator()(_UniformRandomNumberGenerator& __urng) + { + result_type __ret; + + if (_M_saved_available) + { + _M_saved_available = false; + __ret = _M_saved; + } + else + { + result_type __x, __y, __r2; + do + { + __x = result_type(2.0) * __urng() - result_type(1.0); + __y = result_type(2.0) * __urng() - result_type(1.0); + __r2 = __x * __x + __y * __y; + } + while (__r2 > result_type(1.0) || __r2 == result_type(0)); + + const result_type __mult = std::sqrt(-result_type(2.0) + * std::log(__r2) / __r2); + _M_saved = __x * __mult; + _M_saved_available = true; + __ret = __y * __mult; + } + + return __ret * _M_sigma + _M_mean; + } + _GLIBCXX_END_NAMESPACE } diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc new file mode 100644 index 00000000000..aca11a43853 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// +// 2006-06-24 Paolo Carlini +// +// Copyright (C) 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 5.1.7.2 Class template bernoulli_distribution [tr.rand.dist.bern] +// 5.1.1 [7] Table 17 + +#include + +void +test01() +{ + using namespace std::tr1; + + typedef bernoulli_distribution test_type; + + typedef test_type::input_type input_type; + typedef test_type::result_type result_type; +} diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc new file mode 100644 index 00000000000..1bc5b3f8dff --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// +// 2006-06-24 Paolo Carlini +// +// Copyright (C) 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 5.1.7.7 Class template exponential_distribution [tr.rand.dist.exp] +// 5.1.1 [7] Table 17 + +#include + +void +test01() +{ + using namespace std::tr1; + + typedef exponential_distribution test_type; + + typedef test_type::input_type input_type; + typedef test_type::result_type result_type; +} diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc new file mode 100644 index 00000000000..525ca64556f --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// +// 2006-06-24 Paolo Carlini +// +// Copyright (C) 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 5.1.7.3 Class template geometric_distribution [tr.rand.dist.geom] +// 5.1.1 [7] Table 17 + +#include + +void +test01() +{ + using namespace std::tr1; + + typedef geometric_distribution test_type; + + typedef test_type::input_type input_type; + typedef test_type::result_type result_type; +} diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc new file mode 100644 index 00000000000..22094646c37 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// +// 2006-06-24 Paolo Carlini +// +// Copyright (C) 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 5.1.7.8 Class template normal_distribution [tr.rand.dist.norm] +// 5.1.1 [7] Table 17 + +#include + +void +test01() +{ + using namespace std::tr1; + + typedef normal_distribution test_type; + + typedef test_type::input_type input_type; + typedef test_type::result_type result_type; +} diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc index b1ca8f4db58..65bcbd7f3ba 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc @@ -20,7 +20,7 @@ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. -// 5.1.7.6 Class template uniform_int [tr.rand.dist.runif] +// 5.1.7.6 Class template uniform_real [tr.rand.dist.runif] // 5.1.1 [7] Table 17 #include