Re: [Boost-bugs] [Boost C++ Libraries] #9966: exponential_distribution returns negative zero

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #9966: exponential_distribution returns negative zero
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-02-27 11:39:09


#9966: exponential_distribution returns negative zero
-------------------------------+---------------------------
  Reporter: mazzamuto@… | Owner: no-maintainer
      Type: Bugs | Status: new
 Milestone: To Be Determined | Component: random
   Version: Boost 1.48.0 | Severity: Problem
Resolution: | Keywords:
-------------------------------+---------------------------

Comment (by mazzamuto@…):

 I agree that the problem is not with the sign. Indeed I recognize that the
 documentation states: The domain of the random variable is [0, +Inf].
 So, returning zero is expected and documented even if this clashes with
 C++11. Apparently this behaviour results from this code

 {{{#!cpp
 return -result_type(1) /
             _lambda * log(result_type(1)-uniform_01<RealType>()(eng));
 }}}

 where the log argument is (0,1] instead of [0,1).

 This causes another problem with the upper limit +Inf being documented as
 included. For example, this code should produce the minimum and maximum
 values obtainable from exponential_distribution with lambda=1:


 {{{#!cpp
 #include <boost/random.hpp>
 #include <boost/version.hpp>

 #include <math.h>
 #include <stdio.h>

 using namespace boost::random;
 using namespace std;

 int main() {
     cout << "Using BOOST " << BOOST_VERSION << endl;
     cout << "---------------" << endl;

     mt19937* mt = new mt19937(0);

     for (u_int32_t i = mt->min(); i < 5; i++) {
         double factor = 1./(mt->max()-mt->min()+1.);
         double xi = (i-mt->min())*factor;
         printf("%.20f\n", -1.f/1.f*log(1.f-xi));
     }


     cout << "---------------" << endl;

     for (u_int32_t i = mt->max(); i > mt->max() - 5; i--) {
         double factor = 1./(mt->max()-mt->min()+1.);
         double xi = (i-mt->min())*factor;
         printf("%.20f\n", -1.f/1.f*log(1.f-xi));
     }

     return 0;
 }
 }}}

 The output is:
 {{{
 Using BOOST 105700
 ---------------
 -0.00000000000000000000
 0.00000000023283064368
 0.00000000046566128742
 0.00000000069849193121
 0.00000000093132257505
 ---------------
 22.18070977791824915926
 21.48756259735830553836
 21.08209748925014181964
 20.79441541679835836476
 20.57127186548414954359
 }}}

 and we can see that the maximum value is 22, not +Inf. The maximum value
 shifts accordingly to 44 when using mt19937_64, u_int64_t and long double.

 Taking the log argument as [0,1) should fix both problems:
 {{{
 Using BOOST 105700
 ---------------
 inf
 22.18070977791824915926
 21.48756259735830553836
 21.08209748925014181964
 20.79441541679835836476
 ---------------
 0.00000000023283064368
 0.00000000046566128742
 0.00000000069849193121
 0.00000000093132257505
 0.00000000116415321895
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/9966#comment:4>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC