为什么 c++11 std::normal_distribution 在从函数调用时返回相同的模式?
Why c++11 std::normal_distribution return same pattern when called from a function?
我想在信号中引入高斯噪声。我研究了如何使用 C++11std::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;
}
当我从main()
多次调用dist()
时,这非常有效,并且也适用于不同的向量,但是一旦我将代码移动到函数,它总是返回相同的恒定噪声模式,我想调用此函数来修改参考信号并将其分配给不同的数组或向量。这是我的代码:
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()
编辑:
我在Windows 7中使用MinGW-W64-builds-4.3.5
这很可能与 mingw 中的一个功能/错误有关,它使std::random_device
确定性。您可以通过添加另一个熵源来规避这一点,例如当前时间:
uint64_t seed = std::random_device{}() |
std::chrono::system_clock::now().time_since_epoch().count();
但是,更好的解决方案是仅使用一个引擎和分发对象。实现此目的的一种简单方法是在新函数中使用静态变量。
相关文章:
- 返回复合模式的复合对象不返回整个对象
- 为什么 c++11 std::normal_distribution 在从函数调用时返回相同的模式?
- boost::create_directory 在发布模式下返回异常
- 如何在另一个线程中关闭 MFC 模式对话框并获取对话框返回值?
- 从C 中的函数中动态分配的缓冲区返回的最佳模式是什么?
- 模式返回伪随机数生成器
- 返回不同类型/类的方法的设计模式
- 将模式包装为 std::begin; 返回 begin(c); 到函数中
- Q::比例高度变换模式返回空图像
- 为什么将boost::move()的返回值分配给非常数引用在C++0x模式下失败,但在C++03模式下有效
- 可能返回值也可能不返回值的函数的迭代器缩减器模式
- 使用具有返回值的访客模式实现 AST 的最佳方法是什么?
- 返回一组数据类型之一的最佳模式
- 工厂函数返回元组的C++11模式
- 如何在不使用非构造函数的方法的情况下应用singleton设计模式来返回类对象
- 这是一个设计模式吗?从setters返回
- 只有在使用消息模式时,GetLastError()才会在调用PeekNamedPipe后返回ERROR_BROKEN_P
- 从访问者模式返回一个值
- 设计模式-在C++中返回对象集合的函数
- 为返回对象和NRVO的方法设计模式