passagemath-objects 10.6.41__cp314-cp314t-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-objects might be problematic. Click here for more details.

Files changed (280) hide show
  1. passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_objects/__init__.py +3 -0
  3. passagemath_objects-10.6.41.dist-info/METADATA +115 -0
  4. passagemath_objects-10.6.41.dist-info/RECORD +280 -0
  5. passagemath_objects-10.6.41.dist-info/WHEEL +6 -0
  6. passagemath_objects-10.6.41.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_objects.py +37 -0
  8. sage/arith/all__sagemath_objects.py +5 -0
  9. sage/arith/long.pxd +411 -0
  10. sage/arith/numerical_approx.cpython-314t-darwin.so +0 -0
  11. sage/arith/numerical_approx.pxd +35 -0
  12. sage/arith/numerical_approx.pyx +75 -0
  13. sage/arith/power.cpython-314t-darwin.so +0 -0
  14. sage/arith/power.pxd +31 -0
  15. sage/arith/power.pyx +127 -0
  16. sage/categories/action.cpython-314t-darwin.so +0 -0
  17. sage/categories/action.pxd +29 -0
  18. sage/categories/action.pyx +641 -0
  19. sage/categories/algebra_functor.py +745 -0
  20. sage/categories/all__sagemath_objects.py +33 -0
  21. sage/categories/basic.py +62 -0
  22. sage/categories/cartesian_product.py +295 -0
  23. sage/categories/category.py +3401 -0
  24. sage/categories/category_cy_helper.cpython-314t-darwin.so +0 -0
  25. sage/categories/category_cy_helper.pxd +8 -0
  26. sage/categories/category_cy_helper.pyx +322 -0
  27. sage/categories/category_singleton.cpython-314t-darwin.so +0 -0
  28. sage/categories/category_singleton.pxd +3 -0
  29. sage/categories/category_singleton.pyx +342 -0
  30. sage/categories/category_types.py +637 -0
  31. sage/categories/category_with_axiom.py +2876 -0
  32. sage/categories/covariant_functorial_construction.py +703 -0
  33. sage/categories/facade_sets.py +228 -0
  34. sage/categories/functor.cpython-314t-darwin.so +0 -0
  35. sage/categories/functor.pxd +7 -0
  36. sage/categories/functor.pyx +691 -0
  37. sage/categories/homset.py +1338 -0
  38. sage/categories/homsets.py +364 -0
  39. sage/categories/isomorphic_objects.py +73 -0
  40. sage/categories/map.cpython-314t-darwin.so +0 -0
  41. sage/categories/map.pxd +34 -0
  42. sage/categories/map.pyx +2112 -0
  43. sage/categories/morphism.cpython-314t-darwin.so +0 -0
  44. sage/categories/morphism.pxd +14 -0
  45. sage/categories/morphism.pyx +895 -0
  46. sage/categories/objects.py +167 -0
  47. sage/categories/primer.py +1696 -0
  48. sage/categories/pushout.py +4834 -0
  49. sage/categories/quotients.py +64 -0
  50. sage/categories/realizations.py +200 -0
  51. sage/categories/sets_cat.py +3228 -0
  52. sage/categories/sets_with_partial_maps.py +52 -0
  53. sage/categories/subobjects.py +64 -0
  54. sage/categories/subquotients.py +21 -0
  55. sage/categories/with_realizations.py +311 -0
  56. sage/cpython/__init__.py +19 -0
  57. sage/cpython/_py2_random.py +619 -0
  58. sage/cpython/all.py +3 -0
  59. sage/cpython/atexit.cpython-314t-darwin.so +0 -0
  60. sage/cpython/atexit.pyx +269 -0
  61. sage/cpython/builtin_types.cpython-314t-darwin.so +0 -0
  62. sage/cpython/builtin_types.pyx +7 -0
  63. sage/cpython/cython_metaclass.cpython-314t-darwin.so +0 -0
  64. sage/cpython/cython_metaclass.h +117 -0
  65. sage/cpython/cython_metaclass.pxd +3 -0
  66. sage/cpython/cython_metaclass.pyx +130 -0
  67. sage/cpython/debug.cpython-314t-darwin.so +0 -0
  68. sage/cpython/debug.pyx +302 -0
  69. sage/cpython/dict_del_by_value.cpython-314t-darwin.so +0 -0
  70. sage/cpython/dict_del_by_value.pxd +9 -0
  71. sage/cpython/dict_del_by_value.pyx +191 -0
  72. sage/cpython/dict_internal.h +245 -0
  73. sage/cpython/getattr.cpython-314t-darwin.so +0 -0
  74. sage/cpython/getattr.pxd +9 -0
  75. sage/cpython/getattr.pyx +439 -0
  76. sage/cpython/pycore_long.h +97 -0
  77. sage/cpython/pycore_long.pxd +10 -0
  78. sage/cpython/python_debug.h +44 -0
  79. sage/cpython/python_debug.pxd +47 -0
  80. sage/cpython/pyx_visit.h +13 -0
  81. sage/cpython/string.cpython-314t-darwin.so +0 -0
  82. sage/cpython/string.pxd +76 -0
  83. sage/cpython/string.pyx +34 -0
  84. sage/cpython/string_impl.h +60 -0
  85. sage/cpython/type.cpython-314t-darwin.so +0 -0
  86. sage/cpython/type.pxd +2 -0
  87. sage/cpython/type.pyx +40 -0
  88. sage/cpython/wrapperdescr.pxd +67 -0
  89. sage/ext/all__sagemath_objects.py +3 -0
  90. sage/ext/ccobject.h +64 -0
  91. sage/ext/cplusplus.pxd +17 -0
  92. sage/ext/mod_int.h +30 -0
  93. sage/ext/mod_int.pxd +24 -0
  94. sage/ext/stdsage.pxd +39 -0
  95. sage/groups/all__sagemath_objects.py +1 -0
  96. sage/groups/group.cpython-314t-darwin.so +0 -0
  97. sage/groups/group.pxd +14 -0
  98. sage/groups/group.pyx +322 -0
  99. sage/groups/old.cpython-314t-darwin.so +0 -0
  100. sage/groups/old.pxd +14 -0
  101. sage/groups/old.pyx +219 -0
  102. sage/libs/all__sagemath_objects.py +3 -0
  103. sage/libs/gmp/__init__.py +1 -0
  104. sage/libs/gmp/all.pxd +6 -0
  105. sage/libs/gmp/binop.pxd +23 -0
  106. sage/libs/gmp/misc.pxd +8 -0
  107. sage/libs/gmp/mpf.pxd +88 -0
  108. sage/libs/gmp/mpn.pxd +57 -0
  109. sage/libs/gmp/mpq.pxd +57 -0
  110. sage/libs/gmp/mpz.pxd +202 -0
  111. sage/libs/gmp/pylong.cpython-314t-darwin.so +0 -0
  112. sage/libs/gmp/pylong.pxd +12 -0
  113. sage/libs/gmp/pylong.pyx +150 -0
  114. sage/libs/gmp/random.pxd +25 -0
  115. sage/libs/gmp/randomize.pxd +59 -0
  116. sage/libs/gmp/types.pxd +53 -0
  117. sage/libs/gmpxx.pxd +19 -0
  118. sage/misc/abstract_method.py +276 -0
  119. sage/misc/all__sagemath_objects.py +43 -0
  120. sage/misc/bindable_class.py +253 -0
  121. sage/misc/c3_controlled.cpython-314t-darwin.so +0 -0
  122. sage/misc/c3_controlled.pxd +2 -0
  123. sage/misc/c3_controlled.pyx +1402 -0
  124. sage/misc/cachefunc.cpython-314t-darwin.so +0 -0
  125. sage/misc/cachefunc.pxd +43 -0
  126. sage/misc/cachefunc.pyx +3781 -0
  127. sage/misc/call.py +188 -0
  128. sage/misc/classcall_metaclass.cpython-314t-darwin.so +0 -0
  129. sage/misc/classcall_metaclass.pxd +14 -0
  130. sage/misc/classcall_metaclass.pyx +599 -0
  131. sage/misc/constant_function.cpython-314t-darwin.so +0 -0
  132. sage/misc/constant_function.pyx +130 -0
  133. sage/misc/decorators.py +747 -0
  134. sage/misc/fast_methods.cpython-314t-darwin.so +0 -0
  135. sage/misc/fast_methods.pxd +20 -0
  136. sage/misc/fast_methods.pyx +351 -0
  137. sage/misc/flatten.py +90 -0
  138. sage/misc/fpickle.cpython-314t-darwin.so +0 -0
  139. sage/misc/fpickle.pyx +177 -0
  140. sage/misc/function_mangling.cpython-314t-darwin.so +0 -0
  141. sage/misc/function_mangling.pxd +11 -0
  142. sage/misc/function_mangling.pyx +308 -0
  143. sage/misc/inherit_comparison.cpython-314t-darwin.so +0 -0
  144. sage/misc/inherit_comparison.pxd +5 -0
  145. sage/misc/inherit_comparison.pyx +105 -0
  146. sage/misc/instancedoc.cpython-314t-darwin.so +0 -0
  147. sage/misc/instancedoc.pyx +331 -0
  148. sage/misc/lazy_attribute.cpython-314t-darwin.so +0 -0
  149. sage/misc/lazy_attribute.pyx +607 -0
  150. sage/misc/lazy_format.py +135 -0
  151. sage/misc/lazy_import.cpython-314t-darwin.so +0 -0
  152. sage/misc/lazy_import.pyx +1299 -0
  153. sage/misc/lazy_import_cache.py +36 -0
  154. sage/misc/lazy_list.cpython-314t-darwin.so +0 -0
  155. sage/misc/lazy_list.pxd +19 -0
  156. sage/misc/lazy_list.pyx +1187 -0
  157. sage/misc/lazy_string.cpython-314t-darwin.so +0 -0
  158. sage/misc/lazy_string.pxd +7 -0
  159. sage/misc/lazy_string.pyx +546 -0
  160. sage/misc/misc.py +1066 -0
  161. sage/misc/misc_c.cpython-314t-darwin.so +0 -0
  162. sage/misc/misc_c.pxd +3 -0
  163. sage/misc/misc_c.pyx +766 -0
  164. sage/misc/namespace_package.py +37 -0
  165. sage/misc/nested_class.cpython-314t-darwin.so +0 -0
  166. sage/misc/nested_class.pxd +3 -0
  167. sage/misc/nested_class.pyx +394 -0
  168. sage/misc/persist.cpython-314t-darwin.so +0 -0
  169. sage/misc/persist.pyx +1251 -0
  170. sage/misc/prandom.py +418 -0
  171. sage/misc/randstate.cpython-314t-darwin.so +0 -0
  172. sage/misc/randstate.pxd +30 -0
  173. sage/misc/randstate.pyx +1059 -0
  174. sage/misc/repr.py +203 -0
  175. sage/misc/reset.cpython-314t-darwin.so +0 -0
  176. sage/misc/reset.pyx +196 -0
  177. sage/misc/sage_ostools.cpython-314t-darwin.so +0 -0
  178. sage/misc/sage_ostools.pyx +323 -0
  179. sage/misc/sage_timeit.py +276 -0
  180. sage/misc/sage_timeit_class.cpython-314t-darwin.so +0 -0
  181. sage/misc/sage_timeit_class.pyx +120 -0
  182. sage/misc/sage_unittest.py +637 -0
  183. sage/misc/sageinspect.py +2768 -0
  184. sage/misc/session.cpython-314t-darwin.so +0 -0
  185. sage/misc/session.pyx +392 -0
  186. sage/misc/superseded.py +557 -0
  187. sage/misc/test_nested_class.py +228 -0
  188. sage/misc/timing.py +264 -0
  189. sage/misc/unknown.py +222 -0
  190. sage/misc/verbose.py +253 -0
  191. sage/misc/weak_dict.cpython-314t-darwin.so +0 -0
  192. sage/misc/weak_dict.pxd +15 -0
  193. sage/misc/weak_dict.pyx +1231 -0
  194. sage/modules/all__sagemath_objects.py +1 -0
  195. sage/modules/module.cpython-314t-darwin.so +0 -0
  196. sage/modules/module.pxd +5 -0
  197. sage/modules/module.pyx +329 -0
  198. sage/rings/all__sagemath_objects.py +3 -0
  199. sage/rings/integer_fake.h +22 -0
  200. sage/rings/integer_fake.pxd +55 -0
  201. sage/sets/all__sagemath_objects.py +3 -0
  202. sage/sets/pythonclass.cpython-314t-darwin.so +0 -0
  203. sage/sets/pythonclass.pxd +9 -0
  204. sage/sets/pythonclass.pyx +247 -0
  205. sage/structure/__init__.py +4 -0
  206. sage/structure/all.py +30 -0
  207. sage/structure/category_object.cpython-314t-darwin.so +0 -0
  208. sage/structure/category_object.pxd +28 -0
  209. sage/structure/category_object.pyx +1087 -0
  210. sage/structure/coerce.cpython-314t-darwin.so +0 -0
  211. sage/structure/coerce.pxd +44 -0
  212. sage/structure/coerce.pyx +2107 -0
  213. sage/structure/coerce_actions.cpython-314t-darwin.so +0 -0
  214. sage/structure/coerce_actions.pxd +27 -0
  215. sage/structure/coerce_actions.pyx +988 -0
  216. sage/structure/coerce_dict.cpython-314t-darwin.so +0 -0
  217. sage/structure/coerce_dict.pxd +51 -0
  218. sage/structure/coerce_dict.pyx +1557 -0
  219. sage/structure/coerce_exceptions.py +23 -0
  220. sage/structure/coerce_maps.cpython-314t-darwin.so +0 -0
  221. sage/structure/coerce_maps.pxd +28 -0
  222. sage/structure/coerce_maps.pyx +718 -0
  223. sage/structure/debug_options.cpython-314t-darwin.so +0 -0
  224. sage/structure/debug_options.pxd +6 -0
  225. sage/structure/debug_options.pyx +54 -0
  226. sage/structure/dynamic_class.py +541 -0
  227. sage/structure/element.cpython-314t-darwin.so +0 -0
  228. sage/structure/element.pxd +272 -0
  229. sage/structure/element.pyx +4772 -0
  230. sage/structure/element_wrapper.cpython-314t-darwin.so +0 -0
  231. sage/structure/element_wrapper.pxd +12 -0
  232. sage/structure/element_wrapper.pyx +582 -0
  233. sage/structure/factorization.py +1422 -0
  234. sage/structure/factorization_integer.py +105 -0
  235. sage/structure/factory.cpython-314t-darwin.so +0 -0
  236. sage/structure/factory.pyx +786 -0
  237. sage/structure/formal_sum.py +489 -0
  238. sage/structure/gens_py.py +73 -0
  239. sage/structure/global_options.py +1743 -0
  240. sage/structure/indexed_generators.py +863 -0
  241. sage/structure/list_clone.cpython-314t-darwin.so +0 -0
  242. sage/structure/list_clone.pxd +65 -0
  243. sage/structure/list_clone.pyx +1867 -0
  244. sage/structure/list_clone_demo.cpython-314t-darwin.so +0 -0
  245. sage/structure/list_clone_demo.pyx +248 -0
  246. sage/structure/list_clone_timings.py +179 -0
  247. sage/structure/list_clone_timings_cy.cpython-314t-darwin.so +0 -0
  248. sage/structure/list_clone_timings_cy.pyx +86 -0
  249. sage/structure/mutability.cpython-314t-darwin.so +0 -0
  250. sage/structure/mutability.pxd +21 -0
  251. sage/structure/mutability.pyx +348 -0
  252. sage/structure/nonexact.py +69 -0
  253. sage/structure/parent.cpython-314t-darwin.so +0 -0
  254. sage/structure/parent.pxd +112 -0
  255. sage/structure/parent.pyx +3093 -0
  256. sage/structure/parent_base.cpython-314t-darwin.so +0 -0
  257. sage/structure/parent_base.pxd +13 -0
  258. sage/structure/parent_base.pyx +44 -0
  259. sage/structure/parent_gens.cpython-314t-darwin.so +0 -0
  260. sage/structure/parent_gens.pxd +22 -0
  261. sage/structure/parent_gens.pyx +377 -0
  262. sage/structure/parent_old.cpython-314t-darwin.so +0 -0
  263. sage/structure/parent_old.pxd +25 -0
  264. sage/structure/parent_old.pyx +294 -0
  265. sage/structure/proof/__init__.py +1 -0
  266. sage/structure/proof/all.py +243 -0
  267. sage/structure/proof/proof.py +300 -0
  268. sage/structure/richcmp.cpython-314t-darwin.so +0 -0
  269. sage/structure/richcmp.pxd +213 -0
  270. sage/structure/richcmp.pyx +495 -0
  271. sage/structure/sage_object.cpython-314t-darwin.so +0 -0
  272. sage/structure/sage_object.pxd +3 -0
  273. sage/structure/sage_object.pyx +988 -0
  274. sage/structure/sage_object_test.py +19 -0
  275. sage/structure/sequence.py +937 -0
  276. sage/structure/set_factories.py +1178 -0
  277. sage/structure/set_factories_example.py +527 -0
  278. sage/structure/support_view.py +179 -0
  279. sage/structure/test_factory.py +56 -0
  280. sage/structure/unique_representation.py +1359 -0
@@ -0,0 +1,1059 @@
1
+ # sage_setup: distribution = sagemath-objects
2
+ # sage.doctest: needs sage.groups sage.libs.gap sage.libs.ntl sage.libs.pari
3
+ r"""
4
+ Random Number States
5
+
6
+ AUTHORS:
7
+
8
+ - Carl Witty (2008-03): new file
9
+
10
+ This module manages all the available pseudo-random number generators
11
+ in Sage. (For the rest of the documentation in this module, we will
12
+ drop the "pseudo".)
13
+
14
+ The goal is to allow algorithms using random numbers to be
15
+ reproducible from one run of Sage to the next, and (to the extent
16
+ possible) from one machine to the next (even across different
17
+ operating systems and architectures).
18
+
19
+ There are two parts to the API. First we will describe the
20
+ command line oriented API, for setting random number generator seeds.
21
+ Then we will describe the library API, for people writing Sage
22
+ library code that uses random numbers.
23
+
24
+ Command line oriented API
25
+ =========================
26
+
27
+ We'll start with the simplest usage: setting fixed random number seeds
28
+ and showing that these lead to reproducible results. ::
29
+
30
+ sage: K.<x> = QQ[]
31
+ sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
32
+ sage: rgp = Gp()
33
+ sage: def gap_randstring(n):
34
+ ....: current_randstate().set_seed_gap()
35
+ ....: return gap(n).SCRRandomString()
36
+ sage: def rtest():
37
+ ....: current_randstate().set_seed_gp(rgp)
38
+ ....: return (ZZ.random_element(1000), RR.random_element(),
39
+ ....: K.random_element(), G.random_element(),
40
+ ....: gap_randstring(5),
41
+ ....: rgp.random(), ntl.ZZ_random(99999),
42
+ ....: random())
43
+
44
+ The above test shows the results of six different random number
45
+ generators, in three different processes. The random elements from
46
+ ``ZZ``, ``RR``, and ``K`` all derive from a single GMP-based random number
47
+ generator. The random element from ``G`` comes from a GAP subprocess.
48
+ The random "string" (5-element binary list) is also from a GAP
49
+ subprocess, using the "classical" GAP random generator.
50
+ The random number from ``rgp`` is from a Pari/gp subprocess. NTL's
51
+ ``ZZ_random`` uses a separate NTL random number generator in the main
52
+ Sage process. And ``random()`` is from a Python :class:`random.Random`
53
+ object.
54
+
55
+ Here we see that setting the random number seed really does make the
56
+ results of these random number generators reproducible. ::
57
+
58
+ sage: set_random_seed(0)
59
+ sage: print(rtest())
60
+ (303, -0.266166246380421, 1/2*x^2 - 1/95*x - 1/2, (1,3), [ 1, 0, 0, 1, 1 ], 265625921, 5842, 0.9661911734708414)
61
+ sage: set_random_seed(1)
62
+ sage: print(rtest())
63
+ (978, 0.0557699430711638, -3*x^2 - 1/12, (1,2), [ 0, 0, 1, 1, 0 ], 807447831, 29982, 0.8335077654199736)
64
+ sage: set_random_seed(2)
65
+ sage: print(rtest())
66
+ (207, -0.0141049486533456, 4*x^2 + 1/2, (1,2)(4,5), [ 1, 0, 0, 1, 1 ], 1642898426, 41662, 0.19982565117278328)
67
+ sage: set_random_seed(0)
68
+ sage: print(rtest())
69
+ (303, -0.266166246380421, 1/2*x^2 - 1/95*x - 1/2, (1,3), [ 1, 0, 0, 1, 1 ], 265625921, 5842, 0.9661911734708414)
70
+ sage: set_random_seed(1)
71
+ sage: print(rtest())
72
+ (978, 0.0557699430711638, -3*x^2 - 1/12, (1,2), [ 0, 0, 1, 1, 0 ], 807447831, 29982, 0.8335077654199736)
73
+ sage: set_random_seed(2)
74
+ sage: print(rtest())
75
+ (207, -0.0141049486533456, 4*x^2 + 1/2, (1,2)(4,5), [ 1, 0, 0, 1, 1 ], 1642898426, 41662, 0.19982565117278328)
76
+
77
+ Once we've set the random number seed, we can check what seed was used.
78
+ (This is not the current random number state; it does not change when
79
+ random numbers are generated.) ::
80
+
81
+ sage: set_random_seed(12345)
82
+ sage: initial_seed()
83
+ 12345
84
+ sage: print(rtest())
85
+ (720, -0.612180244315804, x^2 - x, (1,2,3), [ 1, 0, 0, 0, 1 ], 1911581957, 27093, 0.9205331599518184)
86
+ sage: initial_seed()
87
+ 12345
88
+
89
+ If :func:`set_random_seed` is called with no arguments, then a new
90
+ seed is automatically selected. On operating systems that support it,
91
+ the new seed comes from :func:`os.urandom`; this is intended to be
92
+ a truly random (not pseudo-random), cryptographically secure number.
93
+ (Whether it is actually cryptographically secure depends on operating
94
+ system details that are outside the control of Sage.)
95
+
96
+ If :func:`os.urandom` is not supported, then the new seed comes
97
+ from the current time, which is definitely not cryptographically
98
+ secure. ::
99
+
100
+ sage: set_random_seed()
101
+ sage: r = rtest()
102
+ sage: r # random
103
+ (909, -0.407373370020575, 6/7*x^2 + 1, (1,2,3)(4,5), 985329107, 21461, 0.30047071049504859)
104
+
105
+ After setting a new random number seed with :func:`set_random_seed`,
106
+ we can use :func:`initial_seed` to see what seed was automatically
107
+ selected, and call :func:`set_random_seed` to restart the same
108
+ random number sequence. ::
109
+
110
+ sage: s = initial_seed()
111
+ sage: s # random
112
+ 336237747258024892084418842839280045662
113
+ sage: set_random_seed(s)
114
+ sage: r2 = rtest()
115
+ sage: r == r2
116
+ True
117
+
118
+ Whenever Sage starts, :func:`set_random_seed` is called just before
119
+ command line interaction starts; so every Sage run starts with a
120
+ different random number seed. This seed can be recovered with
121
+ :func:`initial_seed()` (as long as the user has not set a different
122
+ seed with :func:`set_random_seed`), so that the results of this run
123
+ can be reproduced in another run; or this automatically selected seed
124
+ can be overridden with, for instance, ``set_random_seed(0)``.
125
+
126
+ We can demonstrate this startup behavior by running a new instance of
127
+ Sage as a subprocess. ::
128
+
129
+ sage: subsage = Sage()
130
+ sage: s = ZZ(subsage('initial_seed()'))
131
+ sage: r = ZZ(subsage('ZZ.random_element(2^200)'))
132
+ sage: s # random
133
+ 161165040149656168853863459174502758403
134
+ sage: r # random
135
+ 1273828861620427462924151488498075119241254209468761367941442
136
+ sage: set_random_seed(s)
137
+ sage: r == ZZ.random_element(2^200)
138
+ True
139
+
140
+ Note that wrappers of all the random number generation methods from
141
+ Python's :mod:`random` module are available at the Sage command
142
+ line, and these wrappers are properly affected by :meth:`set_random_seed`. ::
143
+
144
+ sage: set_random_seed(0)
145
+ sage: random(), getrandbits(20), uniform(5.0, 10.0), normalvariate(0, 1)
146
+ (0.111439293741037, 539332, 8.26785106378383, 1.3893337539828183)
147
+ sage: set_random_seed(1)
148
+ sage: random(), getrandbits(20), uniform(5.0, 10.0), normalvariate(0, 1)
149
+ (0.8294022851874259, 624859, 5.77894484361117, -0.4201366826308758)
150
+ sage: set_random_seed(0)
151
+ sage: random(), getrandbits(20), uniform(5.0, 10.0), normalvariate(0, 1)
152
+ (0.111439293741037, 539332, 8.26785106378383, 1.3893337539828183)
153
+
154
+ That pretty much covers what you need to know for command-line use of
155
+ this module. Now let's move to what authors of Sage library code
156
+ need to know about the module.
157
+
158
+
159
+ Library API
160
+ ===========
161
+
162
+ First, we'll cover doctesting. Every docstring now has an implicit
163
+ ``set_random_seed(0)`` prepended. Any uses of ``# random`` that
164
+ are based on random numbers under the control of this module should be
165
+ removed, and the reproducible answers inserted instead.
166
+
167
+ This practice has two potential drawbacks. First, it increases the work
168
+ of maintaining doctests. For instance, in a long docstring that has
169
+ many doctests that depend on random numbers, a change near the beginning
170
+ (for instance, adding a new doctest) may invalidate all later doctests
171
+ in the docstring. To reduce this downside, you may add calls to
172
+ ``set_random_seed(0)`` throughout the docstring (in the extreme case,
173
+ before every doctest).
174
+
175
+ Second, the ``# random`` in the doctest served as a signal to the
176
+ reader of the docstring that the result was unpredictable and that it
177
+ would not be surprising to get a different result when trying out the
178
+ examples in the doctest. If a doctest specifically refers to
179
+ ``ZZ.random_element()`` (for instance), this is presumably enough
180
+ of a signal to render this function of ``# random`` unnecessary.
181
+ However, some doctests are not obviously (from the name) random, but
182
+ do depend on random numbers internally, such as the
183
+ :meth:`composition_series <sage.groups.perm_gps.permgroup.PermutationGroup_generic.composition_series>`
184
+ method of a ``PermutationGroup``. In these cases, the convention is to insert
185
+ the following text at the beginning of the ``EXAMPLES`` section. ::
186
+
187
+ These computations use pseudo-random numbers, so we set the
188
+ seed for reproducible testing.
189
+
190
+ sage: set_random_seed(0)
191
+
192
+ Note that this call to ``set_random_seed(0)`` is redundant, since
193
+ ``set_random_seed(0)`` is automatically inserted at the beginning
194
+ of every docstring. However, it makes the example reproducible for somebody
195
+ who just types the lines from the doctest and doesn't know about the
196
+ automatic ``set_random_seed(0)``.
197
+
198
+ Next, let's cover setting the random seed from library code. The
199
+ first rule is that library code should never call
200
+ :func:`set_random_seed`. This function is only for command-line
201
+ use. Instead, if the library code wants to use a different random
202
+ seed, it should use ``with seed(s):``. This will use the new seed
203
+ within the scope of the ``with`` statement, but will revert to the previous
204
+ seed once the ``with`` statement is completed. (Or the library can use
205
+ ``with seed():`` to get a seed automatically selected using
206
+ :func:`os.urandom()` or the current time, in the same way as described for
207
+ :func:`set_random_seed` above.)
208
+
209
+ Ideally, using ``with seed(s):`` should not affect the outer random
210
+ number sequence at all; we will call this property "isolation." We
211
+ achieve isolation for most, but not all, of the random number generators
212
+ in Sage (we fail for generators, such as NTL, that do not provide an API
213
+ to retrieve the current random number state).
214
+
215
+ We'll demonstrate isolation. First, we show the sequence of random numbers
216
+ that you get without intervening ``with seed``. ::
217
+
218
+ sage: set_random_seed(0)
219
+ sage: r1 = rtest(); print(r1)
220
+ (303, -0.266166246380421, 1/2*x^2 - 1/95*x - 1/2, (1,3), [ 1, 0, 0, 1, 1 ], 265625921, 5842, 0.9661911734708414)
221
+ sage: r2 = rtest(); print(r2)
222
+ (105, 0.642309615982449, -x^2 - x - 6, (1,3)(4,5), [ 1, 0, 0, 0, 1 ], 53231108, 77132, 0.001767155077382232)
223
+
224
+ We get slightly different results with an intervening ``with seed``. ::
225
+
226
+ sage: set_random_seed(0)
227
+ sage: r1 == rtest()
228
+ True
229
+ sage: with seed(1): rtest()
230
+ (978, 0.0557699430711638, -3*x^2 - 1/12, (1,2), [ 0, 0, 1, 1, 0 ], 807447831, 29982, 0.8335077654199736)
231
+ sage: r2m = rtest(); r2m
232
+ (105, 0.642309615982449, -x^2 - x - 6, (1,3)(4,5), [ 1, 0, 0, 0, 1 ], 53231108, 40267, 0.001767155077382232)
233
+ sage: r2m == r2
234
+ False
235
+
236
+ We can see that ``r2`` and ``r2m`` are the same except for the
237
+ call to :func:`ntl.ZZ_random`, which produces different results
238
+ with and without the ``with seed``.
239
+
240
+ However, we do still get a partial form of isolation, even in this
241
+ case, as we see in this example::
242
+
243
+ sage: set_random_seed(0)
244
+ sage: r1 == rtest()
245
+ True
246
+ sage: with seed(1):
247
+ ....: print(rtest())
248
+ ....: print(rtest())
249
+ (978, 0.0557699430711638, -3*x^2 - 1/12, (1,2), [ 0, 0, 1, 1, 0 ], 807447831, 29982, 0.8335077654199736)
250
+ (138, -0.0404945051288503, 2*x - 24, (1,2,3), [ 1, 1, 0, 1, 1 ], 1010791326, 91360, 0.0033332230808060803)
251
+ sage: r2m == rtest()
252
+ True
253
+
254
+ The NTL results after the ``with seed`` don't depend on how many
255
+ NTL random numbers were generated inside the ``with seed``.
256
+
257
+ sage: set_random_seed(0)
258
+ sage: r1 == rtest()
259
+ True
260
+ sage: with seed(1):
261
+ ....: rtest()
262
+ (978, 0.0557699430711638, -3*x^2 - 1/12, (1,2), [ 0, 0, 1, 1, 0 ], 807447831, 29982, 0.8335077654199736)
263
+ sage: r2m == rtest()
264
+ True
265
+
266
+ (In general, the above code is not exactly equivalent to the ``with``
267
+ statement, because if an exception happens in the body, the real
268
+ ``with`` statement will pass the exception information as parameters to
269
+ the ``__exit__`` method. However, our ``__exit__`` method
270
+ ignores the exception information anyway, so the above is equivalent in
271
+ our case.)
272
+
273
+
274
+ Generating random numbers in library code
275
+ =========================================
276
+
277
+ Now we come to the last part of the documentation: actually generating
278
+ random numbers in library code. First, the easy case. If you generate
279
+ random numbers only by calling other Sage library code (such as
280
+ ``random_element`` methods on parents), you don't need to do
281
+ anything special; the other code presumably already interacts with
282
+ this module correctly.
283
+
284
+ Otherwise, it depends on what random number generator you want to use.
285
+
286
+ - ``gmp_randstate_t`` -- if you want to use some random number
287
+ generator that takes a ``gmp_randstate_t`` (like ``mpz_urandomm`` or
288
+ ``mpfr_urandomb``), then use code like the following::
289
+
290
+ from sage.misc.randstate cimport randstate, current_randstate
291
+ ...
292
+
293
+ cdef randstate rstate = current_randstate()
294
+
295
+ Then a ``gmp_randstate_t`` is available as ``rstate.gmp_state``.
296
+
297
+ Fetch the current :class:`randstate` with ``current_randstate()`` in
298
+ every function that wants to use it; don't cache it globally or in a
299
+ class. (Such caching would break ``set_random_seed``).
300
+
301
+ - ``Python`` -- if you want to use the random number generators from
302
+ the :mod:`random` module, you have two choices. The slightly
303
+ easier choice is to import functions from
304
+ :mod:`sage.misc.prandom`; for instance, you can simply replace
305
+ ``from random import randrange`` with
306
+ ``from sage.misc.prandom import randrange``. However, this is slightly less
307
+ efficient, because the wrappers in :mod:`sage.misc.prandom` look up the
308
+ current :class:`randstate` on each call. If you're generating many
309
+ random numbers in a row, it's faster to instead do ::
310
+
311
+ from sage.misc.randstate import current_randstate ...
312
+
313
+ randrange = current_randstate().python_random().randrange
314
+
315
+ Fetch the current :class:`randstate` with
316
+ :func:`current_randstate()` in every function that wants to use it;
317
+ don't cache the :class:`randstate`, the :class:`Random` object
318
+ returned by ``python_random``, or the bound methods on that
319
+ :class:`Random` object globally or in a class. (Such caching would
320
+ break ``set_random_seed``).
321
+
322
+ - ``GAP`` -- if you are calling code in GAP that uses random numbers,
323
+ call ``set_seed_gap`` at the beginning of your function, like this::
324
+
325
+ from sage.misc.randstate import current_randstate
326
+ ...
327
+
328
+ current_randstate().set_seed_gap()
329
+
330
+ Fetch the current :class:`randstate` with
331
+ :func:`current_randstate()` in every function that wants to use it;
332
+ don't cache it globally or in a class. (Such caching would break
333
+ ``set_random_seed``).
334
+
335
+ - ``Pari`` -- if you are calling code in the Pari library that uses
336
+ random numbers, call ``set_seed_pari`` at the beginning of your
337
+ function, like this::
338
+
339
+ from sage.misc.randstate import current_randstate
340
+ ...
341
+
342
+ current_randstate().set_seed_pari()
343
+
344
+ Fetch the current :class:`randstate` with
345
+ :func:`current_randstate()` in every function that wants to use it;
346
+ don't cache it globally or in a class. (Such caching would break
347
+ ``set_random_seed``).
348
+
349
+ - ``Pari/gp`` -- if you are calling code in a Pari/gp subprocess that
350
+ uses random numbers, call ``set_seed_gp`` at the beginning of your
351
+ function, like this::
352
+
353
+ from sage.misc.randstate import current_randstate
354
+ ...
355
+
356
+ current_randstate().set_seed_gp()
357
+
358
+ This will set the seed in the gp process in ``sage.interfaces.gp.gp``.
359
+ If you have a different gp process, say in the variable ``my_gp``, then
360
+ call ``set_seed_gp(my_gp)`` instead.
361
+
362
+ Fetch the current :class:`randstate` with :func:`current_randstate()` in
363
+ every function that wants to use it; don't cache it globally or
364
+ in a class. (Such caching would break ``set_random_seed``).
365
+
366
+ - ``NTL`` -- if you are calling code in the NTL library that uses
367
+ random numbers, call ``set_seed_ntl`` at the beginning of your
368
+ function, like this::
369
+
370
+ from sage.misc.randstate import current_randstate ...
371
+
372
+ current_randstate().set_seed_ntl(False)
373
+
374
+ Fetch the current :class:`randstate` with
375
+ :func:`current_randstate()` in every function that wants to use it;
376
+ don't cache it globally or in a class. (Such caching would break
377
+ ``set_random_seed``).
378
+
379
+ - ``libc`` -- if you are writing code that calls the libc function
380
+ :func:`random()`: don't! The :func:`random()` function does not
381
+ give reproducible results across different operating systems, so we
382
+ can't make portable doctests for the results. Instead, do::
383
+
384
+ from sage.misc.randstate cimport random
385
+
386
+ The :func:`random` function in :mod:`sage.misc.randstate` gives a
387
+ 31-bit random number, but it uses the ``gmp_randstate_t`` in the
388
+ current :class:`randstate`, so it is portable. (This range was
389
+ chosen for two reasons: it matches the range of random() on 32-bit
390
+ and 64-bit Linux, although not Solaris; and it's the largest range
391
+ of nonnegative numbers that fits in a 32-bit signed integer.)
392
+
393
+ However, you may still need to set the libc random number state; for
394
+ instance, if you are wrapping a library that uses :func:`random()`
395
+ internally and you don't want to change the library. In that case,
396
+ call ``set_seed_libc`` at the beginning of your function, like this::
397
+
398
+ from sage.misc.randstate import current_randstate
399
+ ...
400
+
401
+ current_randstate().set_seed_libc(False)
402
+
403
+ Fetch the current :class:`randstate` with
404
+ :func:`current_randstate()` in every function that wants to use it;
405
+ don't cache it globally or in a class. (Such caching would break
406
+ ``set_random_seed``).
407
+
408
+
409
+ Classes and methods
410
+ ===================
411
+ """
412
+
413
+ cdef extern from "stdlib.h":
414
+ # Provide equivalent functions for Windows.
415
+ """
416
+ #ifdef _WIN32
417
+ #include <stdlib.h>
418
+ static inline void srandom(unsigned int seed)
419
+ {
420
+ srand(seed);
421
+ }
422
+
423
+ static inline long int random(void)
424
+ {
425
+ return rand();
426
+ }
427
+ #endif
428
+ """
429
+ long c_libc_random "random"()
430
+ void c_libc_srandom "srandom"(unsigned int seed)
431
+
432
+ from sage.libs.gmp.all cimport *
433
+
434
+ import binascii
435
+ import os
436
+ import time
437
+ import weakref
438
+ import random as _random
439
+
440
+ use_urandom = False
441
+ # Check whether os.urandom() works.
442
+ try:
443
+ os.urandom(1)
444
+ use_urandom = True
445
+ except NotImplementedError:
446
+ pass
447
+
448
+ # Holds the current randstate object.
449
+ cdef randstate _current_randstate
450
+
451
+ # For each kind of random number generator, keep track of which
452
+ # randstate object was the most recent one to seed it. (Before
453
+ # the generator has been seeded, these will be None.)
454
+ cdef randstate _libc_seed_randstate
455
+ cdef randstate _ntl_seed_randstate
456
+ cdef randstate _gap_seed_randstate
457
+ cdef randstate _pari_seed_randstate
458
+ # For each gp subprocess that has been seeded, keep track of which
459
+ # randstate object was the most recent one to seed it.
460
+ _gp_seed_randstates = weakref.WeakKeyDictionary()
461
+
462
+ cpdef randstate current_randstate():
463
+ r"""
464
+ Return the current random number state.
465
+
466
+ EXAMPLES::
467
+
468
+ sage: set_random_seed(0)
469
+ sage: current_randstate()
470
+ <sage.misc.randstate.randstate object at 0x...>
471
+ sage: current_randstate().python_random().random()
472
+ 0.111439293741037
473
+ """
474
+ return _current_randstate
475
+
476
+ # Keep track of the stack of randstates involved in "with seed(s):".
477
+ randstate_stack = []
478
+
479
+ # Default class to use for randstate.python_random
480
+ DEFAULT_PYTHON_RANDOM = _random.Random
481
+
482
+ # The following components of Sage use random numbers that I have not
483
+ # figured out how to seed: fpLLL, mwrank, mpfi
484
+ # (there are probably others; these are the ones I noticed while trying
485
+ # to remove "# random" from doctests)
486
+
487
+ cdef class randstate:
488
+ r"""
489
+ The :class:`randstate` class. This class keeps track of random number
490
+ states and seeds. Type ``sage.misc.randstate?`` for much more
491
+ information on random numbers in Sage.
492
+ """
493
+ def __cinit__(self, *args, **opts):
494
+ """
495
+ Initialise c-data for randstate, in a fail-safe way.
496
+
497
+ TESTS:
498
+
499
+ The following used to segfault (see :issue:`10113`). Now,
500
+ there is a proper type error::
501
+
502
+ sage: seed(1,2) # indirect doctest
503
+ Traceback (most recent call last):
504
+ ...
505
+ TypeError: ...__init__() takes at most 1 positional argument (2 given)
506
+
507
+ AUTHOR:
508
+
509
+ - Simon King <simon.king@uni-jena.de>
510
+ """
511
+ gmp_randinit_default(self.gmp_state)
512
+
513
+ def __init__(self, seed=None):
514
+ r"""
515
+ Initialize a new :class:`randstate` object with the given seed
516
+ (which must be coercible to a Python long).
517
+
518
+ If no seed is given, then a seed is automatically selected
519
+ using :func:`os.urandom` if it is available, or the current
520
+ time otherwise.
521
+
522
+ EXAMPLES::
523
+
524
+ sage: from sage.misc.randstate import randstate
525
+ sage: r = randstate(54321); r
526
+ <sage.misc.randstate.randstate object at 0x...>
527
+ sage: r.seed()
528
+ 54321
529
+ sage: r = randstate(); r
530
+ <sage.misc.randstate.randstate object at 0x...>
531
+ sage: r.seed() # random
532
+ 305866218880103397618377824640007711767
533
+
534
+ Note that creating a :class:`randstate` with a seed of 0
535
+ is vastly faster than any other seed (over a thousand times
536
+ faster in my test). ::
537
+
538
+ sage: timeit('randstate(0)') # random
539
+ 625 loops, best of 3: 1.38 us per loop
540
+ sage: timeit('randstate(1)') # random
541
+ 125 loops, best of 3: 3.59 ms per loop
542
+ """
543
+ cdef mpz_t mpz_seed
544
+
545
+ if seed is None:
546
+ if use_urandom:
547
+ seed = int(binascii.hexlify(os.urandom(16)), 16)
548
+ else:
549
+ seed = int(time.time() * 256)
550
+ else:
551
+ seed = int(seed)
552
+
553
+ # If seed==0, leave it at the default seed used by
554
+ # gmp_randinit_default()
555
+ if seed:
556
+ mpz_init(mpz_seed)
557
+ mpz_set_pylong(mpz_seed, seed)
558
+ gmp_randseed(self.gmp_state, mpz_seed)
559
+ mpz_clear(mpz_seed)
560
+
561
+ self._seed = seed
562
+
563
+ def seed(self):
564
+ r"""
565
+ Return the initial seed of a :class:`randstate` object. (This is not
566
+ the current state; it does not change when you get random
567
+ numbers.)
568
+
569
+ EXAMPLES::
570
+
571
+ sage: set_random_seed(0)
572
+ sage: from sage.misc.randstate import randstate
573
+ sage: r = randstate(314159)
574
+ sage: r.seed()
575
+ 314159
576
+ sage: r.python_random().random()
577
+ 0.111439293741037
578
+ sage: r.seed()
579
+ 314159
580
+ """
581
+ return self._seed
582
+
583
+ def python_random(self, cls=None, seed=None):
584
+ r"""
585
+ Return a :class:`random.Random` object. The first time it is
586
+ called on a given :class:`randstate`, a new :class:`random.Random`
587
+ is created (seeded from the *current* :class:`randstate`);
588
+ the same object is returned on subsequent calls.
589
+
590
+ It is expected that ``python_random`` will only be
591
+ called on the current :class:`randstate`.
592
+
593
+ INPUT:
594
+
595
+ - ``cls`` -- (optional) a class with the same interface as
596
+ :class:`random.Random` (e.g. a subclass thereof) to use as the
597
+ Python RNG interface. Otherwise the standard :class:`random.Random`
598
+ is used.
599
+
600
+ - ``seed`` -- (optional) an integer to seed the :class:`random.Random`
601
+ instance with upon creation; if not specified it is seeded using
602
+ ``ZZ.random_element(1 << 128)``.
603
+
604
+ EXAMPLES::
605
+
606
+ sage: set_random_seed(5)
607
+ sage: rnd = current_randstate().python_random()
608
+ sage: rnd.random()
609
+ 0.013558022446944151
610
+ sage: rnd.randrange(1000)
611
+ 544
612
+ """
613
+
614
+ if cls is None:
615
+ cls = DEFAULT_PYTHON_RANDOM
616
+
617
+ if type(self._python_random) is cls:
618
+ return self._python_random
619
+
620
+ from sage.rings.integer_ring import ZZ
621
+ rand = cls()
622
+ if seed is None:
623
+ rand.seed(int(ZZ.random_element(1<<128)))
624
+ else:
625
+ rand.seed(int(seed))
626
+ self._python_random = rand
627
+ return rand
628
+
629
+ cpdef ZZ_seed(self):
630
+ r"""
631
+ When called on the current :class:`randstate`, returns a 128-bit
632
+ :mod:`Integer <sage.rings.integer_ring>` suitable for seeding another
633
+ random number generator.
634
+
635
+ EXAMPLES::
636
+
637
+ sage: set_random_seed(1414)
638
+ sage: current_randstate().ZZ_seed()
639
+ 48314508034782595865062786044921182484
640
+ """
641
+ from sage.rings.integer_ring import ZZ
642
+ return ZZ.random_element(1<<128)
643
+
644
+ cpdef long_seed(self):
645
+ r"""
646
+ When called on the current :class:`randstate`, returns a 128-bit
647
+ Python long suitable for seeding another random number generator.
648
+
649
+ EXAMPLES::
650
+
651
+ sage: set_random_seed(1618)
652
+ sage: current_randstate().long_seed()
653
+ 256056279774514099508607350947089272595
654
+ """
655
+ from sage.rings.integer_ring import ZZ
656
+ return int(ZZ.random_element(1<<128))
657
+
658
+ cpdef set_seed_libc(self, bint force):
659
+ r"""
660
+ Check to see if ``self`` was the most recent :class:`randstate`
661
+ to seed the libc random number generator. If not, seeds the
662
+ libc random number generator. (Do not use the libc random
663
+ number generator if you have a choice; its randomness is poor,
664
+ and the random number sequences it produces are not portable
665
+ across operating systems.)
666
+
667
+ If the argument ``force`` is ``True``, seeds the generator
668
+ unconditionally.
669
+
670
+ EXAMPLES::
671
+
672
+ sage: from sage.misc.randstate import _doctest_libc_random
673
+ sage: set_random_seed(0xBAD)
674
+ sage: current_randstate().set_seed_libc(False)
675
+ sage: _doctest_libc_random() # random
676
+ 1070075918
677
+ """
678
+ global _libc_seed_randstate
679
+ if force or _libc_seed_randstate is not self:
680
+ c_libc_srandom(gmp_urandomb_ui(self.gmp_state, sizeof(int)*8))
681
+ _libc_seed_randstate = self
682
+
683
+ cpdef set_seed_ntl(self, bint force):
684
+ r"""
685
+ Check to see if ``self`` was the most recent :class:`randstate`
686
+ to seed the NTL random number generator. If not, seeds
687
+ the generator. If the argument ``force`` is ``True``,
688
+ seeds the generator unconditionally.
689
+
690
+ EXAMPLES::
691
+
692
+ sage: set_random_seed(2008)
693
+
694
+ This call is actually redundant; :func:`ntl.ZZ_random` will
695
+ seed the generator itself. However, we put the call in
696
+ to make the coverage tester happy. ::
697
+
698
+ sage: current_randstate().set_seed_ntl(False)
699
+ sage: ntl.ZZ_random(10^40)
700
+ 1495283511775355459459209288047895196007
701
+ """
702
+ global _ntl_seed_randstate
703
+ if force or _ntl_seed_randstate is not self:
704
+ import sage.libs.ntl.ntl_ZZ as ntl_ZZ
705
+ from sage.rings.integer_ring import ZZ
706
+ ntl_ZZ.ntl_setSeed(ZZ.random_element(1<<128))
707
+ _ntl_seed_randstate = self
708
+
709
+ def set_seed_gap(self):
710
+ r"""
711
+ Check to see if ``self`` was the most recent :class:`randstate`
712
+ to seed the GAP random number generator. If not, seeds
713
+ the generator.
714
+
715
+ EXAMPLES::
716
+
717
+ sage: set_random_seed(99900000999)
718
+ sage: current_randstate().set_seed_gap()
719
+ sage: gap.Random(1, 10^50)
720
+ 1496738263332555434474532297768680634540939580077
721
+ sage: gap(35).SCRRandomString()
722
+ [ 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1,
723
+ 1, 0, 0, 1, 1, 1, 1, 1, 0, 1 ]
724
+ """
725
+ global _gap_seed_randstate
726
+ if _gap_seed_randstate is not self:
727
+ from sage.interfaces.gap import gap
728
+
729
+ if self._gap_saved_seed is not None:
730
+ mersenne_seed, classic_seed = self._gap_saved_seed
731
+ else:
732
+ from sage.rings.integer_ring import ZZ
733
+ seed = ZZ.random_element(1<<128)
734
+ classic_seed = seed
735
+ mersenne_seed = seed
736
+
737
+ prev_mersenne_seed = gap.Reset(gap.GlobalMersenneTwister, mersenne_seed)
738
+ prev_classic_seed = gap.Reset(gap.GlobalRandomSource, classic_seed)
739
+
740
+ if _gap_seed_randstate is not None:
741
+ _gap_seed_randstate._gap_saved_seed = \
742
+ prev_mersenne_seed, prev_classic_seed
743
+
744
+ _gap_seed_randstate = self
745
+
746
+ def set_seed_gp(self, gp=None):
747
+ r"""
748
+ Check to see if ``self`` was the most recent :class:`randstate`
749
+ to seed the random number generator in the given instance
750
+ of gp. (If no instance is given, uses the one in
751
+ :class:`gp <sage.interfaces.gp.Gp>`.) If not, seeds the generator.
752
+
753
+ EXAMPLES::
754
+
755
+ sage: set_random_seed(987654321)
756
+ sage: current_randstate().set_seed_gp()
757
+ sage: gp.random()
758
+ 23289294
759
+ """
760
+ if gp is None:
761
+ import sage.interfaces.gp
762
+ gp = sage.interfaces.gp.gp
763
+
764
+ cdef randstate prev
765
+
766
+ try:
767
+ prev = _gp_seed_randstates[gp]
768
+ except KeyError:
769
+ prev = None
770
+
771
+ if prev is not self:
772
+ if self._gp_saved_seeds is not None and gp in self._gp_saved_seeds:
773
+ seed = self._gp_saved_seeds[gp]
774
+ else:
775
+ seed = self.c_random()
776
+
777
+ prev_seed = gp.getrand()
778
+ gp.setrand(seed)
779
+
780
+ if prev is not None:
781
+ if prev._gp_saved_seeds is None:
782
+ prev._gp_saved_seeds = weakref.WeakKeyDictionary()
783
+ prev._gp_saved_seeds[gp] = prev_seed
784
+
785
+ _gp_seed_randstates[gp] = self
786
+
787
+ def set_seed_pari(self):
788
+ r"""
789
+ Check to see if ``self`` was the most recent :class:`randstate` to
790
+ seed the Pari random number generator. If not, seeds the
791
+ generator.
792
+
793
+ .. NOTE::
794
+
795
+ Since pari 2.4.3, pari's random number generator has
796
+ changed a lot. the seed output by getrand() is now a
797
+ vector of integers.
798
+
799
+ EXAMPLES::
800
+
801
+ sage: set_random_seed(5551212)
802
+ sage: current_randstate().set_seed_pari()
803
+ sage: pari.getrand().type()
804
+ 't_INT'
805
+ """
806
+ global _pari_seed_randstate
807
+ if _pari_seed_randstate is not self:
808
+ from sage.libs.pari import pari
809
+
810
+ if self._pari_saved_seed is not None:
811
+ seed = self._pari_saved_seed
812
+ else:
813
+ seed = self.c_random()
814
+
815
+ prev_seed = pari.getrand()
816
+ pari.setrand(seed)
817
+
818
+ if _pari_seed_randstate is not None:
819
+ _pari_seed_randstate._pari_saved_seed = prev_seed
820
+
821
+ _pari_seed_randstate = self
822
+
823
+ cpdef int c_random(self) noexcept:
824
+ r"""
825
+ Return a 31-bit random number. Intended for internal
826
+ use only; instead of calling ``current_randstate().c_random()``,
827
+ it is equivalent (but probably faster) to call the
828
+ :meth:`random <sage.misc.randstate.random>` method of this
829
+ :class:`randstate` class.
830
+
831
+ EXAMPLES::
832
+
833
+ sage: set_random_seed(1207)
834
+ sage: current_randstate().c_random()
835
+ 2008037228
836
+
837
+ We verify the equivalence mentioned above. ::
838
+
839
+ sage: from sage.misc.randstate import random
840
+ sage: set_random_seed(1207)
841
+ sage: random()
842
+ 2008037228
843
+ """
844
+ return gmp_urandomb_ui(self.gmp_state, 31)
845
+
846
+ cpdef double c_rand_double(self) noexcept:
847
+ r"""
848
+ Return a random floating-point number between 0 and 1.
849
+
850
+ EXAMPLES::
851
+
852
+ sage: set_random_seed(2718281828)
853
+ sage: current_randstate().c_rand_double()
854
+ 0.22437207488974298
855
+ """
856
+ cdef double a = gmp_urandomb_ui(self.gmp_state, 25) * (1.0 / 33554432.0) # divide by 2^25
857
+ cdef double b = gmp_urandomb_ui(self.gmp_state, 28) * (1.0 / 9007199254740992.0) # divide by 2^53
858
+ return a+b
859
+
860
+ def __dealloc__(self):
861
+ r"""
862
+ Free up the memory from the ``gmp_randstate_t`` in a
863
+ :class:`randstate`.
864
+
865
+ EXAMPLES::
866
+
867
+ sage: from sage.misc.randstate import randstate
868
+ sage: foo = randstate()
869
+ sage: foo = None
870
+ """
871
+ gmp_randclear(self.gmp_state)
872
+
873
+ def __enter__(self):
874
+ r"""
875
+ Use a :class:`randstate` object as a ``with`` statement context
876
+ manager; switches this :class:`randstate` to be the current
877
+ :class:`randstate`, to be switched back on exit from the ``with``
878
+ statement.
879
+
880
+ For this purpose, we usually use the ``seed`` alias for
881
+ :class:`randstate`.
882
+
883
+ EXAMPLES::
884
+
885
+ sage: from sage.misc.randstate import randstate
886
+ sage: seed is randstate
887
+ True
888
+ sage: set_random_seed(-12345)
889
+ sage: ZZ.random_element(10^30)
890
+ 197130468050826967386035500824
891
+ sage: ZZ.random_element(10^30)
892
+ 601704412330400807050962541983
893
+ sage: set_random_seed(-12345)
894
+ sage: ZZ.random_element(10^30)
895
+ 197130468050826967386035500824
896
+ sage: with seed(12345):
897
+ ....: ZZ.random_element(10^30)
898
+ 197130468050826967386035500824
899
+ sage: ZZ.random_element(10^30)
900
+ 601704412330400807050962541983
901
+ """
902
+ global _current_randstate
903
+ randstate_stack.append(_current_randstate)
904
+ _current_randstate = self
905
+ return self
906
+
907
+ def __exit__(self, ty, value, traceback):
908
+ r"""
909
+ Use a :class:`randstate` object as a ``with`` statement context
910
+ manager; restores the previous :class:`randstate` as the current
911
+ :class:`randstate`.
912
+
913
+ For this purpose, we usually use the ``seed`` alias for
914
+ :class:`randstate`.
915
+
916
+ EXAMPLES::
917
+
918
+ sage: from sage.misc.randstate import randstate
919
+ sage: seed is randstate
920
+ True
921
+ sage: set_random_seed(-12345)
922
+ sage: ZZ.random_element(10^30)
923
+ 197130468050826967386035500824
924
+ sage: ZZ.random_element(10^30)
925
+ 601704412330400807050962541983
926
+ sage: set_random_seed(-12345)
927
+ sage: ZZ.random_element(10^30)
928
+ 197130468050826967386035500824
929
+ sage: with seed(12345):
930
+ ....: ZZ.random_element(10^30)
931
+ 197130468050826967386035500824
932
+ sage: ZZ.random_element(10^30)
933
+ 601704412330400807050962541983
934
+ """
935
+ global _current_randstate
936
+ _current_randstate = randstate_stack.pop()
937
+ return False
938
+
939
+
940
+ cpdef set_random_seed(seed=None):
941
+ r"""
942
+ Set the current random number seed from the given ``seed``
943
+ (which must be coercible to a Python long).
944
+
945
+ If no seed is given, then a seed is automatically selected
946
+ using :func:`os.urandom` if it is available, or the current
947
+ time otherwise.
948
+
949
+ Type ``sage.misc.randstate?`` for much more
950
+ information on random numbers in Sage.
951
+
952
+ This function is only intended for command line use. Never call
953
+ this from library code; instead, use ``with seed(s):``.
954
+
955
+ Note that setting the random number seed to 0 is much faster than
956
+ using any other number.
957
+
958
+ EXAMPLES::
959
+
960
+ sage: set_random_seed(5)
961
+ sage: initial_seed()
962
+ 5
963
+ """
964
+ global _current_randstate
965
+ _current_randstate = randstate(seed)
966
+
967
+ set_random_seed()
968
+
969
+ # Create an alias for randstate to be used in context managers
970
+ seed = randstate
971
+
972
+ cpdef int random() noexcept:
973
+ r"""
974
+ Return a 31-bit random number. Intended as a drop-in replacement for
975
+ the libc :func:`random()` function.
976
+
977
+ EXAMPLES::
978
+
979
+ sage: set_random_seed(31)
980
+ sage: from sage.misc.randstate import random
981
+ sage: random()
982
+ 32990711
983
+ """
984
+ return gmp_urandomb_ui(_current_randstate.gmp_state, 31)
985
+
986
+
987
+ def initial_seed():
988
+ r"""
989
+ Return the initial seed used to create the current :class:`randstate`.
990
+
991
+ EXAMPLES::
992
+
993
+ sage: set_random_seed(42)
994
+ sage: initial_seed()
995
+ 42
996
+
997
+ If you set a random seed (by failing to specify the seed), this is how
998
+ you retrieve the seed actually chosen by Sage. This can also be
999
+ used to retrieve the seed chosen for a new Sage run (if the user
1000
+ has not used ``set_random_seed()``). ::
1001
+
1002
+ sage: set_random_seed()
1003
+ sage: initial_seed() # random
1004
+ 121030915255244661507561642968348336774
1005
+ """
1006
+ return _current_randstate._seed
1007
+
1008
+
1009
+ def benchmark_libc():
1010
+ r"""
1011
+ This function was used to test whether moving from libc to GMP's
1012
+ Mersenne Twister for random numbers would be a significant slowdown.
1013
+
1014
+ EXAMPLES::
1015
+
1016
+ sage: from sage.misc.randstate import benchmark_libc, benchmark_mt
1017
+ sage: timeit('benchmark_libc()') # random
1018
+ 125 loops, best of 3: 1.95 ms per loop
1019
+ sage: timeit('benchmark_mt()') # random
1020
+ 125 loops, best of 3: 2.12 ms per loop
1021
+ """
1022
+ for _ in range(100000):
1023
+ c_libc_random()
1024
+
1025
+
1026
+ def benchmark_mt():
1027
+ r"""
1028
+ This function was used to test whether moving from libc to GMP's
1029
+ Mersenne Twister for random numbers would be a significant slowdown.
1030
+
1031
+ EXAMPLES::
1032
+
1033
+ sage: from sage.misc.randstate import benchmark_libc, benchmark_mt
1034
+ sage: timeit('benchmark_libc()') # random
1035
+ 125 loops, best of 3: 1.95 ms per loop
1036
+ sage: timeit('benchmark_mt()') # random
1037
+ 125 loops, best of 3: 2.11 ms per loop
1038
+ """
1039
+ cdef int i
1040
+ cdef randstate rstate = _current_randstate
1041
+ for i from 0 <= i < 100000:
1042
+ gmp_urandomb_ui(rstate.gmp_state, 32)
1043
+
1044
+
1045
+ cpdef int _doctest_libc_random() noexcept:
1046
+ r"""
1047
+ Return the result of :func:`random()` from libc.
1048
+
1049
+ Only for use in doctests; this should not actually be used in Sage,
1050
+ since the resulting random number stream is not portable across
1051
+ operating systems.
1052
+
1053
+ EXAMPLES::
1054
+
1055
+ sage: from sage.misc.randstate import _doctest_libc_random
1056
+ sage: _doctest_libc_random() # random
1057
+ 910236436
1058
+ """
1059
+ return c_libc_random()