Почему c ++ 11 std :: normal_distribution возвращает тот же шаблон при вызове из функции? - PullRequest
0 голосов
/ 20 сентября 2018

Я хочу ввести гауссов шум в сигнал.Я рассмотрел несколько примеров использования C ++ 11 std::normal_distribution и смог получить ожидаемый случайный результат, используя этот пример: https://stackoverflow.com/a/32890945/3424478

#include <functional>
#include <iostream>
#include <iterator>
#include <random>

int main() {
    // Example data
    std::vector<double> data = {1., 2., 3., 4., 5., 6.};

    // Define random generator with Gaussian distribution
    const double mean = 0.0;
    const double stddev = 0.1;
    auto dist = std::bind(std::normal_distribution<double>{mean, stddev},
                          std::mt19937(std::random_device{}()));

    // Add Gaussian noise
    for (auto& x : data) {
        x = x + dist();
    }

    // Output the result, for demonstration purposes
    std::copy(begin(data), end(data), std::ostream_iterator<double>(std::cout, " "));
    std::cout << "\n";

    return 0;
}

Это прекрасно работает, пока яВызовите dist() несколько раз из main(), а также отлично работает с разными векторами, но как только я перемещаю код в функцию, он всегда возвращает один и тот же шаблон постоянного шума, я хочу вызвать эту функцию, чтобы изменить опорный сигнал и назначитьэто разные массивы или векторы.Вот мой код:

void AddGaussianNoiseToPixel(std::array<short int, N_SLICES>& pixel_array, const std::array<short int, N_SLICES>& reference_pixel)
{
    const float mean   = 0.0;
    const float stddev = 2.0;
    auto dist = std::bind(std::normal_distribution<float>{mean, stddev},
                          std::mt19937(std::random_device{}()));

    for (const auto& slice : reference_pixel) 
    {
        pixel_array[&slice-&reference_pixel[0]] = rint(slice+dist());
    }
}

Я прочитал похожий пост: https://stackoverflow.com/a/22921927/3424478, где это должно происходить из-за семян, переданных генератору случайных чисел, но это не так, так как япередача std::random_device{}() случайному движку std::mt19937()

РЕДАКТИРОВАТЬ:

Я использую MinGW-W64-builds-4.3.5 в Windows 7

1 Ответ

0 голосов
/ 20 сентября 2018

Скорее всего, это связано с функцией / ошибкой в ​​mingw , которая делает std::random_device детерминированной.Вы можете обойти это, добавив другой источник энтропии, например, текущее время:

  uint64_t seed = std::random_device{}() |
    std::chrono::system_clock::now().time_since_epoch().count();

Однако лучшее решение состоит в том, чтобы использовать только один движок и объект распределения.Простой способ сделать это - использовать статическую переменную в новой функции.

...