philbo_baggins
philbo_baggins

Reputation: 179

C++ exponential_distribution occasionally returns inf where 0 is expected

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

Answers (1)

Peter O.
Peter O.

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

Related Questions