Date: Wed, 17 Nov 2021 18:20:40 -0500

On Wed, Nov 17, 2021 at 6:06 PM Dimitrij Mijoski via Std-Proposals

<std-proposals_at_[hidden]> wrote:

>

> Hello,

>

> On Wed, 2021-11-17 at 21:06 +0000, Lénárd Szolnoki via Std-Proposals

> wrote:

> > Hi,

> >

> > On Wed, 17 Nov 2021 18:26:41 +0000

> > Dimitrij Mijoski via Std-Proposals <std-proposals_at_[hidden]>

> > wrote:

> >

> > > The papers P0205<https://wg21.link/p0205> and

> > > P2060<https://wg21.link/p2060> like to improve the code for proper

> > > seeding of the standard Mersenne twister. Both papers cite the

> > > following article

> > > https://www.pcg-random.org/posts/cpp-seeding-surprises.html by

> > > Melissa O’Neill. I will start with that article and their claim that

> > > the standard Mersenne twister (std::mt19937) can never produce some

> > > integers on the first call after seeding. In particular, the numbers

> > > 7 are 13 are mentioned. I state that such claim is false with a

> > > simple counterexample in code.

> > >

> > > #include <random>

> > > #include <cassert>

> > >

> > > using namespace std;

> > >

> > > int main()

> > > {

> > > auto rnd = mt19937(1080100664);

> > > assert(rnd() == 7);

> > >

> > > rnd = mt19937(736640520);

> > > assert(rnd() == 7);

> > >

> > > rnd = mt19937(1292535796);

> > > assert(rnd() == 13);

> > > }

> >

> > Consider the following code:

> >

> > #include <random>

> >

> > using gen = std::mt19937;

> > using res_t = gen::result_type;

> >

> > res_t foo(res_t x) {

> > gen g(x);

> > return g();

> > }

> >

> > `foo` is a pure function. You demonstrated that foo(1080100664) ==

> > foo(736640520) == 7 . Since the range and domain are the same finite

> > sets, it follows that there must be some number that can never be the

> > return value of `foo`.

>

> Yes, you are correct about this. Since 7 is returned at least twice,

> some other number isn't returned at all. But...

>

>

>

> >

> > I don't know how the author of the original article made the mistake,

> > but the point still stands: there are some numbers that can never occur

> > as the first number from a generator seeded from a single number,

> > unless a function similar to `foo` above happens to be a bijection for

> > the given generator.

>

> The point is true but is not useful and even dangerous to take it into

> consideration. The point of all PRNGs is to call them multiple times.

That's missing the forest for the trees. Even if you call the engine

multiple times, you still call it *at least* once. Which means that

you will be getting a biased result, based on whatever engine you are

using. The results may eventually even out, but they will start off

worse than they need to.

I see nothing dangerous about shoving as much randomness at an engine

as it can take.

<std-proposals_at_[hidden]> wrote:

>

> Hello,

>

> On Wed, 2021-11-17 at 21:06 +0000, Lénárd Szolnoki via Std-Proposals

> wrote:

> > Hi,

> >

> > On Wed, 17 Nov 2021 18:26:41 +0000

> > Dimitrij Mijoski via Std-Proposals <std-proposals_at_[hidden]>

> > wrote:

> >

> > > The papers P0205<https://wg21.link/p0205> and

> > > P2060<https://wg21.link/p2060> like to improve the code for proper

> > > seeding of the standard Mersenne twister. Both papers cite the

> > > following article

> > > https://www.pcg-random.org/posts/cpp-seeding-surprises.html by

> > > Melissa O’Neill. I will start with that article and their claim that

> > > the standard Mersenne twister (std::mt19937) can never produce some

> > > integers on the first call after seeding. In particular, the numbers

> > > 7 are 13 are mentioned. I state that such claim is false with a

> > > simple counterexample in code.

> > >

> > > #include <random>

> > > #include <cassert>

> > >

> > > using namespace std;

> > >

> > > int main()

> > > {

> > > auto rnd = mt19937(1080100664);

> > > assert(rnd() == 7);

> > >

> > > rnd = mt19937(736640520);

> > > assert(rnd() == 7);

> > >

> > > rnd = mt19937(1292535796);

> > > assert(rnd() == 13);

> > > }

> >

> > Consider the following code:

> >

> > #include <random>

> >

> > using gen = std::mt19937;

> > using res_t = gen::result_type;

> >

> > res_t foo(res_t x) {

> > gen g(x);

> > return g();

> > }

> >

> > `foo` is a pure function. You demonstrated that foo(1080100664) ==

> > foo(736640520) == 7 . Since the range and domain are the same finite

> > sets, it follows that there must be some number that can never be the

> > return value of `foo`.

>

> Yes, you are correct about this. Since 7 is returned at least twice,

> some other number isn't returned at all. But...

>

>

>

> >

> > I don't know how the author of the original article made the mistake,

> > but the point still stands: there are some numbers that can never occur

> > as the first number from a generator seeded from a single number,

> > unless a function similar to `foo` above happens to be a bijection for

> > the given generator.

>

> The point is true but is not useful and even dangerous to take it into

> consideration. The point of all PRNGs is to call them multiple times.

That's missing the forest for the trees. Even if you call the engine

multiple times, you still call it *at least* once. Which means that

you will be getting a biased result, based on whatever engine you are

using. The results may eventually even out, but they will start off

worse than they need to.

I see nothing dangerous about shoving as much randomness at an engine

as it can take.

Received on 2021-11-17 17:20:53