public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libstdc++: add uniform on sphere distribution
@ 2014-07-13  2:01 Ulrich Drepper
  2014-07-13  2:06 ` Ulrich Drepper
                   ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13  2:01 UTC (permalink / raw)
  To: gcc-patches

Ed's submission of the logistic regression distribution caused problems
for me because, like Ed, I have changes to the <ext/random> header in my
tree for a long time.  Time to submit them.

This first one is a new distribution.  It generates coordinates for
random points on a unit sphere in arbitrarily many dimensions.  This
distribution by itself is useful but if I get some other code fully
implemented it will also form the basis for yet another, more
sophisticated distribution.

The patch is tested against the current tree without causing additional
problems.

OK?


2014-07-12  Ulrich Drepper  <drepper@gmail.com>

	* include/ext/random: Add uniform_on_sphere_distribution definition.
	* include/ext/random.tcc: Add out-of-band member function definitions
	for uniform_on_sphere_distribution.
	* libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/
	cons/default.cc: New file.
        *
	* libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/
        operators/equal.cc: New file.
        *
	* libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/
        operators/inequal.cc: New file.
        *
	* libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/
        operators/serialize.cc: New file.
        *
	* libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/
        operators/values.cc: New file.


diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -36,6 +36,7 @@
 #else
 
 #include <random>
+#include <algorithm>
 #include <array>
 #include <ext/cmath>
 #ifdef __SSE2__
@@ -3293,6 +3294,196 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	       const logistic_distribution<_RealType1>& __d2)
     { return !(__d1 == __d2); }
 
+
+  /**
+   * @brief A distribution for random coordinates on a unit sphere.
+   *
+   * The method used in the generation function is attributed by Donald Knuth
+   * to G. W. Brown, Modern Mathematics for the Engineer (1956).
+   */
+  template<std::size_t _Dimen, typename _RealType = double>
+    class uniform_on_sphere_distribution
+    {
+      static_assert(std::is_floating_point<_RealType>::value,
+		    "template argument not a floating point type");
+      static_assert(_Dimen != 0, "dimension is zero");
+
+    public:
+      /** The type of the range of the distribution. */
+      typedef std::array<_RealType, _Dimen> result_type;
+      /** Parameter type. */
+      struct param_type
+      {
+	explicit
+	param_type()
+	{ }
+
+	friend bool
+	operator==(const param_type& __p1, const param_type& __p2)
+	{ return true; }
+      };
+
+      /**
+       * @brief Constructs a uniform on sphere distribution.
+       */
+      explicit
+      uniform_on_sphere_distribution()
+      : _M_param(), _M_n(_RealType(0), _RealType(1))
+      { }
+
+      explicit
+      uniform_on_sphere_distribution(const param_type& __p)
+      : _M_param(__p), _M_n(_RealType(0), _RealType(1))
+      { }
+
+      /**
+       * @brief Resets the distribution state.
+       */
+      void
+      reset()
+      { }
+
+      /**
+       * @brief Returns the parameter set of the distribution.
+       */
+      param_type
+      param() const
+      { return _M_param; }
+
+      /**
+       * @brief Sets the parameter set of the distribution.
+       * @param __param The new parameter set of the distribution.
+       */
+      void
+      param(const param_type& __param)
+      { _M_param = __param; }
+
+      /**
+       * @brief Returns the greatest lower bound value of the distribution.
+       * This function makes no sense for this distribution.
+       */
+      result_type
+      min() const
+      {
+	result_type __res;
+	__res.fill(0);
+	return __res;
+      }
+
+      /**
+       * @brief Returns the least upper bound value of the distribution.
+       * This function makes no sense for this distribution.
+       */
+      result_type
+      max() const
+      {
+	result_type __res;
+	__res.fill(0);
+	return __res;
+      }
+
+      /**
+       * @brief Generating functions.
+       */
+      template<typename _UniformRandomNumberGenerator>
+	result_type
+	operator()(_UniformRandomNumberGenerator& __urng)
+	{ return this->operator()(__urng, _M_param); }
+
+      template<typename _UniformRandomNumberGenerator>
+	result_type
+	operator()(_UniformRandomNumberGenerator& __urng,
+		   const param_type& __p);
+
+      template<typename _ForwardIterator,
+	       typename _UniformRandomNumberGenerator>
+	void
+	__generate(_ForwardIterator __f, _ForwardIterator __t,
+		   _UniformRandomNumberGenerator& __urng)
+	{ this->__generate(__f, __t, __urng, this->param()); }
+
+      template<typename _ForwardIterator,
+	       typename _UniformRandomNumberGenerator>
+	void
+	__generate(_ForwardIterator __f, _ForwardIterator __t,
+		   _UniformRandomNumberGenerator& __urng,
+		   const param_type& __p)
+	{ this->__generate_impl(__f, __t, __urng, __p); }
+
+      template<typename _UniformRandomNumberGenerator>
+	void
+	__generate(result_type* __f, result_type* __t,
+		   _UniformRandomNumberGenerator& __urng,
+		   const param_type& __p)
+	{ this->__generate_impl(__f, __t, __urng, __p); }
+
+      /**
+       * @brief Return true if two uniform on sphere distributions have
+       *        the same parameters and the sequences that would be
+       *        generated are equal.
+       */
+      friend bool
+      operator==(const uniform_on_sphere_distribution& __d1,
+		 const uniform_on_sphere_distribution& __d2)
+      { return true; }
+
+      /**
+       * @brief Inserts a %uniform_on_sphere_distribution random number distribution
+       * @p __x into the output stream @p __os.
+       *
+       * @param __os An output stream.
+       * @param __x  A %uniform_on_sphere_distribution random number distribution.
+       *
+       * @returns The output stream with the state of @p __x inserted or in
+       * an error state.
+       */
+      template<size_t _Dimen1, typename _RealType1, typename _CharT,
+	       typename _Traits>
+	friend std::basic_ostream<_CharT, _Traits>&
+	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+		   const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
+								   _RealType1>&
+		   __x);
+
+      /**
+       * @brief Extracts a %uniform_on_sphere_distribution random number distribution
+       * @p __x from the input stream @p __is.
+       *
+       * @param __is An input stream.
+       * @param __x  A %uniform_on_sphere_distribution random number generator engine.
+       *
+       * @returns The input stream with @p __x extracted or in an error state.
+       */
+      template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
+	       typename _Traits>
+	friend std::basic_istream<_CharT, _Traits>&
+	operator>>(std::basic_istream<_CharT, _Traits>& __is,
+		   __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
+							     _RealType1>& __x);
+
+    private:
+      template<typename _ForwardIterator,
+	       typename _UniformRandomNumberGenerator>
+	void
+	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
+			_UniformRandomNumberGenerator& __urng,
+			const param_type& __p);
+
+      param_type _M_param;
+      std::normal_distribution<_RealType> _M_n;
+    };
+
+  /**
+   * @brief Return true if two uniform on sphere distributions are different.
+   */
+  template<std::size_t _Dimen, typename _RealType>
+    inline bool
+    operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
+	       _RealType>& __d1,
+	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
+	       _RealType>& __d2)
+   { return false; }
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace __gnu_cxx
 
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -1539,6 +1539,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __is;
     }
 
+
+  template<std::size_t _Dimen, typename _RealType>
+    template<typename _UniformRandomNumberGenerator>
+      typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type
+      uniform_on_sphere_distribution<_Dimen, _RealType>::
+      operator()(_UniformRandomNumberGenerator& __urng,
+		 const param_type& __p)
+      {
+	result_type __ret;
+	_RealType __sum = _RealType(0);
+
+	std::generate(__ret.begin(), __ret.end(),
+		      [&__urng, &__sum, this](){ _RealType __t = _M_n(__urng);
+						 __sum += __t * __t;
+						 return __t; });
+	auto __norm = std::sqrt(__sum);
+	std::transform(__ret.begin(), __ret.end(), __ret.begin(),
+		       [__norm](_RealType __val){ return __val / __norm; });
+
+	return __ret;
+      }
+
+  template<std::size_t _Dimen, typename _RealType>
+    template<typename _OutputIterator,
+	     typename _UniformRandomNumberGenerator>
+      void
+      uniform_on_sphere_distribution<_Dimen, _RealType>::
+      __generate_impl(_OutputIterator __f, _OutputIterator __t,
+		      _UniformRandomNumberGenerator& __urng,
+		      const param_type& __param)
+      {
+	__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator>)
+
+	while (__f != __t)
+	  *__f++ = this->operator()(__urng, __param);
+      }
+
+  template<std::size_t _Dimen, typename _RealType, typename _CharT,
+	   typename _Traits>
+    std::basic_ostream<_CharT, _Traits>&
+    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
+							       _RealType>& __x)
+    {
+      return __os;
+    }
+
+  template<std::size_t _Dimen, typename _RealType, typename _CharT,
+	   typename _Traits>
+    std::basic_istream<_CharT, _Traits>&
+    operator>>(std::basic_istream<_CharT, _Traits>& __is,
+	       __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
+							 _RealType>& __x)
+    {
+      return __is;
+    }
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff -durpN a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/cons/default.cc
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/cons/default.cc	1969-12-31 19:00:00.000000000 -0500
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/cons/default.cc	2014-04-15 22:49:24.971799863 -0400
@@ -0,0 +1,45 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2014-04-15  Ulrich Drepper  <drepper@gmail.com>
+//
+// Copyright (C) 2014 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template uniform_in_sphere [rand.dist.ext.uniform_on_sphere]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test [[gnu::unused]] = true;
+
+  __gnu_cxx::uniform_on_sphere_distribution<2> u2;
+  __gnu_cxx::uniform_on_sphere_distribution<3> u3;
+  __gnu_cxx::uniform_on_sphere_distribution<4, double> u4;
+  __gnu_cxx::uniform_on_sphere_distribution<5, float> u5;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff -durpN a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc	1969-12-31 19:00:00.000000000 -0500
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc	2014-04-15 22:58:59.474117608 -0400
@@ -0,0 +1,43 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2014-04-15  Ulrich Drepper  <drepper@gmail.com>
+//
+// Copyright (C) 2014 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.5.8.4.5 Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test [[gnu::unused]] = true;
+
+  __gnu_cxx::uniform_on_sphere_distribution<3> u, v;
+
+  VERIFY( u == v );
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff -durpN a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc	1969-12-31 19:00:00.000000000 -0500
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc	2014-04-15 23:00:48.489580407 -0400
@@ -0,0 +1,43 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2014-04-15  Ulrich Drepper  <drepper@gmail.com>
+//
+// Copyright (C) 2014 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.5.8.4.5 Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+
+#include <ext/random>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test [[gnu::unused]] = true;
+
+  __gnu_cxx::uniform_on_sphere_distribution<3> u, v;
+
+  VERIFY( !(u != v) );
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff -durpN a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc	1969-12-31 19:00:00.000000000 -0500
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc	2014-04-15 23:11:10.041160516 -0400
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2014-04-15  Ulrich Drepper  <drepper@gmail.com>
+//
+// Copyright (C) 2014 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test [[gnu::unused]] = true;
+
+  std::stringstream str;
+  __gnu_cxx::uniform_on_sphere_distribution<3> u, v;
+  std::minstd_rand0 rng;
+
+  u(rng); // advance
+  str << u;
+
+  str >> v;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
diff -durpN a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/values.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/values.cc
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/values.cc	1969-12-31 19:00:00.000000000 -0500
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/values.cc	2014-04-15 23:13:17.911686481 -0400
@@ -0,0 +1,59 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+// { dg-require-cmath "" }
+//
+// 2014-04-15  Ulrich Drepper  <drepper@gmail.com>
+//
+// Copyright (C) 2014 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.8.3.* Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <functional>
+#include <testsuite_random.h>
+
+void
+test01()
+{
+  using namespace __gnu_test;
+
+  std::mt19937 eng;
+
+  __gnu_cxx::hypergeometric_distribution<> hd1{15, 3, 2};
+  auto bhd1 = std::bind(hd1, eng);
+  testDiscreteDist(bhd1, [](int k)
+		   { return hypergeometric_pdf(k, 15, 3, 2); });
+
+  __gnu_cxx::hypergeometric_distribution<> hd2{500, 50, 30};
+  auto bhd2 = std::bind(hd2, eng);
+  testDiscreteDist(bhd2, [](int k)
+		   { return hypergeometric_pdf(k, 500, 50, 30); });
+
+  __gnu_cxx::hypergeometric_distribution<> hd3{100, 20, 5};
+  auto bhd3 = std::bind(hd3, eng);
+  testDiscreteDist(bhd3, [](int k)
+		   { return hypergeometric_pdf(k, 100, 20, 5); });
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13  2:01 [PATCH] libstdc++: add uniform on sphere distribution Ulrich Drepper
@ 2014-07-13  2:06 ` Ulrich Drepper
  2014-07-13  9:28 ` Paolo Carlini
  2014-07-23 10:05 ` Marc Glisse
  2 siblings, 0 replies; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13  2:06 UTC (permalink / raw)
  To: GCC Patches

On Sat, Jul 12, 2014 at 10:00 PM, Ulrich Drepper <drepper@gmail.com> wrote:
> The patch is tested against the current tree without causing additional
> problems.
>
> OK?

Ignore the values.cc test case, it's a left-over from copying existing
tests and modifying them for a new distribution.  This test does not
apply to the new distribution and therefore the entire file is gone.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13  2:01 [PATCH] libstdc++: add uniform on sphere distribution Ulrich Drepper
  2014-07-13  2:06 ` Ulrich Drepper
@ 2014-07-13  9:28 ` Paolo Carlini
  2014-07-13 10:04   ` Ulrich Drepper
  2014-07-23 10:05 ` Marc Glisse
  2 siblings, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-07-13  9:28 UTC (permalink / raw)
  To: Ulrich Drepper, gcc-patches

Hi,

On 07/13/2014 04:00 AM, Ulrich Drepper wrote:
> +  template<std::size_t _Dimen, typename _RealType, typename _CharT,
> +	   typename _Traits>
> +    std::basic_ostream<_CharT, _Traits>&
> +    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
> +	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
> +							       _RealType>& __x)
> +    {
> +      return __os;
> +    }
> +
> +  template<std::size_t _Dimen, typename _RealType, typename _CharT,
> +	   typename _Traits>
> +    std::basic_istream<_CharT, _Traits>&
> +    operator>>(std::basic_istream<_CharT, _Traits>& __is,
> +	       __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
> +							 _RealType>& __x)
> +    {
> +      return __is;
> +    }
are these dummy implementations intended?

Thanks,
Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13  9:28 ` Paolo Carlini
@ 2014-07-13 10:04   ` Ulrich Drepper
  2014-07-13 10:40     ` Paolo Carlini
  0 siblings, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13 10:04 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: GCC Patches

On Sun, Jul 13, 2014 at 5:24 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> are these dummy implementations intended?

Yes.  There is no state.  The only parameter is the dimensionality
which is a template parameter.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 10:04   ` Ulrich Drepper
@ 2014-07-13 10:40     ` Paolo Carlini
  0 siblings, 0 replies; 41+ messages in thread
From: Paolo Carlini @ 2014-07-13 10:40 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: GCC Patches

Hi,

On 07/13/2014 12:04 PM, Ulrich Drepper wrote:
> On Sun, Jul 13, 2014 at 5:24 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
>> are these dummy implementations intended?
> Yes.  There is no state.  The only parameter is the dimensionality
> which is a template parameter.
Ah, interesting, didn't look close enough, sorry. Maybe add a one line 
comment in the bodies? Patch is Ok.

Thanks!
Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13  2:01 [PATCH] libstdc++: add uniform on sphere distribution Ulrich Drepper
  2014-07-13  2:06 ` Ulrich Drepper
  2014-07-13  9:28 ` Paolo Carlini
@ 2014-07-23 10:05 ` Marc Glisse
  2014-07-23 10:44   ` Jonathan Wakely
  2 siblings, 1 reply; 41+ messages in thread
From: Marc Glisse @ 2014-07-23 10:05 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: gcc-patches, libstdc++

On Sat, 12 Jul 2014, Ulrich Drepper wrote:

> Ed's submission of the logistic regression distribution caused problems
> for me because, like Ed, I have changes to the <ext/random> header in my
> tree for a long time.  Time to submit them.
>
> This first one is a new distribution.  It generates coordinates for
> random points on a unit sphere in arbitrarily many dimensions.  This
> distribution by itself is useful but if I get some other code fully
> implemented it will also form the basis for yet another, more
> sophisticated distribution.

Hello,

I have 2 questions :

* can't we end up dividing by 0 if all values of the normal distribution 
happen to be 0?

* should the implementation be specialized for small dimensions to avoid 
the normal distributions and instead generate points in a square/cube 
until they fall in the disk/ball?

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-23 10:05 ` Marc Glisse
@ 2014-07-23 10:44   ` Jonathan Wakely
  2014-07-24 22:14     ` Ulrich Drepper
  2014-08-08 23:24     ` Ulrich Drepper
  0 siblings, 2 replies; 41+ messages in thread
From: Jonathan Wakely @ 2014-07-23 10:44 UTC (permalink / raw)
  To: libstdc++; +Cc: Ulrich Drepper, gcc-patches

On 23/07/14 11:58 +0200, Marc Glisse wrote:
>* can't we end up dividing by 0 if all values of the normal 
>distribution happen to be 0?

As an aside, we already have divide-by-zero bugs in <ext/random>, it
would be nice if someone could look at that.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60037

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-23 10:44   ` Jonathan Wakely
@ 2014-07-24 22:14     ` Ulrich Drepper
  2014-07-24 23:19       ` Jonathan Wakely
  2014-08-08 23:24     ` Ulrich Drepper
  1 sibling, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-24 22:14 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, GCC Patches

On Wed, Jul 23, 2014 at 6:29 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> As an aside, we already have divide-by-zero bugs in <ext/random>, it
> would be nice if someone could look at that.

I'll take a look at this soon.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-24 22:14     ` Ulrich Drepper
@ 2014-07-24 23:19       ` Jonathan Wakely
  0 siblings, 0 replies; 41+ messages in thread
From: Jonathan Wakely @ 2014-07-24 23:19 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Jonathan Wakely, libstdc++, GCC Patches

On 24 July 2014 22:15, Ulrich Drepper wrote:
> On Wed, Jul 23, 2014 at 6:29 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>> As an aside, we already have divide-by-zero bugs in <ext/random>, it
>> would be nice if someone could look at that.
>
> I'll take a look at this soon.

That would be great, thanks!

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-23 10:44   ` Jonathan Wakely
  2014-07-24 22:14     ` Ulrich Drepper
@ 2014-08-08 23:24     ` Ulrich Drepper
  2014-08-09  7:15       ` Marc Glisse
  1 sibling, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-08-08 23:24 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

Jonathan Wakely <jwakely@redhat.com> writes:

> On 23/07/14 11:58 +0200, Marc Glisse wrote:
> As an aside, we already have divide-by-zero bugs in <ext/random>, it
> would be nice if someone could look at that.
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60037

Sorry, it took a while to get back to tihs and now the referenced bug is
already fixed.  Good.  Now also for a fix of the sphere distribution.
Unless someone objects I'll check in the patch below.


2014-08-08  Ulrich Drepper  <drepper@gmail.com>

	* include/ext/random.tcc
	(uniform_on_sphere_distribution::__generate_impl): Reject
	vectors with norm zero.


diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 05361d8..d1f0b9c 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -1548,13 +1548,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		 const param_type& __p)
       {
 	result_type __ret;
-	_RealType __sum = _RealType(0);
+	_RealType __norm;
+
+	do
+	  {
+	    _RealType __sum = _RealType(0);
+
+	    std::generate(__ret.begin(), __ret.end(),
+		          [&__urng, &__sum, this](){
+			    _RealType __t = _M_nd(__urng);
+			    __sum += __t * __t;
+			    return __t; });
+	    __norm = std::sqrt(__sum);
+	  }
+	while (__norm == _RealType(0));
 
-	std::generate(__ret.begin(), __ret.end(),
-		      [&__urng, &__sum, this](){ _RealType __t = _M_nd(__urng);
-						 __sum += __t * __t;
-						 return __t; });
-	auto __norm = std::sqrt(__sum);
 	std::transform(__ret.begin(), __ret.end(), __ret.begin(),
 		       [__norm](_RealType __val){ return __val / __norm; });
 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-08 23:24     ` Ulrich Drepper
@ 2014-08-09  7:15       ` Marc Glisse
  2014-08-09 11:55         ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Glisse @ 2014-08-09  7:15 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Fri, 8 Aug 2014, Ulrich Drepper wrote:

> Now also for a fix of the sphere distribution. Unless someone objects 
> I'll check in the patch below.
>
>
> 2014-08-08  Ulrich Drepper  <drepper@gmail.com>
>
> 	* include/ext/random.tcc
> 	(uniform_on_sphere_distribution::__generate_impl): Reject
> 	vectors with norm zero.

While there, do we want to also reject infinite norms?
I would have done: while (__sum < small || __sum > large)
but testing exactly for 0 and infinity seems good enough.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09  7:15       ` Marc Glisse
@ 2014-08-09 11:55         ` Ulrich Drepper
  2014-08-09 12:34           ` Marc Glisse
  0 siblings, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-08-09 11:55 UTC (permalink / raw)
  To: libstdc++; +Cc: Jonathan Wakely, GCC Patches

On Sat, Aug 9, 2014 at 3:15 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> While there, do we want to also reject infinite norms?
> I would have done: while (__sum < small || __sum > large)
> but testing exactly for 0 and infinity seems good enough.

I guess the squaring can theoretically overflow and produce infinity.
It will never happen with the way we generate normally distributed
numbers, though.  These values are always so unlikely that it is OK
that the algorithms cannot return them.  If you insist I'll add a test
for infinity.

The other change (which would eliminate the necessity for this test in
a special case) is to use hypot for _Dimen==2.  This might be a case
common enough to warrant that little bit of extra text.  I'll prepare
a patch.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 11:55         ` Ulrich Drepper
@ 2014-08-09 12:34           ` Marc Glisse
  2014-08-09 15:24             ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Glisse @ 2014-08-09 12:34 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

On Sat, 9 Aug 2014, Ulrich Drepper wrote:

> On Sat, Aug 9, 2014 at 3:15 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
>> While there, do we want to also reject infinite norms?
>> I would have done: while (__sum < small || __sum > large)
>> but testing exactly for 0 and infinity seems good enough.
>
> I guess the squaring can theoretically overflow and produce infinity.
> It will never happen with the way we generate normally distributed
> numbers, though.  These values are always so unlikely that it is OK
> that the algorithms cannot return them.  If you insist I'll add a test
> for infinity.

Oh, a comment saying exactly what you just said would be fine with me (or 
even nothing).

> The other change (which would eliminate the necessity for this test in
> a special case) is to use hypot for _Dimen==2.  This might be a case
> common enough to warrant that little bit of extra text.  I'll prepare
> a patch.

If you are going to specialize for dim 2, I imagine you won't be computing 
normal distributions, you will only generate a point uniformy in a square 
and reject it if it is not in the ball? (interestingly enough this is used 
as a subroutine by the implementation of normal_distribution)

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 12:34           ` Marc Glisse
@ 2014-08-09 15:24             ` Ulrich Drepper
  2014-08-09 15:33               ` Marc Glisse
  0 siblings, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-08-09 15:24 UTC (permalink / raw)
  To: libstdc++; +Cc: Jonathan Wakely, GCC Patches

On Sat, Aug 9, 2014 at 8:34 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Oh, a comment saying exactly what you just said would be fine with me (or
> even nothing).

We might at some point use a different method than Box-Muller sampling
so I'm OK with the test.


> If you are going to specialize for dim 2, I imagine you won't be computing
> normal distributions, you will only generate a point uniformy in a square
> and reject it if it is not in the ball? (interestingly enough this is used
> as a subroutine by the implementation of normal_distribution)

We need to be *on* the circle, not inside.  We'll still have to follow
the algorithm unless I miss something.  With reasonable probability we
cannot generate those numbers directly from a uniform source. What is
optimized is just the norm computation.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 15:24             ` Ulrich Drepper
@ 2014-08-09 15:33               ` Marc Glisse
  2014-08-09 16:55                 ` Ed Smith-Rowland
  2014-08-09 16:56                 ` Ulrich Drepper
  0 siblings, 2 replies; 41+ messages in thread
From: Marc Glisse @ 2014-08-09 15:33 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

On Sat, 9 Aug 2014, Ulrich Drepper wrote:

>> If you are going to specialize for dim 2, I imagine you won't be computing
>> normal distributions, you will only generate a point uniformy in a square
>> and reject it if it is not in the ball? (interestingly enough this is used
>> as a subroutine by the implementation of normal_distribution)
>
> We need to be *on* the circle, not inside.

Yes, you still need the normalization step (divide by the norm). It works 
whether you start from a uniform distribution in the disk or from a 
Gaussian in the plane, but the first one is easier to generate (generate 
points in a square until you get one in the disk). When the dimension 
becomes higher, the probability that a point in the cube actually belongs 
to the ball decreases, and it becomes cheaper to use a Gaussian.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 15:33               ` Marc Glisse
@ 2014-08-09 16:55                 ` Ed Smith-Rowland
  2014-08-09 16:56                 ` Ulrich Drepper
  1 sibling, 0 replies; 41+ messages in thread
From: Ed Smith-Rowland @ 2014-08-09 16:55 UTC (permalink / raw)
  To: libstdc++, Ulrich Drepper; +Cc: Jonathan Wakely, GCC Patches

On 08/09/2014 11:33 AM, Marc Glisse wrote:
> On Sat, 9 Aug 2014, Ulrich Drepper wrote:
>
>>> If you are going to specialize for dim 2, I imagine you won't be 
>>> computing
>>> normal distributions, you will only generate a point uniformy in a 
>>> square
>>> and reject it if it is not in the ball? (interestingly enough this 
>>> is used
>>> as a subroutine by the implementation of normal_distribution)
>>
>> We need to be *on* the circle, not inside.
>
> Yes, you still need the normalization step (divide by the norm). It 
> works whether you start from a uniform distribution in the disk or 
> from a Gaussian in the plane, but the first one is easier to generate 
> (generate points in a square until you get one in the disk). When the 
> dimension becomes higher, the probability that a point in the cube 
> actually belongs to the ball decreases, and it becomes cheaper to use 
> a Gaussian.
>
If we pull in the implementation of normal you will just be able to use 
the two values that normal computes on the first, (and third, ...) calls 
without doing two calls.  That and hypot would be a real win.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 15:33               ` Marc Glisse
  2014-08-09 16:55                 ` Ed Smith-Rowland
@ 2014-08-09 16:56                 ` Ulrich Drepper
  2014-08-09 17:40                   ` Marc Glisse
  1 sibling, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-08-09 16:56 UTC (permalink / raw)
  To: libstdc++; +Cc: Jonathan Wakely, GCC Patches

Marc Glisse <marc.glisse@inria.fr> writes:

> On Sat, 9 Aug 2014, Ulrich Drepper wrote:
> Yes, you still need the normalization step (divide by the norm).

I guess we can do this.

How about the patch below?  Instead of specializing the entire class for
_Dimen==2 I've added a class at the implementation level.

I've also improved existing tests and add some new ones.


2014-08-09  Ulrich Drepper  <drepper@gmail.com>

	* include/ext/random.tcc (uniform_on_sphere_helper): Define.
	(uniform_on_sphere_distribution::operator()): Use the new helper
	class for the implementation.

	* testsuite/ext/random/uniform_on_sphere_distribution/operators/
	equal.cc: Remove bogus part of comment.
	* testsuite/ext/random/uniform_on_sphere_distribution/operators/
	inequal.cc: Likewise.
	* testsuite/ext/random/uniform_on_sphere_distribution/operators/
	serialize.cc: Add check to verify result of serialzation and
	deserialization.
	* testsuite/ext/random/uniform_on_sphere_distribution/operators/
	generate.cc: New file.


diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 05361d8..d536ecb 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -1540,6 +1540,83 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 
+  namespace {
+
+    // Helper class for the uniform_on_sphere_distribution generation
+    // function.
+    template<std::size_t _Dimen, typename _RealType>
+      class uniform_on_sphere_helper
+      {
+	typedef typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type result_type;
+
+      public:
+	template<typename _NormalDistribution, typename _UniformRandomNumberGenerator>
+	result_type operator()(_NormalDistribution& __nd,
+			       _UniformRandomNumberGenerator& __urng)
+        {
+	  result_type __ret;
+	  typename result_type::value_type __norm;
+
+	  do
+	    {
+	      auto __sum = _RealType(0);
+
+	      std::generate(__ret.begin(), __ret.end(),
+			    [&__nd, &__urng, &__sum](){
+			      _RealType __t = __nd(__urng);
+			      __sum += __t * __t;
+			      return __t; });
+	      __norm = std::sqrt(__sum);
+	    }
+	  while (__norm == _RealType(0) || ! std::isfinite(__norm));
+
+	  std::transform(__ret.begin(), __ret.end(), __ret.begin(),
+			 [__norm](_RealType __val){ return __val / __norm; });
+
+	  return __ret;
+        }
+      };
+
+
+    template<typename _RealType>
+      class uniform_on_sphere_helper<2, _RealType>
+      {
+	typedef typename uniform_on_sphere_distribution<2, _RealType>::
+	  result_type result_type;
+
+      public:
+	template<typename _NormalDistribution,
+		 typename _UniformRandomNumberGenerator>
+	result_type operator()(_NormalDistribution&,
+			       _UniformRandomNumberGenerator& __urng)
+        {
+	  result_type __ret;
+	  _RealType __sq;
+	  std::__detail::_Adaptor<_UniformRandomNumberGenerator,
+				  _RealType> __aurng(__urng);
+
+	  do
+	    {
+	      __ret[0] = __aurng();
+	      __ret[1] = __aurng();
+
+	      __sq = __ret[0] * __ret[0] + __ret[1] * __ret[1];
+	    }
+	  while (__sq == _RealType(0) || __sq > _RealType(1));
+
+	  // Yes, we do not just use sqrt(__sq) because hypot() is more
+	  // accurate.
+	  auto __norm = std::hypot(__ret[0], __ret[1]);
+	  __ret[0] /= __norm;
+	  __ret[1] /= __norm;
+
+	  return __ret;
+        }
+      };
+
+  }
+
+
   template<std::size_t _Dimen, typename _RealType>
     template<typename _UniformRandomNumberGenerator>
       typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type
@@ -1547,18 +1624,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(_UniformRandomNumberGenerator& __urng,
 		 const param_type& __p)
       {
-	result_type __ret;
-	_RealType __sum = _RealType(0);
-
-	std::generate(__ret.begin(), __ret.end(),
-		      [&__urng, &__sum, this](){ _RealType __t = _M_nd(__urng);
-						 __sum += __t * __t;
-						 return __t; });
-	auto __norm = std::sqrt(__sum);
-	std::transform(__ret.begin(), __ret.end(), __ret.begin(),
-		       [__norm](_RealType __val){ return __val / __norm; });
-
-	return __ret;
+        uniform_on_sphere_helper<_Dimen, _RealType> __helper;
+        return __helper(_M_nd, __urng);
       }
 
   template<std::size_t _Dimen, typename _RealType>
diff --git a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc
index 35a024e..f5b8d17 100644
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc
@@ -20,7 +20,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 26.5.8.4.5 Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+// Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
 
 #include <ext/random>
 #include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc
index 9f8e8c8..2675652 100644
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc
@@ -20,7 +20,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 26.5.8.4.5 Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+// Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
 
 #include <ext/random>
 #include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc
index 80264ff..e9a758c 100644
--- a/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc
@@ -20,8 +20,8 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// 26.4.8.3.* Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
-// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
+// Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+// Concept RandomNumberDistribution [rand.concept.dist]
 
 #include <ext/random>
 #include <sstream>
@@ -40,6 +40,8 @@ test01()
   str << u;
 
   str >> v;
+
+  VERIFY( u == v );
 }
 
 int
--- /dev/null	2014-07-15 08:50:39.432896277 -0400
+++ b/libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/generate.cc	2014-08-09 08:07:29.787244291 -0400
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// 2014-08-09  Ulrich Drepper  <drepper@gmail.com>
+//
+// Copyright (C) 2014 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template uniform_on_sphere_distribution [rand.dist.ext.uniform_on_sphere]
+// Concept RandomNumberDistribution [rand.concept.dist]
+
+#include <ext/random>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test [[gnu::unused]] = true;
+  std::minstd_rand0 rng;
+
+  __gnu_cxx::uniform_on_sphere_distribution<3> u3;
+
+  for (size_t n = 0; n < 1000; ++n)
+    {
+      auto r = u3(rng);
+
+      VERIFY (r[0] != 0.0 || r[1] != 0.0 || r[2] != 0.0);
+    }
+
+  __gnu_cxx::uniform_on_sphere_distribution<2> u2;
+
+  for (size_t n = 0; n < 1000; ++n)
+    {
+      auto r = u2(rng);
+
+      VERIFY (r[0] != 0.0 || r[1] != 0.0);
+    }
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 16:56                 ` Ulrich Drepper
@ 2014-08-09 17:40                   ` Marc Glisse
  2014-08-09 18:00                     ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Glisse @ 2014-08-09 17:40 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

On Sat, 9 Aug 2014, Ulrich Drepper wrote:

> How about the patch below?

Looks good, with two details:

> +    template<typename _RealType>
> +      class uniform_on_sphere_helper<2, _RealType>
> +      {
> +	typedef typename uniform_on_sphere_distribution<2, _RealType>::
> +	  result_type result_type;
> +
> +      public:
> +	template<typename _NormalDistribution,
> +		 typename _UniformRandomNumberGenerator>
> +	result_type operator()(_NormalDistribution&,
> +			       _UniformRandomNumberGenerator& __urng)
> +        {
> +	  result_type __ret;
> +	  _RealType __sq;
> +	  std::__detail::_Adaptor<_UniformRandomNumberGenerator,
> +				  _RealType> __aurng(__urng);
> +
> +	  do
> +	    {
> +	      __ret[0] = __aurng();

I must be missing something obvious, but normal_distribution uses:

                 __x = result_type(2.0) * __aurng() - 1.0;

to get a number between -1 and 1, and I don't see where you do this
rescaling. Does __aurng() already return a number in the right interval in 
this context? If so we may want to update our naming of variables to make 
that clearer.

> +	      __ret[1] = __aurng();
> +
> +	      __sq = __ret[0] * __ret[0] + __ret[1] * __ret[1];
> +	    }
> +	  while (__sq == _RealType(0) || __sq > _RealType(1));
> +
> +	  // Yes, we do not just use sqrt(__sq) because hypot() is more
> +	  // accurate.
> +	  auto __norm = std::hypot(__ret[0], __ret[1]);

Assuming the 2 coordinates are obtained through a rescaling x->2*x-1, if
__sq is not exactly 0, it must be between 2^-103 and 1 (for ieee
double), so I am not sure hypot gains that much (at least in my mind
hypot was mostly a gain close to 0 or infinity, but maybe it has more
advantages). It can only hurt speed though, so not a big issue.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 17:40                   ` Marc Glisse
@ 2014-08-09 18:00                     ` Ulrich Drepper
  2014-08-13  7:36                       ` Bin.Cheng
  0 siblings, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-08-09 18:00 UTC (permalink / raw)
  To: libstdc++; +Cc: Jonathan Wakely, GCC Patches

On Sat, Aug 9, 2014 at 1:40 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>                 __x = result_type(2.0) * __aurng() - 1.0;

You're right, we of course need the negatives as well.

> Assuming the 2 coordinates are obtained through a rescaling x->2*x-1, if
> __sq is not exactly 0, it must be between 2^-103 and 1 (for ieee
> double), so I am not sure hypot gains that much (at least in my mind
> hypot was mostly a gain close to 0 or infinity, but maybe it has more
> advantages). It can only hurt speed though, so not a big issue.

Depending on how similar in size the two values are, not using hypot()
can drop quite a few bits.  Especially with the scaling through
division this error can be noticeable.  Better be sure.  Maybe at some
point I have time to investigate the worst case scenario for the
numbers in question but until this shows hypot isn't needed it's best
to leave it in.

I've committed the patch.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-09 18:00                     ` Ulrich Drepper
@ 2014-08-13  7:36                       ` Bin.Cheng
  2014-08-13  7:43                         ` Bin.Cheng
  2014-08-13  8:41                         ` Paolo Carlini
  0 siblings, 2 replies; 41+ messages in thread
From: Bin.Cheng @ 2014-08-13  7:36 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

On Sun, Aug 10, 2014 at 2:00 AM, Ulrich Drepper <drepper@gmail.com> wrote:
> On Sat, Aug 9, 2014 at 1:40 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>>                 __x = result_type(2.0) * __aurng() - 1.0;
>
> You're right, we of course need the negatives as well.
>
>> Assuming the 2 coordinates are obtained through a rescaling x->2*x-1, if
>> __sq is not exactly 0, it must be between 2^-103 and 1 (for ieee
>> double), so I am not sure hypot gains that much (at least in my mind
>> hypot was mostly a gain close to 0 or infinity, but maybe it has more
>> advantages). It can only hurt speed though, so not a big issue.
>
> Depending on how similar in size the two values are, not using hypot()
> can drop quite a few bits.  Especially with the scaling through
> division this error can be noticeable.  Better be sure.  Maybe at some
> point I have time to investigate the worst case scenario for the
> numbers in question but until this shows hypot isn't needed it's best
> to leave it in.
>
> I've committed the patch.

Hi,

This causes lots of tests under libstdc++-v3/testsuite/ext/ failed on
aarch64-none-elf and arm-none-eabi with below log message.

In file included from
/home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/ext/random:3494:0,
                 from
/home/binche01/work/oban-work/src/gcc/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc:23:
/home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:
In member function
'__gnu_cxx::{anonymous}::uniform_on_sphere_helper<2ul,
_RealType>::result_type
__gnu_cxx::{anonymous}::uniform_on_sphere_helper<2ul,
_RealType>::operator()(_NormalDistribution&,
_UniformRandomNumberGenerator&)':
/home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:1609:18:
error: 'hypot' is not a member of 'std'
    auto __norm = std::hypot(__ret[0], __ret[1]);
                  ^
/home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:1609:18:
note: suggested alternative:
In file included from
/home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/cmath:44:0,
                 from
/home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/random:38,
                 from
/home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/ext/random:38,
                 from
/home/binche01/work/oban-work/src/gcc/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc:23:
/home/binche01/work/oban-work/target-aarch64-none-elf/aarch64-none-elf/include/math.h:306:15:
note:   'hypot'
 extern double hypot _PARAMS((double, double));
               ^

FAIL: ext/random/arcsine_distribution/cons/default.cc (test for excess errors)
Excess errors:
/home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:1609:18:
error: 'hypot' is not a member of 'std'

Thanks,
bin

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-13  7:36                       ` Bin.Cheng
@ 2014-08-13  7:43                         ` Bin.Cheng
  2014-08-13  8:41                         ` Paolo Carlini
  1 sibling, 0 replies; 41+ messages in thread
From: Bin.Cheng @ 2014-08-13  7:43 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

On Wed, Aug 13, 2014 at 3:36 PM, Bin.Cheng <amker.cheng@gmail.com> wrote:
> On Sun, Aug 10, 2014 at 2:00 AM, Ulrich Drepper <drepper@gmail.com> wrote:
>> On Sat, Aug 9, 2014 at 1:40 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>>>                 __x = result_type(2.0) * __aurng() - 1.0;
>>
>> You're right, we of course need the negatives as well.
>>
>>> Assuming the 2 coordinates are obtained through a rescaling x->2*x-1, if
>>> __sq is not exactly 0, it must be between 2^-103 and 1 (for ieee
>>> double), so I am not sure hypot gains that much (at least in my mind
>>> hypot was mostly a gain close to 0 or infinity, but maybe it has more
>>> advantages). It can only hurt speed though, so not a big issue.
>>
>> Depending on how similar in size the two values are, not using hypot()
>> can drop quite a few bits.  Especially with the scaling through
>> division this error can be noticeable.  Better be sure.  Maybe at some
>> point I have time to investigate the worst case scenario for the
>> numbers in question but until this shows hypot isn't needed it's best
>> to leave it in.
>>
>> I've committed the patch.
>
> Hi,
>
> This causes lots of tests under libstdc++-v3/testsuite/ext/ failed on
> aarch64-none-elf and arm-none-eabi with below log message.
>
> In file included from
> /home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/ext/random:3494:0,
>                  from
> /home/binche01/work/oban-work/src/gcc/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc:23:
> /home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:
> In member function
> '__gnu_cxx::{anonymous}::uniform_on_sphere_helper<2ul,
> _RealType>::result_type
> __gnu_cxx::{anonymous}::uniform_on_sphere_helper<2ul,
> _RealType>::operator()(_NormalDistribution&,
> _UniformRandomNumberGenerator&)':
> /home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:1609:18:
> error: 'hypot' is not a member of 'std'
>     auto __norm = std::hypot(__ret[0], __ret[1]);
>                   ^
> /home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:1609:18:
> note: suggested alternative:
> In file included from
> /home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/cmath:44:0,
>                  from
> /home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/random:38,
>                  from
> /home/binche01/work/oban-work/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/ext/random:38,
>                  from
> /home/binche01/work/oban-work/src/gcc/libstdc++-v3/testsuite/ext/random/arcsine_distribution/cons/default.cc:23:
> /home/binche01/work/oban-work/target-aarch64-none-elf/aarch64-none-elf/include/math.h:306:15:
> note:   'hypot'
>  extern double hypot _PARAMS((double, double));
>                ^
>
> FAIL: ext/random/arcsine_distribution/cons/default.cc (test for excess errors)
> Excess errors:
> /home/binche01/work/oban-work/src/gcc/libstdc++-v3/include/ext/random.tcc:1609:18:
> error: 'hypot' is not a member of 'std'
>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62118 filed.

Thanks,
bin

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-13  7:36                       ` Bin.Cheng
  2014-08-13  7:43                         ` Bin.Cheng
@ 2014-08-13  8:41                         ` Paolo Carlini
  2014-08-13 11:25                           ` Paolo Carlini
  1 sibling, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-08-13  8:41 UTC (permalink / raw)
  To: Bin.Cheng, Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

Ulrich--

On 08/13/2014 09:36 AM, Bin.Cheng wrote:
> On Sun, Aug 10, 2014 at 2:00 AM, Ulrich Drepper <drepper@gmail.com> wrote:
>> On Sat, Aug 9, 2014 at 1:40 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>>>                  __x = result_type(2.0) * __aurng() - 1.0;
>> You're right, we of course need the negatives as well.
>>
>>> Assuming the 2 coordinates are obtained through a rescaling x->2*x-1, if
>>> __sq is not exactly 0, it must be between 2^-103 and 1 (for ieee
>>> double), so I am not sure hypot gains that much (at least in my mind
>>> hypot was mostly a gain close to 0 or infinity, but maybe it has more
>>> advantages). It can only hurt speed though, so not a big issue.
>> Depending on how similar in size the two values are, not using hypot()
>> can drop quite a few bits.  Especially with the scaling through
>> division this error can be noticeable.  Better be sure.  Maybe at some
>> point I have time to investigate the worst case scenario for the
>> numbers in question but until this shows hypot isn't needed it's best
>> to leave it in.
>>
>> I've committed the patch.
> Hi,
>
> This causes lots of tests under libstdc++-v3/testsuite/ext/ failed on
> aarch64-none-elf and arm-none-eabi with below log message.
Please follow our usual rules, don't unconditionally use C99 functions 
like std::hypot,  use _GLIBCXX_USE_C99_MATH_TR1 (many examples, eg in 
random.tcc).

Thanks!
Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-13  8:41                         ` Paolo Carlini
@ 2014-08-13 11:25                           ` Paolo Carlini
  2014-08-13 11:32                             ` Marc Glisse
  0 siblings, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-08-13 11:25 UTC (permalink / raw)
  To: Bin.Cheng, Ulrich Drepper; +Cc: libstdc++, Jonathan Wakely, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 66 bytes --]

... fixed with the below.

Thanks,
Paolo.

//////////////////////

[-- Attachment #2: CL_62118 --]
[-- Type: text/plain, Size: 209 bytes --]

2014-08-13  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/62118
	* include/ext/random.tcc (uniform_on_sphere_helper<2, _RealType>::
	operator()): Use std::hypot only when _GLIBCXX_USE_C99_MATH_TR1.

[-- Attachment #3: patch_62118 --]
[-- Type: text/plain, Size: 1192 bytes --]

Index: include/ext/random.tcc
===================================================================
--- include/ext/random.tcc	(revision 213898)
+++ include/ext/random.tcc	(working copy)
@@ -1547,10 +1547,12 @@
     template<std::size_t _Dimen, typename _RealType>
       class uniform_on_sphere_helper
       {
-	typedef typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type result_type;
+	typedef typename uniform_on_sphere_distribution<_Dimen, _RealType>::
+	  result_type result_type;
 
       public:
-	template<typename _NormalDistribution, typename _UniformRandomNumberGenerator>
+	template<typename _NormalDistribution,
+		 typename _UniformRandomNumberGenerator>
 	result_type operator()(_NormalDistribution& __nd,
 			       _UniformRandomNumberGenerator& __urng)
         {
@@ -1604,9 +1606,13 @@
 	    }
 	  while (__sq == _RealType(0) || __sq > _RealType(1));
 
+#if _GLIBCXX_USE_C99_MATH_TR1
 	  // Yes, we do not just use sqrt(__sq) because hypot() is more
 	  // accurate.
 	  auto __norm = std::hypot(__ret[0], __ret[1]);
+#else
+	  auto __norm = std::sqrt(__ret[0] * __ret[0] + __ret[1] * __ret[1]);
+#endif
 	  __ret[0] /= __norm;
 	  __ret[1] /= __norm;
 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-13 11:25                           ` Paolo Carlini
@ 2014-08-13 11:32                             ` Marc Glisse
  2014-08-13 11:40                               ` Paolo Carlini
  0 siblings, 1 reply; 41+ messages in thread
From: Marc Glisse @ 2014-08-13 11:32 UTC (permalink / raw)
  To: Paolo Carlini
  Cc: Bin.Cheng, Ulrich Drepper, libstdc++, Jonathan Wakely, GCC Patches

On Wed, 13 Aug 2014, Paolo Carlini wrote:

> ... fixed with the below.

Could you please use __sq instead of recomputing it?

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-08-13 11:32                             ` Marc Glisse
@ 2014-08-13 11:40                               ` Paolo Carlini
  0 siblings, 0 replies; 41+ messages in thread
From: Paolo Carlini @ 2014-08-13 11:40 UTC (permalink / raw)
  To: libstdc++; +Cc: Bin.Cheng, Ulrich Drepper, Jonathan Wakely, GCC Patches

On 08/13/2014 01:32 PM, Marc Glisse wrote:
> On Wed, 13 Aug 2014, Paolo Carlini wrote:
>
>> ... fixed with the below.
>
> Could you please use __sq instead of recomputing it?
>
Patch preapproved, thanks!

Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-16 15:03                     ` Paolo Carlini
@ 2014-07-16 17:38                       ` Ulrich Drepper
  0 siblings, 0 replies; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-16 17:38 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Ed Smith-Rowland, Andreas Schwab, gcc-patches

On Wed, Jul 16, 2014 at 11:01 AM, Paolo Carlini
<paolo.carlini@oracle.com> wrote:
> Right. And reset too. I'm going to test and apply the below.

Sorry for not reacting to this, I was away from the machines I could
have done that work on.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-16 11:30                   ` Ed Smith-Rowland
@ 2014-07-16 15:03                     ` Paolo Carlini
  2014-07-16 17:38                       ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-07-16 15:03 UTC (permalink / raw)
  To: Ed Smith-Rowland, Andreas Schwab, Ulrich Drepper; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 254 bytes --]

Hi,

On 07/16/2014 01:05 PM, Ed Smith-Rowland wrote:
> One thing we all forgot: the operator== is also non-trivial because it 
> needs to compare _M_n.
Right. And reset too. I'm going to test and apply the below.

Thanks,
Paolo.

///////////////////////

[-- Attachment #2: CL --]
[-- Type: text/plain, Size: 474 bytes --]

2014-07-16  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/ext/random: Minor formatting and cosmetic tweaks.
	(uniform_on_sphere_distribution<>::operator==
	(const uniform_on_sphere_distribution&,
	const uniform_on_sphere_distribution&)): Compare the _M_nds.
	(uniform_on_sphere_distribution<>::reset): Reset _M_nd.
	(operator!=(const uniform_on_sphere_distribution&,
	const uniform_on_sphere_distribution&)): Adjust.
	* include/ext/random.tcc: Minor cosmetc tweaks.

[-- Attachment #3: patchlet --]
[-- Type: text/plain, Size: 4548 bytes --]

Index: include/ext/random
===================================================================
--- include/ext/random	(revision 212581)
+++ include/ext/random	(working copy)
@@ -598,7 +598,7 @@
     inline bool
     operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
 	       const __gnu_cxx::beta_distribution<_RealType>& __d2)
-   { return !(__d1 == __d2); }
+    { return !(__d1 == __d2); }
 
 
   /**
@@ -2575,7 +2575,7 @@
     inline bool
     operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
 	       const __gnu_cxx::triangular_distribution<_RealType>& __d2)
-   { return !(__d1 == __d2); }
+    { return !(__d1 == __d2); }
 
 
   /**
@@ -2810,7 +2810,7 @@
     inline bool
     operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
 	       const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
-   { return !(__d1 == __d2); }
+    { return !(__d1 == __d2); }
 
 
   /**
@@ -3328,12 +3328,12 @@
        */
       explicit
       uniform_on_sphere_distribution()
-      : _M_param(), _M_n(_RealType(0), _RealType(1))
+      : _M_param(), _M_nd()
       { }
 
       explicit
       uniform_on_sphere_distribution(const param_type& __p)
-      : _M_param(__p), _M_n(_RealType(0), _RealType(1))
+      : _M_param(__p), _M_nd()
       { }
 
       /**
@@ -3341,7 +3341,7 @@
        */
       void
       reset()
-      { }
+      { _M_nd.reset(); }
 
       /**
        * @brief Returns the parameter set of the distribution.
@@ -3425,14 +3425,15 @@
       friend bool
       operator==(const uniform_on_sphere_distribution& __d1,
 		 const uniform_on_sphere_distribution& __d2)
-      { return true; }
+      { return __d1._M_nd == __d2._M_nd; }
 
       /**
-       * @brief Inserts a %uniform_on_sphere_distribution random number distribution
-       * @p __x into the output stream @p __os.
+       * @brief Inserts a %uniform_on_sphere_distribution random number
+       *        distribution @p __x into the output stream @p __os.
        *
        * @param __os An output stream.
-       * @param __x  A %uniform_on_sphere_distribution random number distribution.
+       * @param __x  A %uniform_on_sphere_distribution random number
+       *             distribution.
        *
        * @returns The output stream with the state of @p __x inserted or in
        * an error state.
@@ -3446,11 +3447,13 @@
 		   __x);
 
       /**
-       * @brief Extracts a %uniform_on_sphere_distribution random number distribution
+       * @brief Extracts a %uniform_on_sphere_distribution random number
+       *        distribution
        * @p __x from the input stream @p __is.
        *
        * @param __is An input stream.
-       * @param __x  A %uniform_on_sphere_distribution random number generator engine.
+       * @param __x  A %uniform_on_sphere_distribution random number
+       *             generator engine.
        *
        * @returns The input stream with @p __x extracted or in an error state.
        */
@@ -3470,7 +3473,7 @@
 			const param_type& __p);
 
       param_type _M_param;
-      std::normal_distribution<_RealType> _M_n;
+      std::normal_distribution<_RealType> _M_nd;
     };
 
   /**
@@ -3482,7 +3485,7 @@
 	       _RealType>& __d1,
 	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
 	       _RealType>& __d2)
-   { return false; }
+    { return !(__d1 == __d2); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace __gnu_cxx
Index: include/ext/random.tcc
===================================================================
--- include/ext/random.tcc	(revision 212581)
+++ include/ext/random.tcc	(working copy)
@@ -1551,7 +1551,7 @@
 	_RealType __sum = _RealType(0);
 
 	std::generate(__ret.begin(), __ret.end(),
-		      [&__urng, &__sum, this](){ _RealType __t = _M_n(__urng);
+		      [&__urng, &__sum, this](){ _RealType __t = _M_nd(__urng);
 						 __sum += __t * __t;
 						 return __t; });
 	auto __norm = std::sqrt(__sum);
@@ -1583,8 +1583,7 @@
 	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
 							       _RealType>& __x)
     {
-      // The distribution has no state, nothing to save.
-      return __os << __x._M_n;
+      return __os << __x._M_nd;
     }
 
   template<std::size_t _Dimen, typename _RealType, typename _CharT,
@@ -1594,8 +1593,7 @@
 	       __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
 							 _RealType>& __x)
     {
-      // The distribution has no state, nothing to restore.
-      return __is >> __x._M_n;
+      return __is >> __x._M_nd;
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-14  8:18                 ` Paolo Carlini
@ 2014-07-16 11:30                   ` Ed Smith-Rowland
  2014-07-16 15:03                     ` Paolo Carlini
  0 siblings, 1 reply; 41+ messages in thread
From: Ed Smith-Rowland @ 2014-07-16 11:30 UTC (permalink / raw)
  To: Paolo Carlini, Andreas Schwab, Ulrich Drepper; +Cc: gcc-patches

On 07/14/2014 04:14 AM, Paolo Carlini wrote:
> Hi,
>
> On 07/14/2014 09:58 AM, Andreas Schwab wrote:
>> FAIL: ext/random/arcsine_distribution/cons/default.cc (test for 
>> excess errors)
>> Excess errors:
>> /daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1587:22: 
>> error: '_M_n' was not declared in this scope
>> /daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1598:22: 
>> error: '_M_n' was not declared in this scope
> Ulrich please fix those _M_n to __x._M_n and remove the obsolete 
> comments. We could also add the usual minimal set of tests exercising 
> serialization. Thanks.
>
> Paolo.
>

All,

One thing we all forgot: the operator== is also non-trivial because it 
needs to compare _M_n.

Operators must be guaranteed to produce the same numbers in future when 
fed with identical urngs if they compare equal.

Ulrich, do you want to do this?  There are also old comments in the 
inserters and extractors.

Ed

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
@ 2014-07-14 10:31 Dominique Dhumieres
  0 siblings, 0 replies; 41+ messages in thread
From: Dominique Dhumieres @ 2014-07-14 10:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: drepper

> I've checked in a patch to save the _M_n state.

If it is r212496, did you test it?

It breaks many tests (see https://gcc.gnu.org/ml/gcc-regression/2014-07/msg00213.html)

/opt/gcc/work/libstdc++-v3/include/ext/random.tcc: In function 'std::basic_ostream<_CharT, _Traits>& __gnu_cxx::operator<<(std::basic_ostream<_CharT, _Traits>&, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>&)':
/opt/gcc/work/libstdc++-v3/include/ext/random.tcc:1587:22: error: '_M_n' was not declared in this scope
       return __os << _M_n;
                      ^
/opt/gcc/work/libstdc++-v3/include/ext/random.tcc: In function 'std::basic_istream<_CharT, _Traits>& __gnu_cxx::operator>>(std::basic_istream<_CharT, _Traits>&, __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>&)':
/opt/gcc/work/libstdc++-v3/include/ext/random.tcc:1598:22: error: '_M_n' was not declared in this scope
       return __is >> _M_n
                      ^

TIA

Dominique

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-14  7:58               ` Andreas Schwab
@ 2014-07-14  8:18                 ` Paolo Carlini
  2014-07-16 11:30                   ` Ed Smith-Rowland
  0 siblings, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-07-14  8:18 UTC (permalink / raw)
  To: Andreas Schwab, Ulrich Drepper; +Cc: Ed Smith-Rowland, gcc-patches

Hi,

On 07/14/2014 09:58 AM, Andreas Schwab wrote:
> FAIL: ext/random/arcsine_distribution/cons/default.cc (test for excess errors)
> Excess errors:
> /daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1587:22: error: '_M_n' was not declared in this scope
> /daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1598:22: error: '_M_n' was not declared in this scope
Ulrich please fix those _M_n to __x._M_n and remove the obsolete 
comments. We could also add the usual minimal set of tests exercising 
serialization. Thanks.

Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 16:45             ` Ulrich Drepper
  2014-07-13 16:56               ` Paolo Carlini
@ 2014-07-14  7:58               ` Andreas Schwab
  2014-07-14  8:18                 ` Paolo Carlini
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Schwab @ 2014-07-14  7:58 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Paolo Carlini, Ed Smith-Rowland, gcc-patches

FAIL: ext/random/arcsine_distribution/cons/default.cc (test for excess errors)
Excess errors:
/daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1587:22: error: '_M_n' was not declared in this scope
/daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1598:22: error: '_M_n' was not declared in this scope

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 16:45             ` Ulrich Drepper
@ 2014-07-13 16:56               ` Paolo Carlini
  2014-07-14  7:58               ` Andreas Schwab
  1 sibling, 0 replies; 41+ messages in thread
From: Paolo Carlini @ 2014-07-13 16:56 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Ed Smith-Rowland, gcc-patches

Hi,

On 07/13/2014 06:44 PM, Ulrich Drepper wrote:
> But your 4th and 7th call example by itself is not a reason. Again, 
> the input exclusively determined by the random numbers. Here, of 
> course, the 4th and 7th use will produce different results. But this 
> is not what the state of the distribution is supposed to capture. For 
> that you'll have to save the state of the RNG as well.
Yes, you are right. Saving the full state of the distribution solves 
only half of my hypothetical problem, but certainly you have to save it 
if you want to, say, reset the RNGs to a common state and get the same 
sequences of numbers after the os << x and is >> y pair.

Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 16:29           ` Paolo Carlini
@ 2014-07-13 16:45             ` Ulrich Drepper
  2014-07-13 16:56               ` Paolo Carlini
  2014-07-14  7:58               ` Andreas Schwab
  0 siblings, 2 replies; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13 16:45 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Ed Smith-Rowland, gcc-patches

On Sun, Jul 13, 2014 at 12:25 PM, Paolo Carlini
<paolo.carlini@oracle.com> wrote:
> I don't think so. It depends on the past of the two different
> uniform_on_sphere: each time each uniform_on_sphere calls _M_n(__urng) the
> state of *its own* _M_n changes, evolves from the initial state.

I indeed should use the normal_distribution operator<< and operator>>
but I think for a different reason than you think.  The way the
normal_distribution is implemented produces two values at a time and
saves the second for a latter call.  So, yes, that implicit state has
to be preserved and I should have followed what Ed said.

But your 4th and 7th call example by itself is not a reason.  Again,
the input exclusively determined by the random numbers.  Here, of
course, the 4th and 7th use will produce different results.  But this
is not what the state of the distribution is supposed to capture.  For
that you'll have to save the state of the RNG as well.


I've checked in a patch to save the _M_n state.

Thanks.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 16:18         ` Ulrich Drepper
@ 2014-07-13 16:29           ` Paolo Carlini
  2014-07-13 16:45             ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-07-13 16:29 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Ed Smith-Rowland, gcc-patches

Hi,

On 07/13/2014 06:18 PM, Ulrich Drepper wrote:
> On Sun, Jul 13, 2014 at 12:07 PM, Paolo Carlini
> <paolo.carlini@oracle.com> wrote:
>> Sorry, I still don't get it. When operator() of x and y, two
>> uniform_on_sphere_distribution, call _M_n(__urng) and those _M_n have a
>> different state, the numbers produced are in general different.
> Correct.  But in the case of this distribution once you have the
> random numbers the remainder of the work is done by a fixed formula:
>
>     v = (N(0,1), ..., N(0,1))
>
>     result = v / ||v||_2
>
> That's it, nothing else to be done.
>
> If you have two calls of operator() of two different uniform_on_sphere
> objects and you pass to each an RNG object in exactly the same state
> you will get the same result.
I don't think so. It depends on the past of the two different 
uniform_on_sphere: each time each uniform_on_sphere calls _M_n(__urng) 
the state of *its own* _M_n changes, evolves from the initial state. For 
instance, you call it 4 times on one and 7 times on another. The states 
of the two _M_n are different, and from that point the next numbers will 
be different. This is exactly what happens when you call os << x and is 
 >> y, no object is destroyed, no object is constructed, and x has 
called _M_n(__urng) 4 times, and y has called it 7 times. Your inserters 
and extractors are trivial. The next numbers will be different. Note 
that, if I understand the standard correctly, we are comparing the 
numbers *from that point on*, not the whole story, whatever that may 
mean. In other terms, I'm saying the sequence of numbers produced after 
the 4th number isn't in general the same sequence of numbers produced 
after the 7th number.

Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 16:12       ` Paolo Carlini
@ 2014-07-13 16:18         ` Ulrich Drepper
  2014-07-13 16:29           ` Paolo Carlini
  0 siblings, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13 16:18 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Ed Smith-Rowland, gcc-patches

On Sun, Jul 13, 2014 at 12:07 PM, Paolo Carlini
<paolo.carlini@oracle.com> wrote:
> Sorry, I still don't get it. When operator() of x and y, two
> uniform_on_sphere_distribution, call _M_n(__urng) and those _M_n have a
> different state, the numbers produced are in general different.

Correct.  But in the case of this distribution once you have the
random numbers the remainder of the work is done by a fixed formula:

   v = (N(0,1), ..., N(0,1))

   result = v / ||v||_2

That's it, nothing else to be done.

If you have two calls of operator() of two different uniform_on_sphere
objects and you pass to each an RNG object in exactly the same state
you will get the same result.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 16:04     ` Ulrich Drepper
@ 2014-07-13 16:12       ` Paolo Carlini
  2014-07-13 16:18         ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-07-13 16:12 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Ed Smith-Rowland, gcc-patches

Hi,

On 07/13/2014 06:03 PM, Ulrich Drepper wrote:
> On Sun, Jul 13, 2014 at 11:43 AM, Paolo Carlini
> <paolo.carlini@oracle.com> wrote:
>> and I think: the normal distributions in x and y do have a non-trivial state
>> (_M_saved, _M_saved_available) which, at any given moment, is different in x
>> and y. Then the trivial inserter of x is called and the trivial extractor of
>> y is called, nothing changes in y. I don't see how the following invocations
>> of y(g) can produce the same sequence of numbers that would be produced by
>> invocations of x(g).
> Remember: we are talking about distributions, not RNGs.
>
> The distribution has no parameters so given the same input (i.e.,
> random byte sequences) it will create the same output all the time.
Sorry, I still don't get it. When operator() of x and y, two 
uniform_on_sphere_distribution, call _M_n(__urng) and those _M_n have a 
different state, the numbers produced are in general different. For 
example, suppose _M_saved_available is true in both _M_n, everything is 
already "decided", no RNGs are involved.

Paolo.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 15:47   ` Paolo Carlini
@ 2014-07-13 16:04     ` Ulrich Drepper
  2014-07-13 16:12       ` Paolo Carlini
  0 siblings, 1 reply; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13 16:04 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Ed Smith-Rowland, gcc-patches

On Sun, Jul 13, 2014 at 11:43 AM, Paolo Carlini
<paolo.carlini@oracle.com> wrote:
> and I think: the normal distributions in x and y do have a non-trivial state
> (_M_saved, _M_saved_available) which, at any given moment, is different in x
> and y. Then the trivial inserter of x is called and the trivial extractor of
> y is called, nothing changes in y. I don't see how the following invocations
> of y(g) can produce the same sequence of numbers that would be produced by
> invocations of x(g).

Remember: we are talking about distributions, not RNGs.

The distribution has no parameters so given the same input (i.e.,
random byte sequences) it will create the same output all the time.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 14:12 ` Ulrich Drepper
  2014-07-13 14:48   ` Ed Smith-Rowland
@ 2014-07-13 15:47   ` Paolo Carlini
  2014-07-13 16:04     ` Ulrich Drepper
  1 sibling, 1 reply; 41+ messages in thread
From: Paolo Carlini @ 2014-07-13 15:47 UTC (permalink / raw)
  To: Ulrich Drepper, Ed Smith-Rowland; +Cc: gcc-patches

Hi,

On 07/13/2014 04:11 PM, Ulrich Drepper wrote:
> On Sun, Jul 13, 2014 at 9:55 AM, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
>> So I would just serialize _M_n here.
> It has fixed parameters. This would mean unnecessary work.  When you
> try to use the parameter of the sphere distribution the normal
> distribution will be reset.  So there really is no need here.
At the cost of appearing a little dumb (and admittedly lately I'm not 
spending much time on <random>, anyway), I'd like to make sure I 
*really* understand your reasoning... Thus I read this (26.5.1.6/6):

"If a textual representation is written using os << x and that 
representation is restored into the same or a different object y of the 
same type using is >> y, repeated invocations of y(g) shall produce the 
same sequence of numbers as would repeated invocations of x(g)."

and I think: the normal distributions in x and y do have a non-trivial 
state (_M_saved, _M_saved_available) which, at any given moment, is 
different in x and y. Then the trivial inserter of x is called and the 
trivial extractor of y is called, nothing changes in y. I don't see how 
the following invocations of y(g) can produce the same sequence of 
numbers that would be produced by invocations of x(g).

Paolo.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 14:12 ` Ulrich Drepper
@ 2014-07-13 14:48   ` Ed Smith-Rowland
  2014-07-13 15:47   ` Paolo Carlini
  1 sibling, 0 replies; 41+ messages in thread
From: Ed Smith-Rowland @ 2014-07-13 14:48 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: gcc-patches, Paolo Carlini

On 07/13/2014 10:11 AM, Ulrich Drepper wrote:
> On Sun, Jul 13, 2014 at 9:55 AM, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
>> So I would just serialize _M_n here.
> It has fixed parameters. This would mean unnecessary work.  When you
> try to use the parameter of the sphere distribution the normal
> distribution will be reset.  So there really is no need here.
>
> The only problem would be if code couldn't handle the operators not
> writing/reading anything  But I haven't seen anything like that.
>
OK.  I see it. Thanks.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
  2014-07-13 13:55 Ed Smith-Rowland
@ 2014-07-13 14:12 ` Ulrich Drepper
  2014-07-13 14:48   ` Ed Smith-Rowland
  2014-07-13 15:47   ` Paolo Carlini
  0 siblings, 2 replies; 41+ messages in thread
From: Ulrich Drepper @ 2014-07-13 14:12 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: gcc-patches, Paolo Carlini

On Sun, Jul 13, 2014 at 9:55 AM, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
> So I would just serialize _M_n here.

It has fixed parameters. This would mean unnecessary work.  When you
try to use the parameter of the sphere distribution the normal
distribution will be reset.  So there really is no need here.

The only problem would be if code couldn't handle the operators not
writing/reading anything  But I haven't seen anything like that.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH] libstdc++: add uniform on sphere distribution
@ 2014-07-13 13:55 Ed Smith-Rowland
  2014-07-13 14:12 ` Ulrich Drepper
  0 siblings, 1 reply; 41+ messages in thread
From: Ed Smith-Rowland @ 2014-07-13 13:55 UTC (permalink / raw)
  To: gcc-patches, Paolo Carlini, Ulrich Drepper

> > are these dummy implementations intended?

> Yes.  There is no state.  The only parameter is the dimensionality
> which is a template parameter.

We do often serialize underlying helper distributions, in your case the 
normal distribution _M_n.
While the normal distribution mean and stddev are trivial for your case 
(not actually needing serialization)
the normal distribution has these _M_saved, etc. shat we should store.

So I would just serialize _M_n here.

This is a great distribution.
Thanks!

Are you looking at the normal distribution equivalent of these?

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2014-08-13 11:40 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-13  2:01 [PATCH] libstdc++: add uniform on sphere distribution Ulrich Drepper
2014-07-13  2:06 ` Ulrich Drepper
2014-07-13  9:28 ` Paolo Carlini
2014-07-13 10:04   ` Ulrich Drepper
2014-07-13 10:40     ` Paolo Carlini
2014-07-23 10:05 ` Marc Glisse
2014-07-23 10:44   ` Jonathan Wakely
2014-07-24 22:14     ` Ulrich Drepper
2014-07-24 23:19       ` Jonathan Wakely
2014-08-08 23:24     ` Ulrich Drepper
2014-08-09  7:15       ` Marc Glisse
2014-08-09 11:55         ` Ulrich Drepper
2014-08-09 12:34           ` Marc Glisse
2014-08-09 15:24             ` Ulrich Drepper
2014-08-09 15:33               ` Marc Glisse
2014-08-09 16:55                 ` Ed Smith-Rowland
2014-08-09 16:56                 ` Ulrich Drepper
2014-08-09 17:40                   ` Marc Glisse
2014-08-09 18:00                     ` Ulrich Drepper
2014-08-13  7:36                       ` Bin.Cheng
2014-08-13  7:43                         ` Bin.Cheng
2014-08-13  8:41                         ` Paolo Carlini
2014-08-13 11:25                           ` Paolo Carlini
2014-08-13 11:32                             ` Marc Glisse
2014-08-13 11:40                               ` Paolo Carlini
2014-07-13 13:55 Ed Smith-Rowland
2014-07-13 14:12 ` Ulrich Drepper
2014-07-13 14:48   ` Ed Smith-Rowland
2014-07-13 15:47   ` Paolo Carlini
2014-07-13 16:04     ` Ulrich Drepper
2014-07-13 16:12       ` Paolo Carlini
2014-07-13 16:18         ` Ulrich Drepper
2014-07-13 16:29           ` Paolo Carlini
2014-07-13 16:45             ` Ulrich Drepper
2014-07-13 16:56               ` Paolo Carlini
2014-07-14  7:58               ` Andreas Schwab
2014-07-14  8:18                 ` Paolo Carlini
2014-07-16 11:30                   ` Ed Smith-Rowland
2014-07-16 15:03                     ` Paolo Carlini
2014-07-16 17:38                       ` Ulrich Drepper
2014-07-14 10:31 Dominique Dhumieres

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).