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] Add tr1::normal_distribution, etc.


Hi,

tested x86-linux, committed to mainline.

Paolo.

///////////////////
2006-06-24  Paolo Carlini  <pcarlini@suse.de>

	* 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.
Index: include/tr1/random
===================================================================
--- include/tr1/random	(revision 114961)
+++ include/tr1/random	(working copy)
@@ -124,6 +124,15 @@
       	return __return_value;
       }
 
+    template<typename _UIntType, int __w, bool = 
+	     __w != std::numeric_limits<_UIntType>::digits>
+      struct _Shift
+      { static const _UIntType __value = 0; };
+
+    template<typename _UIntType, int __w>
+      struct _Shift<_UIntType, __w, true>
+      { static const _UIntType __value = _UIntType(1) << __w; };
+
   } // namespace std::tr1::_Private
 
 
@@ -301,7 +310,9 @@
        *
        * @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 @@
        * @param __g The seed generator function.
        */
       template<class _Gen>
-        linear_congruential(_Gen& __g);
+        linear_congruential(_Gen& __g)
+        { this->seed(__g); }
 
       /**
        * Reseeds the %linear_congruential random number generator engine
@@ -513,7 +525,8 @@
       { return 0; };
 
       result_type
-      max() const;
+      max() const
+      { return _Private::_Shift<_UIntType, __w>::__value - 1; }
 
       result_type
       operator()();
@@ -1657,7 +1670,10 @@
        */
       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 @@
       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<typename _RealType = double>
+    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<class _UniformRandomNumberGenerator>
+        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<typename _CharT, typename _Traits>
+        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<typename _CharT, typename _Traits>
+        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
Index: include/tr1/random.tcc
===================================================================
--- include/tr1/random.tcc	(revision 114961)
+++ include/tr1/random.tcc	(working copy)
@@ -27,8 +27,6 @@
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-#include <limits>
-
 namespace std
 {
 _GLIBCXX_BEGIN_NAMESPACE(tr1)
@@ -96,41 +94,10 @@
       __mod(_Tp __x)
       { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
 
-    template<typename _UIntType, int __w, bool = 
-	     __w != std::numeric_limits<_UIntType>::digits>
-      struct _Shift
-      { static const _UIntType __value = 0; };
-
-    template<typename _UIntType, int __w>
-      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<typename _UIntType, int __w>
-      struct _Max
-      { static const _UIntType __value = _Shift<_UIntType, __w>::__value - 1; };
-
   } // namespace _Private
 
 
   /**
-   * Constructs the LCR engine with integral seed @p __x0.
-   */
-  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
-    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<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
-    template<class _Gen>
-      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.
    */
@@ -247,17 +214,6 @@
 		     __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<class _UIntType, int __w, int __n, int __m, int __r,
-	   _UIntType __a, int __u, int __s,
-	   _UIntType __b, int __t, _UIntType __c, int __l>
-    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>::
     operator()()
     {
       // Reload the vector - cost is O(n) amortized over n calls.
@@ -396,5 +352,47 @@
       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<typename _RealType>
+    template<class _UniformRandomNumberGenerator>
+      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
 }
Index: testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc
===================================================================
--- testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc	(revision 114961)
+++ testsuite/tr1/5_numerical_facilities/random/uniform_real/requirements/typedefs.cc	(working copy)
@@ -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 <tr1/random>
Index: testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc
===================================================================
--- testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc	(revision 0)
+++ testsuite/tr1/5_numerical_facilities/random/exponential_distribution/requirements/typedefs.cc	(revision 0)
@@ -0,0 +1,37 @@
+// { dg-do compile }
+//
+// 2006-06-24  Paolo Carlini  <pcarlini@suse.de>
+//
+// 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 <tr1/random>
+
+void
+test01() 
+{ 
+  using namespace std::tr1;
+
+  typedef exponential_distribution<double> test_type;
+
+  typedef test_type::input_type  input_type;
+  typedef test_type::result_type result_type;
+}
Index: testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc
===================================================================
--- testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc	(revision 0)
+++ testsuite/tr1/5_numerical_facilities/random/normal_distribution/requirements/typedefs.cc	(revision 0)
@@ -0,0 +1,37 @@
+// { dg-do compile }
+//
+// 2006-06-24  Paolo Carlini  <pcarlini@suse.de>
+//
+// 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 <tr1/random>
+
+void
+test01() 
+{ 
+  using namespace std::tr1;
+
+  typedef normal_distribution<double> test_type;
+
+  typedef test_type::input_type  input_type;
+  typedef test_type::result_type result_type;
+}
Index: testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc
===================================================================
--- testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc	(revision 0)
+++ testsuite/tr1/5_numerical_facilities/random/bernoulli_distribution/requirements/typedefs.cc	(revision 0)
@@ -0,0 +1,37 @@
+// { dg-do compile }
+//
+// 2006-06-24  Paolo Carlini  <pcarlini@suse.de>
+//
+// 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 <tr1/random>
+
+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;
+}
Index: testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc
===================================================================
--- testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc	(revision 0)
+++ testsuite/tr1/5_numerical_facilities/random/geometric_distribution/requirements/typedefs.cc	(revision 0)
@@ -0,0 +1,37 @@
+// { dg-do compile }
+//
+// 2006-06-24  Paolo Carlini  <pcarlini@suse.de>
+//
+// 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 <tr1/random>
+
+void
+test01() 
+{ 
+  using namespace std::tr1;
+
+  typedef geometric_distribution<int, double> test_type;
+
+  typedef test_type::input_type  input_type;
+  typedef test_type::result_type result_type;
+}

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