From a3b6119721e9344233ac684940ea4cc0ee79e9c5 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Tue, 29 Aug 2006 11:46:54 +0000 Subject: [PATCH] random (subtract_with_carry_01<>::_M_initialize_npows): New. 2006-08-29 Paolo Carlini * include/tr1/random (subtract_with_carry_01<>::_M_initialize_npows): New. (subtract_with_carry_01<>::subtract_with_carry_01(), subtract_with_carry_01<>::subtract_with_carry_01(unsigned long), subtract_with_carry_01<>::subtract_with_carry_01(_Gen&)): Use it. * include/tr1/random.tcc: Define. * include/tr1/random (xor_combine<>::_M_initialize_max()): New. (xor_combine<>::xor_combine(), xor_combine<>::xor_combine(const base1_type&, const base2_type&), xor_combine<>::xor_combine(unsigned long), xor_combine<>::xor_combine(_Gen&)): Use it. (xor_combine<>::min, xor_combine<>::max): Adjust. * include/tr1/random.tcc: Define. From-SVN: r116559 --- libstdc++-v3/ChangeLog | 16 +++++++++ libstdc++-v3/include/tr1/random | 46 +++++++++++++++++------- libstdc++-v3/include/tr1/random.tcc | 54 ++++++++++++++++++++++++----- 3 files changed, 95 insertions(+), 21 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a7bc8526c3af..cf8546c87a06 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,19 @@ +2006-08-29 Paolo Carlini + + * include/tr1/random (subtract_with_carry_01<>::_M_initialize_npows): + New. + (subtract_with_carry_01<>::subtract_with_carry_01(), + subtract_with_carry_01<>::subtract_with_carry_01(unsigned long), + subtract_with_carry_01<>::subtract_with_carry_01(_Gen&)): Use it. + * include/tr1/random.tcc: Define. + + * include/tr1/random (xor_combine<>::_M_initialize_max()): New. + (xor_combine<>::xor_combine(), xor_combine<>::xor_combine(const + base1_type&, const base2_type&), xor_combine<>::xor_combine(unsigned + long), xor_combine<>::xor_combine(_Gen&)): Use it. + (xor_combine<>::min, xor_combine<>::max): Adjust. + * include/tr1/random.tcc: Define. + 2006-08-29 Benjamin Kosnik * acinclude.m4(glibcxx_PCHFLAGS): Set to stdtr1c++.h. diff --git a/libstdc++-v3/include/tr1/random b/libstdc++-v3/include/tr1/random index b90d3239da26..8ffdf16d7f59 100644 --- a/libstdc++-v3/include/tr1/random +++ b/libstdc++-v3/include/tr1/random @@ -944,7 +944,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) * number generator. */ subtract_with_carry_01() - { this->seed(); } + { + this->seed(); + _M_initialize_npows(); + } /** * Constructs an explicitly seeded % subtract_with_carry_01 random number @@ -952,7 +955,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) */ explicit subtract_with_carry_01(unsigned long __value) - { this->seed(__value); } + { + this->seed(__value); + _M_initialize_npows(); + } /** * Constructs a % subtract_with_carry_01 random number generator engine @@ -962,7 +968,10 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) */ template subtract_with_carry_01(_Gen& __g) - { this->seed(__g); } + { + this->seed(__g); + _M_initialize_npows(); + } /** * Seeds the initial state @f$ x_0 @f$ of the random number generator. @@ -1081,6 +1090,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) seed(_Gen& __g, false_type); private: + void + _M_initialize_npows(); + static const int __n = (__w + 31) / 32; _UInt32Type _M_x[long_lag][__n]; @@ -1372,17 +1384,22 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) static const int shift2 = __s2; // constructors and member function - xor_combine() { } + xor_combine() + : _M_b1(), _M_b2() + { _M_initialize_max(); } xor_combine(const base1_type& __rng1, const base2_type& __rng2) - : _M_b1(__rng1), _M_b2(__rng2) { } + : _M_b1(__rng1), _M_b2(__rng2) + { _M_initialize_max(); } xor_combine(unsigned long __s) - : _M_b1(__s), _M_b2(__s + 1) { } + : _M_b1(__s), _M_b2(__s + 1) + { _M_initialize_max(); } template xor_combine(_Gen& __g) - : _M_b1(__g), _M_b2(__g) { } + : _M_b1(__g), _M_b2(__g) + { _M_initialize_max(); } void seed() @@ -1407,15 +1424,14 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) base2() const { return _M_b2; } - // FIXME: Cannot be always correct. FWIW, the solution in N2032 - // in practice isn't much better.. + // XXX Per N2032, but aren't always right... result_type min() const - { return _M_b1.min() ^ _M_b2.min(); } + { return 0; } result_type max() const - { return _M_b1.max() | _M_b2.max(); } + { return _M_max; } /** * Gets the next random number in the sequence. @@ -1492,8 +1508,12 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _UniformRandomNumberGenerator21, __s21>& __x); private: - base1_type _M_b1; - base2_type _M_b2; + void + _M_initialize_max(); + + base1_type _M_b1; + base2_type _M_b2; + result_type _M_max; }; diff --git a/libstdc++-v3/include/tr1/random.tcc b/libstdc++-v3/include/tr1/random.tcc index b95a5f8d3f51..e6d4d941d596 100644 --- a/libstdc++-v3/include/tr1/random.tcc +++ b/libstdc++-v3/include/tr1/random.tcc @@ -445,6 +445,19 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) } + template + void + subtract_with_carry_01<_RealType, __w, __s, __r>:: + _M_initialize_npows() + { + for (int __j = 0; __j < __n; ++__j) +#if _GLIBCXX_USE_C99_MATH_TR1 + _M_npows[__j] = std::tr1::ldexp(_RealType(1), -__w + __j * 32); +#else + _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32); +#endif + } + template void subtract_with_carry_01<_RealType, __w, __s, __r>:: @@ -484,14 +497,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) } _M_p = 0; - - // Initialize the array holding the negative powers of 2. - for (int __j = 0; __j < __n; ++__j) -#if _GLIBCXX_USE_C99_MATH_TR1 - _M_npows[__j] = std::tr1::ldexp(_RealType(1), -__w + __j * 32); -#else - _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32); -#endif } template @@ -637,6 +642,39 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) } + template + void + xor_combine<_UniformRandomNumberGenerator1, __s1, + _UniformRandomNumberGenerator2, __s2>:: + _M_initialize_max() + { + const int __lshift = std::abs(__s1 - __s2); + + result_type __m1 = _M_b1.max() - _M_b1.min(); + result_type __m2 = _M_b2.max() - _M_b2.min(); + + // NB: in TR1 s1 is not required to be >= s2. + if (__s1 >= __s2) + __m1 <<= __lshift; + else + __m2 <<= __lshift; + + result_type __a = __m1 & __m2; + const result_type __b = __m1 | __m2; + + result_type __c = 0; + if (__a) + { + result_type __k; + for (__k = 0; __a != 1; __a >>= 1) + ++__k; + __c = (result_type(1) << __k) - 1; + } + + _M_max = (__c | __b) << __lshift; + } + template