Re: Add uniform_inside_sphere_distribution
On 27/10/16 15:33 +0200, Andreas Schwab wrote: On Okt 26 2016, Jonathan Wakelywrote: In all the new tests please replace this dg-options directive with: { dg-do run { target cxx11 } } ERROR: ext/random/uniform_inside_sphere_distribution/cons/default.cc: syntax error in target selector "target cxx11" for " dg-do 1 run { target cxx11 } " My fault, it should be { target c++11 } not { target cxx11 }. Testing this, will commit shortly. commit 9fdf7cdb6b00c6d962959c27a057beb91e23b219 Author: Jonathan Wakely Date: Thu Oct 27 14:54:13 2016 +0100 Fix target selectors in uniform_inside_sphere_distribution tests * testsuite/ext/random/uniform_inside_sphere_distribution/cons/ default.cc: Fix effective target selector. * testsuite/ext/random/uniform_inside_sphere_distribution/cons/ parms.cc: Likewise. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ equal.cc: Likewise. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ generate.cc: Likewise. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ inequal.cc: Likewise. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ serialize.cc: Likewise. diff --git a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc index 79ae488..ff5bcb3 100644 --- a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc +++ b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc @@ -1,4 +1,4 @@ -// { dg-do run { target cxx11 } } +// { dg-do run { target c++11 } } // { dg-require-cstdint "" } // // Copyright (C) 2014-2016 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/parms.cc index 924b997..6a6ea2c 100644 --- a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/parms.cc +++ b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/cons/parms.cc @@ -1,4 +1,4 @@ -// { dg-do run { target cxx11 } } +// { dg-do run { target c++11 } } // { dg-require-cstdint "" } // // Copyright (C) 2014-2016 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/equal.cc index 370ee56..1210946 100644 --- a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/equal.cc +++ b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/equal.cc @@ -1,4 +1,4 @@ -// { dg-do run { target cxx11 } } +// { dg-do run { target c++11 } } // { dg-require-cstdint "" } // // Copyright (C) 2014-2016 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/generate.cc b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/generate.cc index 60d76f3..e9a7ca7 100644 --- a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/generate.cc +++ b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/generate.cc @@ -1,4 +1,4 @@ -// { dg-do run { target cxx11 } } +// { dg-do run { target c++11 } } // { dg-require-cstdint "" } // // Copyright (C) 2014-2016 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/inequal.cc index 0256d47..ca0d380 100644 --- a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/inequal.cc +++ b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/inequal.cc @@ -1,4 +1,4 @@ -// { dg-do run { target cxx11 } } +// { dg-do run { target c++11 } } // { dg-require-cstdint "" } // // Copyright (C) 2014-2016 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/serialize.cc index d03ce35..89eb604 100644 --- a/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/serialize.cc +++ b/libstdc++-v3/testsuite/ext/random/uniform_inside_sphere_distribution/operators/serialize.cc @@ -1,4 +1,4 @@ -// { dg-do run { target cxx11 } } +// { dg-do run { target c++11 } } // { dg-require-cstdint "" } // // Copyright (C) 2014-2016 Free Software Foundation, Inc.
Re: Add uniform_inside_sphere_distribution
On Okt 26 2016, Jonathan Wakelywrote: > In all the new tests please replace this dg-options directive with: > > { dg-do run { target cxx11 } } ERROR: ext/random/uniform_inside_sphere_distribution/cons/default.cc: syntax error in target selector "target cxx11" for " dg-do 1 run { target cxx11 } " Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: Add uniform_inside_sphere_distribution
On 10/26/2016 05:01 AM, Jonathan Wakely wrote: On 25/10/16 08:20 -0400, Ed Smith-Rowland wrote: +explicit +param_type(_RealType __radius = _RealType(1)) +: _M_radius(__radius) +{ + _GLIBCXX_DEBUG_ASSERT(_M_radius > _RealType(0)); Nowadays we're able to do cheaper assertions when _GLIBCXX_ASSERTIONS is defined, without the full debug mode (i.e. _GLIBCXX_DEBUG). The macro above is only active for the full debug mode, but it looks like a cheap check, should it use __glibcxx_assert instead? It looks like we're not consistent about which one to use in , which is probably my fault. Expensive checks like using std::distance on forward iterators should use _GLIBCXX_DEBUG_ASSERT but some of them look like they could use __glibcxx_assert. This parameter check could definitely use __glibcxx_assert. In fact, these two features look like 2/3 of the contracts proposal for C++ almost. Or at least they could help. Index: testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc === --- testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc (nonexistent) +++ testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc (working copy) @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++11" } In all the new tests please replace this dg-options directive with: { dg-do run { target cxx11 } } so it can be tested for C++14 and C++17 too. Done. +// { dg-require-cstdint "" } +// +// Copyright (C) 2014 Free Software Foundation, Inc. And update the dates to 2014-2016. Done. Committed as 241562 with the attached . Index: include/ext/random === --- include/ext/random (revision 241499) +++ include/ext/random (working copy) @@ -3493,6 +3493,218 @@ _RealType>& __d2) { return !(__d1 == __d2); } + + /** + * @brief A distribution for random coordinates inside a unit sphere. + */ + template +class uniform_inside_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. */ + using result_type = std::array<_RealType, _Dimen>; + + /** Parameter type. */ + struct param_type + { + using distribution_type + = uniform_inside_sphere_distribution<_Dimen, _RealType>; + friend class uniform_inside_sphere_distribution<_Dimen, _RealType>; + + explicit + param_type(_RealType __radius = _RealType(1)) + : _M_radius(__radius) + { + __glibcxx_assert(_M_radius > _RealType(0)); + } + + _RealType + radius() const + { return _M_radius; } + + friend bool + operator==(const param_type& __p1, const param_type& __p2) + { return __p1._M_radius == __p2._M_radius; } + + private: + _RealType _M_radius; + }; + + /** + * @brief Constructors. + */ + explicit + uniform_inside_sphere_distribution(_RealType __radius = _RealType(1)) + : _M_param(__radius), _M_uosd() + { } + + explicit + uniform_inside_sphere_distribution(const param_type& __p) + : _M_param(__p), _M_uosd() + { } + + /** + * @brief Resets the distribution state. + */ + void + reset() + { _M_uosd.reset(); } + + /** + * @brief Returns the @f$radius@f$ of the distribution. + */ + _RealType + radius() const + { return _M_param.radius(); } + + /** + * @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 + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return this->operator()(__urng, _M_param); } + + template + result_type + operator()(_UniformRandomNumberGenerator& __urng, +
Re: Add uniform_inside_sphere_distribution
On 25/10/16 08:20 -0400, Ed Smith-Rowland wrote: + explicit + param_type(_RealType __radius = _RealType(1)) + : _M_radius(__radius) + { + _GLIBCXX_DEBUG_ASSERT(_M_radius > _RealType(0)); Nowadays we're able to do cheaper assertions when _GLIBCXX_ASSERTIONS is defined, without the full debug mode (i.e. _GLIBCXX_DEBUG). The macro above is only active for the full debug mode, but it looks like a cheap check, should it use __glibcxx_assert instead? It looks like we're not consistent about which one to use in , which is probably my fault. Expensive checks like using std::distance on forward iterators should use _GLIBCXX_DEBUG_ASSERT but some of them look like they could use __glibcxx_assert. Index: testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc === --- testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc (nonexistent) +++ testsuite/ext/random/uniform_inside_sphere_distribution/cons/default.cc (working copy) @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++11" } In all the new tests please replace this dg-options directive with: { dg-do run { target cxx11 } } so it can be tested for C++14 and C++17 too. +// { dg-require-cstdint "" } +// +// Copyright (C) 2014 Free Software Foundation, Inc. And update the dates to 2014-2016. OK for trunk with those changes to the tests. Whether to use DEBUG_ASSERT/assert is your call. Thanks.
Re: Add uniform_inside_sphere_distribution
All, Here is the library extension for uniform_inside _sphere_distribution. It works from discs and has been tested up through 12-dimentional spheres. The patch dispatches to rejection for Dim<8, transform otherwise as discussed earlier. Builds and tests cleanly on x86_64-linux. OK? Ed Index: include/ext/random === --- include/ext/random (revision 241499) +++ include/ext/random (working copy) @@ -3493,6 +3493,218 @@ _RealType>& __d2) { return !(__d1 == __d2); } + + /** + * @brief A distribution for random coordinates inside a unit sphere. + */ + template +class uniform_inside_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. */ + using result_type = std::array<_RealType, _Dimen>; + + /** Parameter type. */ + struct param_type + { + using distribution_type + = uniform_inside_sphere_distribution<_Dimen, _RealType>; + friend class uniform_inside_sphere_distribution<_Dimen, _RealType>; + + explicit + param_type(_RealType __radius = _RealType(1)) + : _M_radius(__radius) + { + _GLIBCXX_DEBUG_ASSERT(_M_radius > _RealType(0)); + } + + _RealType + radius() const + { return _M_radius; } + + friend bool + operator==(const param_type& __p1, const param_type& __p2) + { return __p1._M_radius == __p2._M_radius; } + + private: + _RealType _M_radius; + }; + + /** + * @brief Constructors. + */ + explicit + uniform_inside_sphere_distribution(_RealType __radius = _RealType(1)) + : _M_param(__radius), _M_uosd() + { } + + explicit + uniform_inside_sphere_distribution(const param_type& __p) + : _M_param(__p), _M_uosd() + { } + + /** + * @brief Resets the distribution state. + */ + void + reset() + { _M_uosd.reset(); } + + /** + * @brief Returns the @f$radius@f$ of the distribution. + */ + _RealType + radius() const + { return _M_param.radius(); } + + /** + * @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 + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return this->operator()(__urng, _M_param); } + + template + result_type + operator()(_UniformRandomNumberGenerator& __urng, + const param_type& __p); + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + 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_inside_sphere_distribution& __d1, +const uniform_inside_sphere_distribution& __d2) + { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; } + + /** + * @brief Inserts a %uniform_inside_sphere_distribution random number + *distribution @p __x into the output stream @p __os. + * + * @param
Re: Add uniform_inside_sphere_distribution
On 11/06/2014 02:23 AM, Marc Glisse wrote: On Wed, 5 Nov 2014, Ed Smith-Rowland wrote: On 11/05/2014 04:25 PM, Marc Glisse wrote: On Wed, 5 Nov 2014, Ed Smith-Rowland wrote: Like the uniform_on_sphere_distribution which is used inside, the 2-dimensional case uses rejection Could you point out where in the code you are special-casing dimension 2? Somehow I can't see it in the patch. My miscommunication. Sorry. The special casing - and all the hard work - is done by the contained uniform_on_sphere_distribution. In dimension 2, uniform_on_sphere_distribution generates a uniform random point in the unit disk and projects it to the circle. Using that + one more random number to regenerate a uniform random point in the disk seems wasteful to me. Good point. I'll check out a direct rejection and see what that gets me time-wise. The ratio is pi/4 which is pretty good.
Add uniform_inside_sphere_distribution
This distribution has come in handy for me. It relies on uniform_on_sphere_distribution and like it, min and max have no real meaning. Unlike uniform_on_sphere_distribution which really is a random multidimensional unit vector users often want to pick the radius of the distribution. Unit radius is a good default and is provided but the user can specify radius. Like the uniform_on_sphere_distribution which is used inside, the 2-dimensional case uses rejection and higher dimensions use a transform. Built and tested clean on x86_64-linux. OK? Ed 2014-09-05 Edward Smith-Rowland 3dw...@verizon.net * include/ext/random: Add uniform_inside_sphere_distribution. * include/ext/random.tcc: Out-of-line implementation of uniform_inside_sphere_distribution. * testsuite/ext/random/uniform_inside_sphere_distribution/cons/ default.cc: New. * testsuite/ext/random/uniform_inside_sphere_distribution/cons/ parms.cc: New. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ equal.cc: New. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ generate.cc: New. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ inequal.cc: New. * testsuite/ext/random/uniform_inside_sphere_distribution/operators/ serialize.cc: New. Index: include/ext/random === --- include/ext/random (revision 216942) +++ include/ext/random (working copy) @@ -3487,6 +3487,218 @@ _RealType __d2) { return !(__d1 == __d2); } + + /** + * @brief A distribution for random coordinates inside a unit sphere. + */ + templatestd::size_t _Dimen, typename _RealType = double +class uniform_inside_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. */ + using result_type = std::array_RealType, _Dimen; + + /** Parameter type. */ + struct param_type + { + using distribution_type + = uniform_inside_sphere_distribution_Dimen, _RealType; + friend class uniform_inside_sphere_distribution_Dimen, _RealType; + + explicit + param_type(_RealType __radius = _RealType(1)) + : _M_radius(__radius) + { + _GLIBCXX_DEBUG_ASSERT(_M_radius _RealType(0)); + } + + _RealType + radius() const + { return _M_radius; } + + friend bool + operator==(const param_type __p1, const param_type __p2) + { return __p1._M_radius == __p2._M_radius; } + + private: + _RealType _M_radius; + }; + + /** + * @brief Constructors. + */ + explicit + uniform_inside_sphere_distribution(_RealType __radius = _RealType(1)) + : _M_param(__radius), _M_uosd() + { } + + explicit + uniform_inside_sphere_distribution(const param_type __p) + : _M_param(__p), _M_uosd() + { } + + /** + * @brief Resets the distribution state. + */ + void + reset() + { _M_uosd.reset(); } + + /** + * @brief Returns the @f$radius@f$ of the distribution. + */ + _RealType + radius() const + { return _M_param.radius(); } + + /** + * @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. + */ + templatetypename _UniformRandomNumberGenerator + result_type + operator()(_UniformRandomNumberGenerator __urng) + { return this-operator()(__urng, _M_param); } + + templatetypename _UniformRandomNumberGenerator + result_type + operator()(_UniformRandomNumberGenerator __urng, + const param_type __p); + + templatetypename _ForwardIterator, + typename _UniformRandomNumberGenerator + void + __generate
Re: Add uniform_inside_sphere_distribution
On Wed, 5 Nov 2014, Ed Smith-Rowland wrote: Like the uniform_on_sphere_distribution which is used inside, the 2-dimensional case uses rejection Could you point out where in the code you are special-casing dimension 2? Somehow I can't see it in the patch. -- Marc Glisse
Re: Add uniform_inside_sphere_distribution
On 11/05/2014 04:25 PM, Marc Glisse wrote: On Wed, 5 Nov 2014, Ed Smith-Rowland wrote: Like the uniform_on_sphere_distribution which is used inside, the 2-dimensional case uses rejection Could you point out where in the code you are special-casing dimension 2? Somehow I can't see it in the patch. My miscommunication. Sorry. The special casing - and all the hard work - is done by the contained uniform_on_sphere_distribution. The uniform_inside_sphere_distribution only has one template. Ed