Issue |
140133
|
Summary |
normal distribution implementation
|
Labels |
new issue
|
Assignees |
|
Reporter |
francois-rincon
|
Hello,
apologies for the possible bad formating of my issue, I'm not used to report.
trying to debug my code accross platforms and compilers, I found that the implementation of the normal distribution std::normal_distribution (normal_distribution.h) differs between gnu c++ and llvm.
The normal distribution generator takes two uniform random numbers in input, and can also output two random numbers. So when it is called one time, it saves the second number as the output of the next possible call.
The polar formula of Marsaglia is used to generate these numbers, but the order in which they are sent in output in two consecutive calls is permuted between gnu c++ and llvm.
This makes the code output differ depending on the compilers. It's a pity because the uniform number generation based on the mersenne twister appears to be deterministic between platforms, so I would have thought the whole code in <random> would be intended to be deterministic (and unfortunately I was inclined to think so after reading some comments about std::random on stackoverflow).
Would this be considered something worth patching ? Thanks !
--
LLVM return __u * __fp first time, __v * __fp second time
if (__v_hot_) {
__v_hot_ = false;
__up = __v_;
} else {
uniform_real_distribution<result_type> __uni(-1, 1);
result_type __u;
result_type __v;
result_type __s;
do {
__u = __uni(__g);
__v = __uni(__g);
__s = __u * __u + __v * __v;
} while (__s > 1 || __s == 0);
result_type __fp = std::sqrt(-2 * std::log(__s) / __s);
__v_ = __v * __fp;
__v_hot_ = true;
__up = __u * __fp;
}
GNU C++ returns __y*__mult first time, __x*__mult second time
if (_M_saved_available)
{
_M_saved_available = false;
__ret = _M_saved;
}
else
{
result_type __x, __y, __r2;
do
{
__x = result_type (2.0) * __aurng() - 1.0;
__y = result_type (2.0) * __aurng() - 1.0;
__r2 = __x * __x + __y * __y;
}
while (__r2 > 1.0 || __r2 == 0.0);
const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
_M_saved = __x * __mult;
_M_saved_available = true;
__ret = __y * __mult;
}
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs