From 36ac3ed6b75d80704a706dbd2f9f33594d657af7 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 5 Jun 2006 21:23:59 +0000 Subject: [PATCH] random (mersenne_twister<>::seed()): Fix per tr1/5.1.4.2, p8. 2006-06-05 Paolo Carlini * include/tr1/random (mersenne_twister<>::seed()): Fix per tr1/5.1.4.2, p8. * include/tr1/random.tcc (mod_w): Add. (mersenne_twister<>::seed(unsigned long)): Fix per tr1/5.1.4.2, p9. (mersenne_twister<>::seed(Gen&, false_type)): Adjust to use mod_w. * testsuite/tr1/5_numerical_facilies/random/mt19937.cc: Fix expected result per tr1/5.1.5, p2. * testsuite/tr1/5_numerical_facilies/random/mersenne_twister/ cons/default.cc: Adjust. * include/tr1/random (exponential_distribution<>::operator()()): Fix. From-SVN: r114412 --- libstdc++-v3/ChangeLog | 14 +++ libstdc++-v3/include/tr1/random | 4 +- libstdc++-v3/include/tr1/random.tcc | 90 +++++++++---------- .../random/mersenne_twister/cons/default.cc | 2 +- .../5_numerical_facilies/random/mt19937.cc | 2 +- 5 files changed, 58 insertions(+), 54 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1c04e88339e2..1203fc6f6e88 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2006-06-05 Paolo Carlini + + * include/tr1/random (mersenne_twister<>::seed()): Fix per + tr1/5.1.4.2, p8. + * include/tr1/random.tcc (mod_w): Add. + (mersenne_twister<>::seed(unsigned long)): Fix per tr1/5.1.4.2, p9. + (mersenne_twister<>::seed(Gen&, false_type)): Adjust to use mod_w. + * testsuite/tr1/5_numerical_facilies/random/mt19937.cc: Fix + expected result per tr1/5.1.5, p2. + * testsuite/tr1/5_numerical_facilies/random/mersenne_twister/ + cons/default.cc: Adjust. + + * include/tr1/random (exponential_distribution<>::operator()()): Fix. + 2006-06-05 Paolo Carlini * include/tr1/random.tcc (Max::value()): Cast 1 to Tp(1) and diff --git a/libstdc++-v3/include/tr1/random b/libstdc++-v3/include/tr1/random index a4ec86e6a815..2d86cdbe1545 100644 --- a/libstdc++-v3/include/tr1/random +++ b/libstdc++-v3/include/tr1/random @@ -493,7 +493,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) void seed() - { seed(0UL); } + { seed(5489UL); } void seed(unsigned long value); @@ -1560,7 +1560,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) template result_type operator()(_UniformRandomNumberGenerator& __urng) - { return std::log(__urng) / _M_lambda; } + { return -std::log(__urng()) / _M_lambda; } /** * Inserts a %exponential_distribution random number distribution diff --git a/libstdc++-v3/include/tr1/random.tcc b/libstdc++-v3/include/tr1/random.tcc index b78bb4ec1afc..1b252e8f6284 100644 --- a/libstdc++-v3/include/tr1/random.tcc +++ b/libstdc++-v3/include/tr1/random.tcc @@ -113,6 +113,11 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) { return x; } }; + template + inline _Tp + mod_w(_Tp x) + { return Mod_w<_Tp, w, w == std::numeric_limits<_Tp>::digits>::calc(x); } + // Selector to return the maximum value possible that will fit in // @p w bits of @p _Tp. template @@ -229,27 +234,18 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) mersenne_twister<_UInt, w, n, m, r, a, u, s, b, t, c, l>:: seed(unsigned long value) { - if (value == 0) - value = 4357; - -#if 0 - // @todo handle case numeric_limits<_UInt>::digits > 32 - if (std::numeric_limits<_UInt>::digits > 32) - { - std::tr1::linear_congruential lcg(value); - seed(lcg); - } - else - { - std::tr1::linear_congruential lcg(value); - seed(lcg); - } -#else - std::tr1::linear_congruential lcg(value); - seed(lcg); -#endif - } + _M_x[0] = _Private::mod_w<_UInt, w>(value); + for (int i = 1; i < n; ++i) + { + _UInt x = _M_x[i - 1]; + x ^= x >> (w - 2); + x *= 1812433253ul; + x += i; + _M_x[i] = _Private::mod_w<_UInt, w>(x); + } + _M_p = n; + } template:: seed(Gen& gen, false_type) { - using _Private::Mod_w; - using std::numeric_limits; - - for (int i = 0; i < state_size; ++i) - _M_x[i] = Mod_w<_UInt, w, - w == numeric_limits<_UInt>::digits>::calc(gen()); - _M_p = state_size + 1; + for (int i = 0; i < n; ++i) + _M_x[i] = _Private::mod_w<_UInt, w>(gen()); + _M_p = n; } template::digits>::value(); } - template @@ -290,8 +281,8 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) mersenne_twister<_UInt, w, n, m, r, a, u, s, b, t, c, l>:: operator()() { - // reload the vector - cost is O(n) amortized over n calls. - if (_M_p >= state_size) + // Reload the vector - cost is O(n) amortized over n calls. + if (_M_p >= n) { const _UInt upper_mask = (~_UInt()) << r; const _UInt lower_mask = ~upper_mask; @@ -311,14 +302,14 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _M_p = 0; } - // Calculate x(i) - result_type y = _M_x[_M_p++]; - y ^= (y >> u); - y ^= (y << s) & b; - y ^= (y << t) & c; - y ^= (y >> l); - - return y; + // Calculate o(x(i)). + result_type z = _M_x[_M_p++]; + z ^= (z >> u); + z ^= (z << s) & b; + z ^= (z << t) & c; + z ^= (z >> l); + + return z; } @@ -329,15 +320,14 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) { std::tr1::linear_congruential lcg(__value); - + for (int i = 0; i < long_lag; ++i) _M_x[i] = _Private::mod<_IntType, 1, 0, modulus>(lcg()); - + _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; _M_p = 0; } - // // This implementation differs from the tr1 spec because the tr1 spec refused // to make any sense to me: the exponent of the factor in the spec goes from @@ -367,18 +357,18 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; _M_p = 0; } - template typename subtract_with_carry<_IntType, __m, __s, __r>::result_type subtract_with_carry<_IntType, __m, __s, __r>:: operator()() { - // derive short lag index from current index + // Derive short lag index from current index. int ps = _M_p - short_lag; - if (ps < 0) ps += long_lag; - - // calculate new x(i) without overflow or division + if (ps < 0) + ps += long_lag; + + // Calculate new x(i) without overflow or division. _IntType xi; if (_M_x[ps] >= _M_x[_M_p] + _M_carry) { @@ -391,15 +381,15 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) _M_carry = 1; } _M_x[_M_p++] = xi; - - // adjust current index to loop around in ring buffer + + // Adjust current index to loop around in ring buffer. if (_M_p >= long_lag) _M_p = 0; - + return xi; } - + template typename discard_block<_E, __p, __r>::result_type discard_block<_E, __p, __r>:: diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mersenne_twister/cons/default.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mersenne_twister/cons/default.cc index 9a17e164016b..459bb4721526 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mersenne_twister/cons/default.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mersenne_twister/cons/default.cc @@ -38,7 +38,7 @@ test01() VERIFY( x.min() == 0 ); VERIFY( x.max() == 4294967295ul ); - VERIFY( x() == 4290933890ul ); + VERIFY( x() == 3499211612ul ); } int main() diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mt19937.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mt19937.cc index 0b89e8b44375..a3ddb3d9e3e5 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mt19937.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilies/random/mt19937.cc @@ -33,7 +33,7 @@ test01() for (int i = 0; i < 9999; ++i) a(); - VERIFY( a() == 3346425566ul ); + VERIFY( a() == 4123659995ul ); } int main()