<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jun 3, 2018 at 8:21 PM, Robert Kern <span dir="ltr"><<a href="mailto:robert.kern@gmail.com" target="_blank">robert.kern@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Moving some of the Github PR comments here:<div><br><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Implementation</div><div>--------------</div><div><br></div><div>We propose first freezing ``RandomState`` as it is and developing a new RNG</div><div>subsystem alongside it.  This allows anyone who has been relying on our old</div><div>stream-compatibility guarantee to have plenty of time to migrate.</div><div>``RandomState`` will be considered deprecated, but with a long deprecation</div><div>cycle, at least a few years.</div></div></blockquote><div><br></div></span><div><div style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><span style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><a href="https://github.com/numpy/numpy/pull/11229#discussion_r192604195" target="_blank">https://github.com/numpy/<wbr>numpy/pull/11229#discussion_<wbr>r192604195</a></span><br clear="all" style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">@bashtage writes:<br class="m_-2867197254728711193gmail-Apple-interchange-newline"></div>> RandomState could pretty easily be spun out into a stand-alone package, if useful. It is effectively a stand-alone submodule already.<br style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><br></div><div>Indeed. That would be a graceful forever-home for the code for anyone who needs it. However, I'd still only make that switch after at least a few years of deprecation inside numpy. And maybe a 2.0.0 release.</div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>Any new design for the RNG subsystem will provide a choice of different core</div><div>uniform PRNG algorithms.  We will be more strict about a select subset of</div><div>methods on these core PRNG objects.  They MUST guarantee stream-compatibility</div><div>for a minimal, specified set of methods which are chosen to make it easier to</div><div>compose them to build other distributions.  Namely,</div><div><br></div><div>    * ``.bytes()``</div><div>    * ``.random_uintegers()``</div></div></div></blockquote></span></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>    * ``.random_sample()``</div></div></div></blockquote><div><br></div><div><div class="gmail_quote" style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><div>BTW, `random_uintegers()` is a new method in Kevin Sheppard's `randomgen`, and I am referring to its semantics here.</div><div><a href="https://github.com/bashtage/randomgen/blob/master/randomgen/generator.pyx#L191" target="_blank">https://github.com/bashtage/<wbr>randomgen/blob/master/<wbr>randomgen/generator.pyx#L191</a><br></div><div><br></div><div><a href="https://github.com/numpy/numpy/pull/11229#discussion_r192604275" target="_blank">https://github.com/numpy/<wbr>numpy/pull/11229#discussion_<wbr>r192604275</a><br></div><div><a class="gmail_plusreply" id="m_-2867197254728711193gmail-plusReplyChip-1" style="color:rgb(34,34,34)">@bashtage writes:</a><br></div>> One of these (bytes, uintegers) seems redundant. uintegers should probably by 64 bit.</div><div class="gmail_quote" style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><br></div><div class="gmail_quote" style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial">Because different core generators have different "native" outputs (MT19937, PCG32 output `uint32`s, PCG64 outputs `uint64`s, and some that I hope we never implement natively output doubles), there are some simple, but non-trivial choices to make to support each of these. I would like the core generator's author to make those choices and maintain them. They're not hard, but they are the kind of thing that ought to be decided once and consistently.</div><div class="gmail_quote" style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><br></div><div class="gmail_quote" style="color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial">I am of the opinion that `uintegers` should support at least `uint32` and `uint64` as those are the most common native outputs among core generators. There should be a maintained way to get that native format (and yes, I'd rather have the user be explicit about it than have `random_native_uint()` in addition to `random_uint64()`).<br><div> </div><div>This argument extends to `.bytes()`, too, now that I think about it. A stream of bytes is a native format for some generators, too, like if we decide to hook up /dev/urandom or other file-backed interface.</div><div><br></div><div>Hmm, what do you think about adding `random_interval()` to this list? And raising that up to the Python API level (a la what Python 3 did with exposing `secrets.randbelow()` as a primitive)?</div><div><a href="https://github.com/bashtage/randomgen/blob/master/randomgen/src/distributions/distributions.c#L1164-L1200" target="_blank">https://github.com/bashtage/<wbr>randomgen/blob/master/<wbr>randomgen/src/distributions/<wbr>distributions.c#L1164-L1200</a><br></div><div><br></div><div>Many, many uses of this method would be with numbers much less than 1<<32 (e.g. Fisher-Yates shuffle), and for the 32-bit native PRNGs could mean using half as many core PRNG draws if `random_interval()` is implemented along with the core PRNG to make use of that fact.</div><div><br></div></div></div><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>The list of ``StableRandom`` methods should be chosen to support unit tests:</div><div><br></div><div>    * ``.randint()``</div><div>    * ``.uniform()``</div><div>    * ``.normal()``</div><div>    * ``.standard_normal()``</div><div>    * ``.choice()``</div><div>    * ``.shuffle()``</div><div>    * ``.permutation()``</div></div></div></blockquote><div><br></div></span><div><a href="https://github.com/numpy/numpy/pull/11229#discussion_r192604311" target="_blank">https://github.com/numpy/<wbr>numpy/pull/11229#discussion_<wbr>r192604311</a><br></div><div>@bashtage writes:<br></div>> standard_gamma and standard_exponential are important enough to be included here IMO.<div><br></div><div>"Importance" was not my criterion, only whether they are used in unit test suites. This list was just off the top of my head for methods that I think were actually used in test suites, so I'd be happy to be shown live tests that use other methods. I'd like to be a *little* conservative about what methods we stick in here, but we don't have to be *too* conservative, since we are explicitly never going to be modifying these.</div></div></div></div></blockquote><div><br></div><div>That's one area where I thought the selection is too narrow.</div><div>We should be able to get a stable stream from the uniform for some distributions.</div><div><br></div><div>However, according to the Wikipedia description Poisson doesn't look easy. I just wrote a unit test for statsmodels using Poisson random numbers with hard coded numbers for the regression tests.</div><div>I'm not sure which other distributions are common enough and not easily reproducible by transformation. E.g. negative binomial can be reproduces by a gamma-poisson mixture.</div><div><br></div><div>On the other hand normal can be easily recreated from standard_normal.</div><div><br></div><div>Would it be difficult to keep this list large, given that it should be frozen, low maintenance code ?</div><div><br></div><div><br></div><div>Josef</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="gmail_quote"><span class="HOEnZb"><font color="#888888"><div><br></div></font></span></div><span class="HOEnZb"><font color="#888888">-- <br><div dir="ltr" class="m_-2867197254728711193gmail_signature">Robert Kern</div></font></span></div></div>
<br>______________________________<wbr>_________________<br>
NumPy-Discussion mailing list<br>
<a href="mailto:NumPy-Discussion@python.org">NumPy-Discussion@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/numpy-discussion" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/numpy-<wbr>discussion</a><br>
<br></blockquote></div><br></div></div>