On Oct 8, 10:10 am, "William Stein" <[EMAIL PROTECTED]> wrote: > I agree. However, I strongly encourage people to discuss > this a bit longer in sage-devel before implementing something. > Whatever we do it will likely be easy to implement but hard > to design.
OK, here's my preliminary proposal for a class randgen, that manages random number generators and seeds. Note that the methods of randgen are intended to be used by library authors (like the authors of ZZ.random_element() and RR.random_element()), not directly by end-users; end-users may create randgen objects and pass them around, but would probably never directly call any methods on them. randgen is a Cython class. The main state it holds is a gmp_randstate_t, although it also has some other cached information. randgen methods include: python_random() Returns an instance of random.Random. The first time it is called on a given instance of randgen, a new random.Random is created and seeded from the gmp_randstate_t; this is saved, and subsequent calls return the same random.Random instance. set_seed_libc() set_seed_ntl() set_seed_pari() set_seed_magma() set_seed_mathematica() set_seed_...() Sets the seed of the specified random number generator, from a new random number from the gmp_randstate_t. new_randgen() Creates a new randgen object, seeded from a random number from this object's gmp_randstate_t. Also, Cython code can just access the gmp_randstate_t directly. Constructor: randgen() Create a new randgen, seeded randomly (from os.urandom() if available, from the system time otherwise). randgen(n) Create a new randgen, seeded from n. One of my design goals is that if algorithm A calls algorithm B, where both A and B use random numbers, it should be possible to change algorithm B (for instance, to use a different number of random numbers) without affecting the random numbers seen by algorithm A. The interface supports that by having algorithm A call .new_randgen() on its randgen object, and passing this new randgen to algorithm B. Algorithm A's isolation from algorithm B is then perfect if B uses only the main gmp_randstate_t or python_random(); if the algorithms use one of the other random number generators, then isolation is achieved if both algorithms use set_seed_...() before every use of the corresponding random number generator. There is a single global default randgen, named default_rgen. Every function/method that uses random numbers has an optional argument rgen, and is declared with rgen=default_rgen. So ZZ.random_element() would use the gmp_randstate_t inside the default randgen, but ZZ.random_element(rgen=randgen(3)) would create a new randgen and use the gmp_randstate_t inside it. (So it would return the same number every time.) To make a sequence of doctests repeatable, any of the following would work: sage: sage.misc.random.default_rgen = randgen(1) sage: ZZ.random_element() sage: RR.random_element() or sage: rgen = randgen(1) sage: ZZ.random_element(rgen=rgen) sage: RR.random_element(rgen=rgen) or sage: ZZ.random_element(rgen=rgen(1)) sage: RR.random_element(rgen=rgen(1)) (The first two options would print the same random numbers as each other. In the third option, the second line would print a different random number.) The names "rgen" and "randgen" are carefully chosen not to include the string "random", to avoid triggering the doctest feature "ignore doctests that include the word random". But if people like this approach, which allows "random" doctests to still give identical results across runs and across machines, then maybe that doctest feature should be disabled. What do you think? Carl --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---