[Bug libstdc++/55047] New: operator() in std::exponential_distribution may call log(0)
hyounes at google dot com
gcc-bugzilla@gcc.gnu.org
Wed Oct 24 02:25:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55047
Bug #: 55047
Summary: operator() in std::exponential_distribution may call
log(0)
Classification: Unclassified
Product: gcc
Version: 4.6.3
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: hyounes@google.com
The implementation of operator() for std::exponential_distribution is:
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
const param_type& __p)
{
__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
__aurng(__urng);
return -std::log(__aurng()) / __p.lambda();
}
If I understand this correctly, __aurng() returns a value in [0,1). This
leaves the possibility of computing -log(0)/lambda, which I expect to be Inf.
On the other hand, -log(1)/lambda will never occur, so the resulting value can
never be 0. There are two problems with this implementation:
1. The actual range (0,Inf) U Inf is not consistent with the reported range of
[0,Inf) as computed by the min() and max() member functions.
2. -log(U01)/lambda is not the mathematically correct form for the inverse
transformation for the exponential distribution. -log(1 - U01)/lambda is the
correct form. This form also gives you the correct range of [0,Inf). It is an
incorrect optimization to change 1-U01 to just U01 when U01 is [0,1). It is
only correct if U01 is [0,1] or (0,1), but I do not believe that to be the case
here.
I believe the correct implementation should have the following return
statement:
return -std::log(result_type(1) - __aurng()) / __p.lambda();
The same problem appears in several other distributions. For example,
std::weibull_distribution.
More information about the Gcc-bugs
mailing list