This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] tr1/xor_combine::max


Hi,

tested x86-linux, committed to mainline.

Paolo.

/////////////////
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.
Index: include/tr1/random
===================================================================
--- include/tr1/random	(revision 116557)
+++ include/tr1/random	(working copy)
@@ -944,7 +944,10 @@
        * 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 @@
        */
       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 @@
        */
       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 @@
         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 @@
       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 @@
       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 @@
 		   _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: include/tr1/random.tcc
===================================================================
--- include/tr1/random.tcc	(revision 116557)
+++ include/tr1/random.tcc	(working copy)
@@ -448,6 +448,19 @@
   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 @@
 	    }
 
 	_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 @@
 
 
   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>&

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]