This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] libstdc++: add uniform on sphere distribution
- From: Ulrich Drepper <drepper at gmail dot com>
- To: Jonathan Wakely <jwakely at redhat dot com>
- Cc: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 08 Aug 2014 19:24:52 -0400
- Subject: Re: [PATCH] libstdc++: add uniform on sphere distribution
- Authentication-results: sourceware.org; auth=none
- References: <87a98eow4m dot fsf at x240 dot local dot i-did-not-set--mail-host-address--so-tickle-me> <alpine dot DEB dot 2 dot 11 dot 1407231149300 dot 1768 at laptop-mg dot saclay dot inria dot fr> <20140723102908 dot GM2361 at redhat dot com>
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; });