Я использую Mersenne twister, чтобы иметь согласованные случайные значения между проектами в Matlab и C++. Но я не смог получить согласованные нормально распределенные псевдослучайные значения при использовании randn
или C++ 11 normal_distribution
.
Здесь C++:
void main()
{
unsigned int mersenneSeed = 1977;
std::mt19937_64 generator; // it doesn't matter if I use the 64 or the std::mt19937
generator.seed(mersenneSeed);
std::normal_distribution<double> normal; // default is 0 mean and 1.0 std
double temp = normal(generator);
// results 1.4404780513814264 for mt19937_64 and 1.8252033038258377 for mt19937
}
Здесь Matlab:
rng(1977) % default Matlab uses mersenne twister
randn() % default is 0 mean and 1.0 std
Я использую Matlab 2013b и Visual Studio Express 2013. Я что-то не так с нормальным распределением C++ 11?
Сам Mersenne twister производит только 32-битные целочисленные случайные числа. Наиболее вероятным объяснением несоответствия, которое вы наблюдаете, является способ преобразования этих равномерно распределенных целых чисел в нормально распределенные числа с плавающей запятой с двойной точностью.
Поскольку документация randn
не объясняет это преобразование, а исходный код недоступен (это встроенная функция), сложно сказать об этом без обратной инженерии. (Согласно комментарию Кейси, то же самое похоже на сторону C++.)
Самый простой способ добиться согласованности, вероятно, состоял бы в том, чтобы генерировать случайные числа в C++ или Matlab, сохранять результаты и загружать их по мере необходимости. Альтернативой было бы написать собственную функцию случайного числа Matlab в C++ в виде файла MEX (используя C++ normal_distribution
) и использовать эту функцию в Matlab вместо randn
.
rng
дляrng
и вашего кода, вероятно, также совершенно разные.