Reputation: 179
In a project, I am generating millions of expo(lambda) random variables, where lambda is potentially very large. When using std::exponential_distribution<float>
I occasionally get a return value of inf
. I would understand this if lambda were close to 0, but when lambda is large a value very close to zero is expected. For example, the following program usually terminates after several million draws:
#include<iostream>
#include<random>
int main(void)
{
std::random_device rd;
std::mt19937 generator(rd());
float lambda = 1000000.0;
float val = 0;
for(int i = 0; i < 1000000000; ++i)
{
std::exponential_distribution<float> dist(lambda);
val = dist(generator);
if(isinf(val))
{
std::cout << i << " " << val << " failure" << std::endl;
exit(0);
}
}
return 0;
}
If there is some error (due to precision) in the function, why does it return inf
instead of the more convenient 0.0
? Is there any way to fix this, besides for manually checking that the output is finite? Thanks.
Upvotes: 0
Views: 254
Reputation: 32888
Richard Critten's comment says:
"...Some implementations may occasionally return infinity if RealType is float. This is LWG issue 2524..." source (has a link to the issue): https://en.cppreference.com/w/cpp/numeric/random/exponential_distribution
Switching to double
doesn't fix this problem, but rather, it merely reduces the chance of seeing it (or at least makes it negligible). As the LWG issue points out, the underlying issue is that generate_canonical
(which some implementations could make use of) might return 1.0 in rare cases, so that -log(1-generate_canonical())
could output infinity. In practice, this was more likely with float
than with double
since there are considerably fewer numbers that generate_canonical
could produce with float
than with double
(in practice, 2^24 as opposed to 2^53). (In any case, there are other problems with naive implementations of right-tailed distributions, such as the exponential distribution; see "Reconditioning your quantile function".)
Upvotes: 3