C++ Logo

std-proposals

Advanced search

Re: Comments for P0205 and P2060: Mersenne twister can actually generate 7 and 13

From: Jason McKesson <jmckesson_at_[hidden]>
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.

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