Std::normal_distribution result for the same generator value?

Marcin

New Member
#1
I noticed a very weird behavior with GNU C++ standard library.

When using a custom generator with normal distribution, it seems the distribution might return different values even for the same generator result.

Example code
Mã:
#include <iostream>
#include <string>
#include <random>

template <int MAX>
class Generator
{
public:
  long long operator()() {return (++state) % MAX;}
  long long min() {return 0;}
  long long max() {return MAX;}
  long long state = 0;
};

int main()
{
  // 3 identical generators, 2 identical distributions
  Generator<5> gen0, gen1, gen2;
  std::normal_distribution<float> dist1(10, 1), dist2(10,1);

  // Print: iteration, generator output, distributions output
  printf("i   gen       dist1      dist2\n");   
  for (int i = 0; i < 10; i++) {
    printf("%d     %lld  %10.6f %10.6f\n", i, gen0(), dist1(gen1), dist2(gen2));
    dist2.reset();
  }

}
This produces (g++ 6.2.1, same on newer ones):
Mã:
i   gen       dist1      dist2
0     1   11.295982  11.295982
1     2    9.325577  10.256990
2     3   10.256990   9.672720
3     4    8.679697   9.300377
4     0    9.672720   8.957100
5     1    9.097454  11.295982
6     2    9.300377  10.256990
7     3   10.582899   9.672720
8     4    8.957100   9.300377
9     0   10.169774   8.957100
See how the dist1 results in rows 0 and 5 are different, even though generator produces the same value 1. For dist2, they're the same, as we call reset().

Btw, the reason seems to be that the GNU C++ library generates values in pairs, and caches them between the calls, not necessarily calling the generator. This also explains why dist1 row 4 is the same as dist2 (which resets the distribution) row 2.

I searched in the documentation, but I couldn't figure out if this behavior is standard compliant. Hence, I don't know if it's a standard library bug :)

Note, from what I saw, std::normal_distribution is the only class exhibiting this behavior.
 

Admin

Administrator
Thành viên BQT
#2
It's standard compliant. There is no requirement that the generator be stateless. If there were, the reset function would serve no purpose.
 

Từ khóa phổ biến

You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an alternative browser.

Top