C ++ exponential_distribution иногда возвращает inf, где ожидается 0 - PullRequest
0 голосов
/ 01 апреля 2020

В проекте я генерирую миллионы expo (лямбда) случайных величин, где лямбда потенциально очень велика. При использовании std::exponential_distribution<float> я иногда получаю возвращаемое значение inf. Я бы понял это, если бы лямбда была близка к 0, но когда лямбда велика, ожидается значение, очень близкое к нулю. Например, следующая программа обычно завершает работу после нескольких миллионов др aws:

#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;
}

Если в функции есть какая-то ошибка (из-за точности), почему она возвращает inf вместо более удобно 0.0? Есть ли способ исправить это, кроме ручной проверки конечности вывода? Спасибо.

1 Ответ

3 голосов
/ 01 апреля 2020

Комментарий Ричарда Криттена гласит:

"... Некоторые реализации могут иногда возвращать бесконечность, если RealType является плавающим. Это источник LWG Issue 2524 ..." (имеется ссылка на проблему) : https://en.cppreference.com/w/cpp/numeric/random/exponential_distribution

Переключение на double не решает эту проблему, а скорее уменьшает вероятность ее увидеть (или, по крайней мере, делает ее незначительной) , Как указывает проблема LWG, основная проблема заключается в том, что generate_canonical (который могут использовать некоторые реализации) может возвращать 1.0 в редких случаях, так что -log(1-generate_canonical()) может выводить бесконечность. На практике это было более вероятно с float, чем с double, поскольку число generate_canonical, которое можно получить с float, значительно меньше, чем с double (на практике 2 ^ 24 вместо 2 ^ 53 ). (В любом случае есть другие проблемы с наивными реализациями распределений с прямым хвостом, например, экспоненциальное распределение; см. « Восстановление вашей функции квантиля ».)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...