-
Notifications
You must be signed in to change notification settings - Fork 6
/
nep-0019-rng-policy.html
877 lines (688 loc) · 51.4 KB
/
nep-0019-rng-policy.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
<!DOCTYPE html>
<html lang="en" data-content_root="./" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>NEP 19 — Random number generator policy — NumPy Enhancement Proposals</title>
<script data-cfasync="false">
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
</script>
<!--
this give us a css class that will be invisible only if js is disabled
-->
<noscript>
<style>
.pst-js-only { display: none !important; }
</style>
</noscript>
<!-- Loaded before other Sphinx assets -->
<link href="_static/styles/theme.css?digest=26a4bc78f4c0ddb94549" rel="stylesheet" />
<link href="_static/styles/pydata-sphinx-theme.css?digest=26a4bc78f4c0ddb94549" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=fa44fd50" />
<!-- So that users can add custom icons -->
<script src="_static/scripts/fontawesome.js?digest=26a4bc78f4c0ddb94549"></script>
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="_static/scripts/bootstrap.js?digest=26a4bc78f4c0ddb94549" />
<link rel="preload" as="script" href="_static/scripts/pydata-sphinx-theme.js?digest=26a4bc78f4c0ddb94549" />
<script src="_static/documentation_options.js?v=7f41d439"></script>
<script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script>DOCUMENTATION_OPTIONS.pagename = 'nep-0019-rng-policy';</script>
<link rel="icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="NEP 20 — Expansion of generalized universal function signatures" href="nep-0020-gufunc-signature-enhancement.html" />
<link rel="prev" title="NEP 18 — A dispatch mechanism for NumPy’s high level array functions" href="nep-0018-array-function-protocol.html" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="docsearch:language" content="en"/>
<meta name="docsearch:version" content="" />
<meta name="docbuild:last-update" content="Nov 15, 2024"/>
</head>
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
<div id="pst-scroll-pixel-helper"></div>
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
<dialog id="pst-search-dialog">
<form class="bd-search d-flex align-items-center"
action="search.html"
method="get">
<i class="fa-solid fa-magnifying-glass"></i>
<input type="search"
class="form-control"
name="q"
placeholder="Search the docs ..."
aria-label="Search the docs ..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</form>
</dialog>
<div class="pst-async-banner-revealer d-none">
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
</div>
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
<div class="bd-header__inner bd-page-width">
<button class="pst-navbar-icon sidebar-toggle primary-toggle" aria-label="Site navigation">
<span class="fa-solid fa-bars"></span>
</button>
<div class="col-lg-3 navbar-header-items__start">
<div class="navbar-item">
<a class="navbar-brand logo" href="content.html">
<img src="_static/numpylogo.svg" class="logo__image only-light" alt="NumPy Enhancement Proposals - Home"/>
<img src="_static/numpylogo.svg" class="logo__image only-dark pst-js-only" alt="NumPy Enhancement Proposals - Home"/>
</a></div>
</div>
<div class="col-lg-9 navbar-header-items">
<div class="me-auto navbar-header-items__center">
<div class="navbar-item">
<nav>
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item current active">
<a class="nav-link nav-internal" href="index.html">
Index
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-internal" href="scope.html">
The Scope of NumPy
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-internal" href="roadmap.html">
Current roadmap
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/numpy/numpy/issues?q=is%3Aopen+is%3Aissue+label%3A%2223+-+Wish+List%22">
Wish list
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/numpy/numpy/issues?q=is%3Aopen+is%3Aissue+label%3A%2223+-+Wish+List%22">
Wishlist
</a>
</li>
</ul>
</nav></div>
</div>
<div class="navbar-header-items__end">
<div class="navbar-item navbar-persistent--container">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
<div class="navbar-item"><ul class="navbar-icon-links"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://github.com/numpy/numpy" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-square-github fa-lg" aria-hidden="true"></i>
<span class="sr-only">GitHub</span></a>
</li>
</ul></div>
</div>
</div>
<div class="navbar-persistent--mobile">
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
</div>
<button class="pst-navbar-icon sidebar-toggle secondary-toggle" aria-label="On this page">
<span class="fa-solid fa-outdent"></span>
</button>
</div>
</header>
<div class="bd-container">
<div class="bd-container__inner bd-page-width">
<dialog id="pst-primary-sidebar-modal"></dialog>
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar">
<div class="sidebar-header-items sidebar-primary__section">
<div class="sidebar-header-items__center">
<div class="navbar-item">
<nav>
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item current active">
<a class="nav-link nav-internal" href="index.html">
Index
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-internal" href="scope.html">
The Scope of NumPy
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-internal" href="roadmap.html">
Current roadmap
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/numpy/numpy/issues?q=is%3Aopen+is%3Aissue+label%3A%2223+-+Wish+List%22">
Wish list
</a>
</li>
<li class="nav-item ">
<a class="nav-link nav-external" href="https://github.com/numpy/numpy/issues?q=is%3Aopen+is%3Aissue+label%3A%2223+-+Wish+List%22">
Wishlist
</a>
</li>
</ul>
</nav></div>
</div>
<div class="sidebar-header-items__end">
<div class="navbar-item">
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
</button></div>
<div class="navbar-item"><ul class="navbar-icon-links"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://github.com/numpy/numpy" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-square-github fa-lg" aria-hidden="true"></i>
<span class="sr-only">GitHub</span></a>
</li>
</ul></div>
</div>
</div>
<div class="sidebar-primary-items__start sidebar-primary__section">
<div class="sidebar-primary-item">
<nav class="bd-docs-nav bd-links"
aria-label="Section Navigation">
<p class="bd-links__title" role="heading" aria-level="1">Section Navigation</p>
<div class="bd-toc-item navbar-nav"><ul class="nav bd-sidenav">
<li class="toctree-l1"><a class="reference internal" href="scope.html">The Scope of NumPy</a></li>
<li class="toctree-l1"><a class="reference internal" href="roadmap.html">Current roadmap</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/numpy/numpy/issues?q=is%3Aopen+is%3Aissue+label%3A%2223+-+Wish+List%22">Wish list</a></li>
</ul>
<ul class="current nav bd-sidenav">
<li class="toctree-l1 has-children"><a class="reference internal" href="meta.html">Meta-NEPs (NEPs about NEPs or active Processes)</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="nep-0000.html">NEP 0 — Purpose and process</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0023-backwards-compatibility.html">NEP 23 — Backwards compatibility and deprecation policy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0036-fair-play.html">NEP 36 — Fair play</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0045-c_style_guide.html">NEP 45 — C style guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0046-sponsorship-guidelines.html">NEP 46 — NumPy sponsorship guidelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0048-spending-project-funds.html">NEP 48 — Spending NumPy project funds</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-template.html">NEP X — Template and instructions</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="provisional.html">Provisional NEPs (provisionally accepted; interface may change)</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul class="simple">
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="accepted.html">Accepted NEPs (implementation in progress)</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="nep-0041-improved-dtype-support.html">NEP 41 — First step towards a new datatype system</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0042-new-dtypes.html">NEP 42 — New and extensible DTypes</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0044-restructuring-numpy-docs.html">NEP 44 — Restructuring the NumPy documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0051-scalar-representation.html">NEP 51 — Changing the representation of NumPy scalars</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="open.html">Open NEPs (under consideration)</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="nep-0043-extensible-ufuncs.html">NEP 43 — Enhancing the extensibility of UFuncs</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0053-c-abi-evolution.html">NEP 53 — Evolving the NumPy C-API for NumPy 2.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0054-simd-cpp-highway.html">NEP 54 — SIMD infrastructure evolution: adopting Google Highway when moving to C++?</a></li>
</ul>
</details></li>
<li class="toctree-l1 current active has-children"><a class="reference internal" href="finished.html">Finished NEPs</a><details open="open"><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="nep-0001-npy-format.html">NEP 1 — A simple file format for NumPy arrays</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0005-generalized-ufuncs.html">NEP 5 — Generalized universal functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0007-datetime-proposal.html">NEP 7 — A proposal for implementing some date/time types in NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0010-new-iterator-ufunc.html">NEP 10 — Optimizing iterator/UFunc performance</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0013-ufunc-overrides.html">NEP 13 — A mechanism for overriding Ufuncs</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0014-dropping-python2.7-proposal.html">NEP 14 — Plan for dropping Python 2.7 support</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0015-merge-multiarray-umath.html">NEP 15 — Merging multiarray and umath</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0018-array-function-protocol.html">NEP 18 — A dispatch mechanism for NumPy's high level array functions</a></li>
<li class="toctree-l2 current active"><a class="current reference internal" href="#">NEP 19 — Random number generator policy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0020-gufunc-signature-enhancement.html">NEP 20 — Expansion of generalized universal function signatures</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0022-ndarray-duck-typing-overview.html">NEP 22 — Duck typing for NumPy arrays – high level overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0027-zero-rank-arrarys.html">NEP 27 — Zero rank arrays</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0028-website-redesign.html">NEP 28 — numpy.org website redesign</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0029-deprecation_policy.html">NEP 29 — Recommend Python and NumPy version support as a community policy standard</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0032-remove-financial-functions.html">NEP 32 — Remove the financial functions from NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0034-infer-dtype-is-object.html">NEP 34 — Disallow inferring ``dtype=object`` from sequences</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0035-array-creation-dispatch-with-array-function.html">NEP 35 — Array creation dispatching with __array_function__</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0038-SIMD-optimizations.html">NEP 38 — Using SIMD optimization instructions for performance</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0040-legacy-datatype-impl.html">NEP 40 — Legacy datatype implementation in NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0049.html">NEP 49 — Data allocation strategies</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0050-scalar-promotion.html">NEP 50 — Promotion rules for Python scalars</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0052-python-api-cleanup.html">NEP 52 — Python API cleanup for NumPy 2.0</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0055-string_dtype.html">NEP 55 — Add a UTF-8 variable-width string DType to NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0056-array-api-main-namespace.html">NEP 56 — Array API standard support in NumPy's main namespace</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="deferred.html">Deferred and Superseded NEPs</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="nep-0002-warnfix.html">NEP 2 — A proposal to build numpy without warning with a big set of warning flags</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0003-math_config_clean.html">NEP 3 — Cleaning the math configuration of numpy.core</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0004-datetime-proposal3.html">NEP 4 — A (third) proposal for implementing some date/time types in NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0006-newbugtracker.html">NEP 6 — Replacing Trac with a different bug tracker</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0008-groupby_additions.html">NEP 8 — A proposal for adding groupby functionality to NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0009-structured_array_extensions.html">NEP 9 — Structured array extensions</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0011-deferred-ufunc-evaluation.html">NEP 11 — Deferred UFunc evaluation</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0012-missing-data.html">NEP 12 — Missing data functionality in NumPy</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0021-advanced-indexing.html">NEP 21 — Simplified and explicit advanced indexing</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0024-missing-data-2.html">NEP 24 — Missing data functionality - alternative 1 to NEP 12</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0025-missing-data-3.html">NEP 25 — NA support via special dtypes</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0026-missing-data-summary.html">NEP 26 — Summary of missing data NEPs and discussion</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0030-duck-array-protocol.html">NEP 30 — Duck typing for NumPy arrays - implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0031-uarray.html">NEP 31 — Context-local and global overrides of the NumPy API</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0037-array-module.html">NEP 37 — A dispatch protocol for NumPy-like modules</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0047-array-api-standard.html">NEP 47 — Adopting the array API standard</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="rejected.html">Rejected and Withdrawn NEPs</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="nep-0016-abstract-array.html">NEP 16 — An abstract base class for identifying "duck arrays"</a></li>
<li class="toctree-l2"><a class="reference internal" href="nep-0017-split-out-maskedarray.html">NEP 17 — Split out masked arrays</a></li>
</ul>
</details></li>
</ul>
</div>
</nav></div>
</div>
<div class="sidebar-primary-items__end sidebar-primary__section">
</div>
<div id="rtd-footer-container"></div>
</div>
<main id="main-content" class="bd-main" role="main">
<div class="bd-content">
<div class="bd-article-container">
<div class="bd-header-article d-print-none">
<div class="header-article-items header-article__inner">
<div class="header-article-items__start">
<div class="header-article-item">
<nav aria-label="Breadcrumb" class="d-print-none">
<ul class="bd-breadcrumbs">
<li class="breadcrumb-item breadcrumb-home">
<a href="content.html" class="nav-link" aria-label="Home">
<i class="fa-solid fa-home"></i>
</a>
</li>
<li class="breadcrumb-item"><a href="index.html" class="nav-link">Roadmap & NumPy enhancement proposals</a></li>
<li class="breadcrumb-item"><a href="finished.html" class="nav-link">Finished NEPs</a></li>
<li class="breadcrumb-item active" aria-current="page"><span class="ellipsis">NEP 19 — Random number generator policy</span></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div id="searchbox"></div>
<article class="bd-article">
<section id="nep-19-random-number-generator-policy">
<span id="nep19"></span><h1>NEP 19 — Random number generator policy<a class="headerlink" href="#nep-19-random-number-generator-policy" title="Link to this heading">#</a></h1>
<dl class="field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd"><p>Robert Kern <<a class="reference external" href="mailto:robert.kern%40gmail.com">robert<span>.</span>kern<span>@</span>gmail<span>.</span>com</a>></p>
</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><p>Final</p>
</dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><p>Standards Track</p>
</dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even"><p>2018-05-24</p>
</dd>
<dt class="field-odd">Updated<span class="colon">:</span></dt>
<dd class="field-odd"><p>2019-05-21</p>
</dd>
<dt class="field-even">Resolution<span class="colon">:</span></dt>
<dd class="field-even"><p><a class="reference external" href="https://mail.python.org/pipermail/numpy-discussion/2018-July/078380.html">https://mail.python.org/pipermail/numpy-discussion/2018-July/078380.html</a></p>
</dd>
</dl>
<section id="abstract">
<h2>Abstract<a class="headerlink" href="#abstract" title="Link to this heading">#</a></h2>
<p>For the past decade, NumPy has had a strict backwards compatibility policy for
the number stream of all of its random number distributions. Unlike other
numerical components in <code class="docutils literal notranslate"><span class="pre">numpy</span></code>, which are usually allowed to return
different results when modified if the results remain correct, we have
obligated the random number distributions to always produce the exact same
numbers in every version. The objective of our stream-compatibility guarantee
was to provide exact reproducibility for simulations across numpy versions in
order to promote reproducible research. However, this policy has made it very
difficult to enhance any of the distributions with faster or more accurate
algorithms. After a decade of experience and improvements in the surrounding
ecosystem of scientific software, we believe that there are now better ways to
achieve these objectives. We propose relaxing our strict stream-compatibility
policy to remove the obstacles that are in the way of accepting contributions
to our random number generation capabilities.</p>
</section>
<section id="the-status-quo">
<h2>The status quo<a class="headerlink" href="#the-status-quo" title="Link to this heading">#</a></h2>
<p>Our current policy, in full:</p>
<blockquote>
<div><p>A fixed seed and a fixed series of calls to <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> methods using the
same parameters will always produce the same results up to roundoff error
except when the values were incorrect. Incorrect values will be fixed and
the NumPy version in which the fix was made will be noted in the relevant
docstring. Extension of existing parameter ranges and the addition of new
parameters is allowed as long the previous behavior remains unchanged.</p>
</div></blockquote>
<p>This policy was first instated in Nov 2008 (in essence; the full set of weasel
words grew over time) in response to a user wanting to be sure that the
simulations that formed the basis of their scientific publication could be
reproduced years later, exactly, with whatever version of <code class="docutils literal notranslate"><span class="pre">numpy</span></code> that was
current at the time. We were keen to support reproducible research, and it was
still early in the life of <code class="docutils literal notranslate"><span class="pre">numpy.random</span></code>. We had not seen much cause to
change the distribution methods all that much.</p>
<p>We also had not thought very thoroughly about the limits of what we really
could promise (and by “we” in this section, we really mean Robert Kern, let’s
be honest). Despite all of the weasel words, our policy overpromises
compatibility. The same version of <code class="docutils literal notranslate"><span class="pre">numpy</span></code> built on different platforms, or
just in a different way could cause changes in the stream, with varying degrees
of rarity. The biggest is that the <code class="docutils literal notranslate"><span class="pre">.multivariate_normal()</span></code> method relies on
<code class="docutils literal notranslate"><span class="pre">numpy.linalg</span></code> functions. Even on the same platform, if one links <code class="docutils literal notranslate"><span class="pre">numpy</span></code>
with a different LAPACK, <code class="docutils literal notranslate"><span class="pre">.multivariate_normal()</span></code> may well return completely
different results. More rarely, building on a different OS or CPU can cause
differences in the stream. We use C <code class="docutils literal notranslate"><span class="pre">long</span></code> integers internally for integer
distribution (it seemed like a good idea at the time), and those can vary in
size depending on the platform. Distribution methods can overflow their
internal C <code class="docutils literal notranslate"><span class="pre">longs</span></code> at different breakpoints depending on the platform and
cause all of the random variate draws that follow to be different.</p>
<p>And even if all of that is controlled, our policy still does not provide exact
guarantees across versions. We still do apply bug fixes when correctness is at
stake. And even if we didn’t do that, any nontrivial program does more than
just draw random numbers. They do computations on those numbers, transform
those with numerical algorithms from the rest of <code class="docutils literal notranslate"><span class="pre">numpy</span></code>, which is not
subject to so strict a policy. Trying to maintain stream-compatibility for our
random number distributions does not help reproducible research for these
reasons.</p>
<p>The standard practice now for bit-for-bit reproducible research is to pin all
of the versions of code of your software stack, possibly down to the OS itself.
The landscape for accomplishing this is much easier today than it was in 2008.
We now have <code class="docutils literal notranslate"><span class="pre">pip</span></code>. We now have virtual machines. Those who need to
reproduce simulations exactly now can (and ought to) do so by using the exact
same version of <code class="docutils literal notranslate"><span class="pre">numpy</span></code>. We do not need to maintain stream-compatibility
across <code class="docutils literal notranslate"><span class="pre">numpy</span></code> versions to help them.</p>
<p>Our stream-compatibility guarantee has hindered our ability to make
improvements to <code class="docutils literal notranslate"><span class="pre">numpy.random</span></code>. Several first-time contributors have
submitted PRs to improve the distributions, usually by implementing a faster,
or more accurate algorithm than the one that is currently there.
Unfortunately, most of them would have required breaking the stream to do so.
Blocked by our policy, and our inability to work around that policy, many of
those contributors simply walked away.</p>
</section>
<section id="implementation">
<h2>Implementation<a class="headerlink" href="#implementation" title="Link to this heading">#</a></h2>
<p>Work on a proposed new Pseudo Random Number Generator (PRNG) subsystem is
already underway in the <a class="reference external" href="https://github.com/bashtage/randomgen">randomgen</a>
project. The specifics of the new design are out of scope for this NEP and up
for much discussion, but we will discuss general policies that will guide the
evolution of whatever code is adopted. We will also outline just a few of the
requirements that such a new system must have to support the policy proposed in
this NEP.</p>
<p>First, we will maintain API source compatibility just as we do with the rest of
<code class="docutils literal notranslate"><span class="pre">numpy</span></code>. If we <em>must</em> make a breaking change, we will only do so with an
appropriate deprecation period and warnings.</p>
<p>Second, breaking stream-compatibility in order to introduce new features or
improve performance will be <em>allowed</em> with <em>caution</em>. Such changes will be
considered features, and as such will be no faster than the standard release
cadence of features (i.e. on <code class="docutils literal notranslate"><span class="pre">X.Y</span></code> releases, never <code class="docutils literal notranslate"><span class="pre">X.Y.Z</span></code>). Slowness will
not be considered a bug for this purpose. Correctness bug fixes that break
stream-compatibility can happen on bugfix releases, per usual, but developers
should consider if they can wait until the next feature release. We encourage
developers to strongly weight user’s pain from the break in
stream-compatibility against the improvements. One example of a worthwhile
improvement would be to change algorithms for a significant increase in
performance, for example, moving from the <a class="reference external" href="https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform">Box-Muller transform</a> method of
Gaussian variate generation to the faster <a class="reference external" href="https://en.wikipedia.org/wiki/Ziggurat_algorithm">Ziggurat algorithm</a>. An example of a
discouraged improvement would be tweaking the Ziggurat tables just a little bit
for a small performance improvement.</p>
<p>Any new design for the random subsystem will provide a choice of different core
uniform PRNG algorithms. A promising design choice is to make these core
uniform PRNGs their own lightweight objects with a minimal set of methods
(<a class="reference external" href="https://github.com/bashtage/randomgen">randomgen</a> calls them “BitGenerators”). The broader set of non-uniform
distributions will be its own class that holds a reference to one of these core
uniform PRNG objects and simply delegates to the core uniform PRNG object when
it needs uniform random numbers (<a class="reference external" href="https://github.com/bashtage/randomgen">randomgen</a> calls this the Generator). To
borrow an example from <a class="reference external" href="https://github.com/bashtage/randomgen">randomgen</a>, the
class <code class="docutils literal notranslate"><span class="pre">MT19937</span></code> is a BitGenerator that implements the classic Mersenne Twister
algorithm. The class <code class="docutils literal notranslate"><span class="pre">Generator</span></code> wraps around the BitGenerator to provide
all of the non-uniform distribution methods:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># This is not the only way to instantiate this object.</span>
<span class="c1"># This is just handy for demonstrating the delegation.</span>
<span class="o">>>></span> <span class="n">bg</span> <span class="o">=</span> <span class="n">MT19937</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">rg</span> <span class="o">=</span> <span class="n">Generator</span><span class="p">(</span><span class="n">bg</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">x</span> <span class="o">=</span> <span class="n">rg</span><span class="o">.</span><span class="n">standard_normal</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
</pre></div>
</div>
<p>We will be more strict about a select subset of methods on these BitGenerator
objects. They MUST guarantee stream-compatibility for a specified set
of methods which are chosen to make it easier to compose them to build other
distributions and which are needed to abstract over the implementation details
of the variety of BitGenerator algorithms. Namely,</p>
<blockquote>
<div><ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">.bytes()</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">integers()</span></code> (formerly <code class="docutils literal notranslate"><span class="pre">.random_integers()</span></code>)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">random()</span></code> (formerly <code class="docutils literal notranslate"><span class="pre">.random_sample()</span></code>)</p></li>
</ul>
</div></blockquote>
<p>The distributions class (<code class="docutils literal notranslate"><span class="pre">Generator</span></code>) SHOULD have all of the same
distribution methods as <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> with close-enough function signatures
such that almost all code that currently works with <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> instances
will work with <code class="docutils literal notranslate"><span class="pre">Generator</span></code> instances (ignoring the precise stream
values). Some variance will be allowed for integer distributions: in order to
avoid some of the cross-platform problems described above, these SHOULD be
rewritten to work with <code class="docutils literal notranslate"><span class="pre">uint64</span></code> numbers on all platforms.</p>
<section id="supporting-unit-tests">
<h3>Supporting Unit Tests<a class="headerlink" href="#supporting-unit-tests" title="Link to this heading">#</a></h3>
<p>Because we did make a strong stream-compatibility guarantee early in numpy’s
life, reliance on stream-compatibility has grown beyond reproducible
simulations. One use case that remains for stream-compatibility across numpy
versions is to use pseudorandom streams to generate test data in unit tests.
With care, many of the cross-platform instabilities can be avoided in the
context of small unit tests.</p>
<p>The new PRNG subsystem MUST provide a second, legacy distributions class that
uses the same implementations of the distribution methods as the current
version of <code class="docutils literal notranslate"><span class="pre">numpy.random.RandomState</span></code>. The methods of this class will have
strict stream-compatibility guarantees, even stricter than the current policy.
It is intended that this class will no longer be modified, except to keep it
working when numpy internals change. All new development should go into the
primary distributions class. Bug fixes that change the stream SHALL NOT be
made to <code class="docutils literal notranslate"><span class="pre">RandomState</span></code>; instead, buggy distributions should be made to warn
when they are buggy. The purpose of <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> will be documented as
providing certain fixed functionality for backwards compatibility and stable
numbers for the limited purpose of unit testing, and not making whole programs
reproducible across numpy versions.</p>
<p>This legacy distributions class MUST be accessible under the name
<code class="docutils literal notranslate"><span class="pre">numpy.random.RandomState</span></code> for backwards compatibility. All current ways of
instantiating <code class="docutils literal notranslate"><span class="pre">numpy.random.RandomState</span></code> with a given state should
instantiate the Mersenne Twister BitGenerator with the same state. The legacy
distributions class MUST be capable of accepting other BitGenerators. The
purpose
here is to ensure that one can write a program with a consistent BitGenerator
state with a mixture of libraries that may or may not have upgraded from
<code class="docutils literal notranslate"><span class="pre">RandomState</span></code>. Instances of the legacy distributions class MUST respond
<code class="docutils literal notranslate"><span class="pre">True</span></code> to <code class="docutils literal notranslate"><span class="pre">isinstance(rg,</span> <span class="pre">numpy.random.RandomState)</span></code> because there is
current utility code that relies on that check. Similarly, old pickles of
<code class="docutils literal notranslate"><span class="pre">numpy.random.RandomState</span></code> instances MUST unpickle correctly.</p>
</section>
<section id="numpy-random">
<h3><code class="docutils literal notranslate"><span class="pre">numpy.random.*</span></code><a class="headerlink" href="#numpy-random" title="Link to this heading">#</a></h3>
<p>The preferred best practice for getting reproducible pseudorandom numbers is to
instantiate a generator object with a seed and pass it around. The implicit
global <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> behind the <code class="docutils literal notranslate"><span class="pre">numpy.random.*</span></code> convenience functions can
cause problems, especially when threads or other forms of concurrency are
involved. Global state is always problematic. We categorically recommend
avoiding using the convenience functions when reproducibility is involved.</p>
<p>That said, people do use them and use <code class="docutils literal notranslate"><span class="pre">numpy.random.seed()</span></code> to control the
state underneath them. It can be hard to categorize and count API usages
consistently and usefully, but a very common usage is in unit tests where many
of the problems of global state are less likely.</p>
<p>This NEP does not propose removing these functions or changing them to use the
less-stable <code class="docutils literal notranslate"><span class="pre">Generator</span></code> distribution implementations. Future NEPs
might.</p>
<p>Specifically, the initial release of the new PRNG subsystem SHALL leave these
convenience functions as aliases to the methods on a global <code class="docutils literal notranslate"><span class="pre">RandomState</span></code>
that is initialized with a Mersenne Twister BitGenerator object. A call to
<code class="docutils literal notranslate"><span class="pre">numpy.random.seed()</span></code> will be forwarded to that BitGenerator object. In
addition, the global <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> instance MUST be accessible in this
initial release by the name <code class="docutils literal notranslate"><span class="pre">numpy.random.mtrand._rand</span></code>: Robert Kern long ago
promised <code class="docutils literal notranslate"><span class="pre">scikit-learn</span></code> that this name would be stable. Whoops.</p>
<p>In order to allow certain workarounds, it MUST be possible to replace the
BitGenerator underneath the global <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> with any other BitGenerator
object (we leave the precise API details up to the new subsystem). Calling
<code class="docutils literal notranslate"><span class="pre">numpy.random.seed()</span></code> thereafter SHOULD just pass the given seed to the
current BitGenerator object and not attempt to reset the BitGenerator to the
Mersenne Twister. The set of <code class="docutils literal notranslate"><span class="pre">numpy.random.*</span></code> convenience functions SHALL
remain the same as they currently are. They SHALL be aliases to the
<code class="docutils literal notranslate"><span class="pre">RandomState</span></code> methods and not the new less-stable distributions class
(<code class="docutils literal notranslate"><span class="pre">Generator</span></code>, in the examples above). Users who want to get the fastest, best
distributions can follow best practices and instantiate generator objects explicitly.</p>
<p>This NEP does not propose that these requirements remain in perpetuity. After
we have experience with the new PRNG subsystem, we can and should revisit these
issues in future NEPs.</p>
</section>
</section>
<section id="alternatives">
<h2>Alternatives<a class="headerlink" href="#alternatives" title="Link to this heading">#</a></h2>
<section id="versioning">
<h3>Versioning<a class="headerlink" href="#versioning" title="Link to this heading">#</a></h3>
<p>For a long time, we considered that the way to allow algorithmic improvements
while maintaining the stream was to apply some form of versioning. That is,
every time we make a stream change in one of the distributions, we increment
some version number somewhere. <code class="docutils literal notranslate"><span class="pre">numpy.random</span></code> would keep all past versions
of the code, and there would be a way to get the old versions.</p>
<p>We will not be doing this. If one needs to get the exact bit-for-bit results
from a given version of <code class="docutils literal notranslate"><span class="pre">numpy</span></code>, whether one uses random numbers or not, one
should use the exact version of <code class="docutils literal notranslate"><span class="pre">numpy</span></code>.</p>
<p>Proposals of how to do RNG versioning varied widely, and we will not
exhaustively list them here. We spent years going back and forth on these
designs and were not able to find one that sufficed. Let that time lost, and
more importantly, the contributors that we lost while we dithered, serve as
evidence against the notion.</p>
<p>Concretely, adding in versioning makes maintenance of <code class="docutils literal notranslate"><span class="pre">numpy.random</span></code>
difficult. Necessarily, we would be keeping lots of versions of the same code
around. Adding a new algorithm safely would still be quite hard.</p>
<p>But most importantly, versioning is fundamentally difficult to <em>use</em> correctly.
We want to make it easy and straightforward to get the latest, fastest, best
versions of the distribution algorithms; otherwise, what’s the point? The way
to make that easy is to make the latest the default. But the default will
necessarily change from release to release, so the user’s code would need to be
altered anyway to specify the specific version that one wants to replicate.</p>
<p>Adding in versioning to maintain stream-compatibility would still only provide
the same level of stream-compatibility that we currently do, with all of the
limitations described earlier. Given that the standard practice for such needs
is to pin the release of <code class="docutils literal notranslate"><span class="pre">numpy</span></code> as a whole, versioning <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> alone
is superfluous.</p>
</section>
<section id="stablerandom">
<h3><code class="docutils literal notranslate"><span class="pre">StableRandom</span></code><a class="headerlink" href="#stablerandom" title="Link to this heading">#</a></h3>
<p>A previous version of this NEP proposed to leave <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> completely
alone for a deprecation period and build the new subsystem alongside with new
names. To satisfy the unit testing use case, it proposed introducing a small
distributions class nominally called <code class="docutils literal notranslate"><span class="pre">StableRandom</span></code>. It would have provided
a small subset of distribution methods that were considered most useful in unit
testing, but not the full set such that it would be too likely to be used
outside of the testing context.</p>
<p>During discussion about this proposal, it became apparent that there was no
satisfactory subset. At least some projects used a fairly broad selection of
the <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> methods in unit tests.</p>
<p>Downstream project owners would have been forced to modify their code to
accommodate the new PRNG subsystem. Some modifications might be simply
mechanical, but the bulk of the work would have been tedious churn for no
positive improvement to the downstream project, just avoiding being broken.</p>
<p>Furthermore, under this old proposal, we would have had a quite lengthy
deprecation period where <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> existed alongside the new system of
BitGenerator and Generator classes. Leaving the implementation of
<code class="docutils literal notranslate"><span class="pre">RandomState</span></code> fixed meant that it could not use the new BitGenerator state
objects. Developing programs that use a mixture of libraries that have and
have not upgraded would require managing two sets of PRNG states. This would
notionally have been time-limited, but we intended the deprecation to be very
long.</p>
<p>The current proposal solves all of these problems. All current usages of
<code class="docutils literal notranslate"><span class="pre">RandomState</span></code> will continue to work in perpetuity, though some may be
discouraged through documentation. Unit tests can continue to use the full
complement of <code class="docutils literal notranslate"><span class="pre">RandomState</span></code> methods. Mixed <code class="docutils literal notranslate"><span class="pre">RandomState/Generator</span></code>
code can safely share the common BitGenerator state. Unmodified <code class="docutils literal notranslate"><span class="pre">RandomState</span></code>
code can make use of the new features of alternative BitGenerator-like settable
streams.</p>
</section>
</section>
<section id="discussion">
<h2>Discussion<a class="headerlink" href="#discussion" title="Link to this heading">#</a></h2>
<ul class="simple">
<li><p><a class="reference external" href="https://mail.python.org/pipermail/numpy-discussion/2018-June/078126.html">NEP discussion</a></p></li>
<li><p><a class="reference external" href="https://mail.python.org/pipermail/numpy-discussion/2018-January/077608.html">Earlier discussion</a></p></li>
</ul>
</section>
<section id="copyright">
<h2>Copyright<a class="headerlink" href="#copyright" title="Link to this heading">#</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
</article>
</div>
<dialog id="pst-secondary-sidebar-modal"></dialog>
<div id="pst-secondary-sidebar" class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item">
<div
id="pst-page-navigation-heading-2"
class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> On this page
</div>
<nav class="bd-toc-nav page-toc" aria-labelledby="pst-page-navigation-heading-2">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#abstract">Abstract</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#the-status-quo">The status quo</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#implementation">Implementation</a><ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#supporting-unit-tests">Supporting Unit Tests</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#numpy-random"><code class="docutils literal notranslate"><span class="pre">numpy.random.*</span></code></a></li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#alternatives">Alternatives</a><ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#versioning">Versioning</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#stablerandom"><code class="docutils literal notranslate"><span class="pre">StableRandom</span></code></a></li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#discussion">Discussion</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#copyright">Copyright</a></li>
</ul>
</nav></div>
</div></div>
</div>
<footer class="bd-footer-content">
</footer>
</main>
</div>
</div>
<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script defer src="_static/scripts/bootstrap.js?digest=26a4bc78f4c0ddb94549"></script>
<script defer src="_static/scripts/pydata-sphinx-theme.js?digest=26a4bc78f4c0ddb94549"></script>
<footer class="bd-footer">
<div class="bd-footer__inner bd-page-width">
<div class="footer-items__start">
<div class="footer-item">
<p class="copyright">
© Copyright 2017-2024, NumPy Developers.
<br/>
</p>
</div>
<div class="footer-item">
<p class="sphinx-version">
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.2.6.
<br/>
</p>
</div>
</div>
<div class="footer-items__end">
<div class="footer-item">
<p class="theme-version">
Built with the <a href="https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html">PyData Sphinx Theme</a> 0.16.0.
</p></div>
</div>
</div>
</footer>
</body>
</html>