2006-08-29 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Aug 2006 11:46:54 +0000 (11:46 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Aug 2006 11:46:54 +0000 (11:46 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116559 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/tr1/random
libstdc++-v3/include/tr1/random.tcc

index a7bc852..cf8546c 100644 (file)
@@ -1,3 +1,19 @@
+2006-08-29  Paolo Carlini  <pcarlini@suse.de>
+
+       * 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  <bkoz@redhat.com>
 
        * acinclude.m4(glibcxx_PCHFLAGS): Set to stdtr1c++.h.
index b90d323..8ffdf16 100644 (file)
@@ -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<class _Gen>
         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<class _Gen>
         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;
     };
 
 
index b95a5f8..e6d4d94 100644 (file)
@@ -448,6 +448,19 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
   template<typename _RealType, int __w, int __s, int __r>
     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<typename _RealType, int __w, int __s, int __r>
+    void
+    subtract_with_carry_01<_RealType, __w, __s, __r>::
     seed(unsigned long __value)
     {
       if (__value == 0)
@@ -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<typename _RealType, int __w, int __s, int __r>
@@ -638,6 +643,39 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
 
 
   template<class _UniformRandomNumberGenerator1, int __s1,
+          class _UniformRandomNumberGenerator2, int __s2>
+    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<class _UniformRandomNumberGenerator1, int __s1,
           class _UniformRandomNumberGenerator2, int __s2,
           typename _CharT, typename _Traits>
     std::basic_ostream<_CharT, _Traits>&