]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
random: Add uniform_on_sphere_distribution definition.
authorUlrich Drepper <drepper@gcc.gnu.org>
Sun, 13 Jul 2014 11:07:44 +0000 (11:07 +0000)
committerUlrich Drepper <drepper@gcc.gnu.org>
Sun, 13 Jul 2014 11:07:44 +0000 (11:07 +0000)
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.
* testsuite/ext/random/uniform_on_sphere_distribution/
cons/default.cc: New file.
* testsuite/ext/random/uniform_on_sphere_distribution/
operators/equal.cc: New file.
* testsuite/ext/random/uniform_on_sphere_distribution/
operators/inequal.cc: New file.
* testsuite/ext/random/uniform_on_sphere_distribution/
operators/serialize.cc: New file.

From-SVN: r212492

libstdc++-v3/ChangeLog
libstdc++-v3/include/ext/random
libstdc++-v3/include/ext/random.tcc
libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/cons/default.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/equal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/inequal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/random/uniform_on_sphere_distribution/operators/serialize.cc [new file with mode: 0644]

index c8a6a6d95c6487c88552975e07b050ba6c053e84..4b798c0f125142fb0a89e7ae14a840a6b04621d8 100644 (file)
@@ -1,3 +1,17 @@
+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.
+       * testsuite/ext/random/uniform_on_sphere_distribution/
+       cons/default.cc: New file.
+       * testsuite/ext/random/uniform_on_sphere_distribution/
+       operators/equal.cc: New file.
+       * testsuite/ext/random/uniform_on_sphere_distribution/
+       operators/inequal.cc: New file.
+       * testsuite/ext/random/uniform_on_sphere_distribution/
+       operators/serialize.cc: New file.
+
 2014-07-11  Edward Smith-Rowland  <3dw4rd@verizon.net>
 
        Add the logistic_distribution as an extension.
 
        Revert:
        2014-06-18  Paolo Carlini  <paolo.carlini@oracle.com>
-                   Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+                   Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        PR libstdc++/61536
        * config/abi/pre/gnu.ver: Adjust for out of line comparisons.
        * include/std/chrono (_Checked_integral_constant): Allow zero.
        * testsuite/20_util/duration/literals/values.cc: Test non-positive
        values and digit separators.
-       * include/experimental/any 
+       * include/experimental/any
 
        PR libstdc++/61532
        * testsuite/20_util/make_signed/requirements/typedefs-1.cc: Do not
 
 2014-05-20  Cesar Philippidis  <cesar@codesourcery.com>
 
-       * scripts/testsuite_flags.in (cxxflags): Remove @CXXFLAGS@ since 
+       * scripts/testsuite_flags.in (cxxflags): Remove @CXXFLAGS@ since
        libstdc++.exp imports those flags via getenv.
-       * testsuite/lib/libstdc++.exp (libstdc++_init): Ensure that 
-       CXXFLAGS contains a '-O' flag. 
+       * testsuite/lib/libstdc++.exp (libstdc++_init): Ensure that
+       CXXFLAGS contains a '-O' flag.
 
 2014-05-20  Alexey Merzlyakov  <alexey.merzlyakov@samsung.com>
 
index eab3fb8ef3241d55c0a0df23aaa5e8a058a9b340..e6d5ca0dba4d3f5a451af7bbe6b0ca9b1e0a6ffd 100644 (file)
@@ -36,6 +36,7 @@
 #else
 
 #include <random>
+#include <algorithm>
 #include <array>
 #include <ext/cmath>
 #ifdef __SSE2__
@@ -2962,7 +2963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
        using _IntType = typename std::make_signed<result_type>::type;
        return static_cast<result_type>(std::max(static_cast<_IntType>(0),
-                               static_cast<_IntType>(this->total_draws()
+                               static_cast<_IntType>(this->total_draws()
                                                - this->unsuccessful_size())));
       }
 
@@ -3033,7 +3034,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
                   const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
-                   __x);
+                  __x);
 
       /**
        * @brief Extracts a %hypergeometric_distribution random number
@@ -3127,7 +3128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        friend bool
        operator==(const param_type& __p1, const param_type& __p2)
        { return __p1._M_a == __p2._M_a
-              && __p1._M_b == __p2._M_b; }
+             && __p1._M_b == __p2._M_b; }
 
       private:
        void _M_initialize();
@@ -3238,10 +3239,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *        be generated are equal.
        */
       template<typename _RealType1>
-        friend bool
-        operator==(const logistic_distribution<_RealType1>& __d1,
+       friend bool
+       operator==(const logistic_distribution<_RealType1>& __d1,
                   const logistic_distribution<_RealType1>& __d2)
-        { return __d1.param() == __d2.param(); }
+       { return __d1.param() == __d2.param(); }
 
       /**
        * @brief Inserts a %logistic_distribution random number distribution
@@ -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
 
index ba9ab6dcce2fd6a0a5f121a6219bd1e3ddcecf22..c836b211cae86027f2af3b5106f6a47951056e59 100644 (file)
@@ -1362,7 +1362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        result_type __b = __param.total_size();
        result_type __k = 0;
 
-       if (__param.total_draws() < __param.total_size() / 2) 
+       if (__param.total_draws() < __param.total_size() / 2)
          {
            for (result_type __i = 0; __i < __param.total_draws(); ++__i)
              {
@@ -1539,6 +1539,65 @@ _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)
+    {
+      // The distribution has no state, nothing to save.
+      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)
+    {
+      // The distribution has no state, nothing to restore.
+      return __is;
+    }
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff --git 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
new file mode 100644 (file)
index 0000000..fb48fe2
--- /dev/null
@@ -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 --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
new file mode 100644 (file)
index 0000000..35a024e
--- /dev/null
@@ -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 --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
new file mode 100644 (file)
index 0000000..9f8e8c8
--- /dev/null
@@ -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 --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
new file mode 100644 (file)
index 0000000..80264ff
--- /dev/null
@@ -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;
+}