[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

random numbers in CL

Jim Newton

1/26/2016 3:28:00 PM

Can someone explain to me how to use RANDOM and MAKE-RANDOM-STATE so that
every time I run a function the random see starts again at the same point.
In my case I want to exercise a function through several hundred random numbers.
But when I re-run the function, I want the same sequence of random numbers, and tomorrow
when I exit lisp and restart, I still want the same random numbers as yesterday.

Is this possible, or do I simply need to generate a list of several 100 random numbers
and hard code that list into my program?

12 Answers

Kaz Kylheku

1/26/2016 3:56:00 PM

0

On 2016-01-26, Jim Newton <jimka.issy@gmail.com> wrote:
> Can someone explain to me how to use RANDOM and MAKE-RANDOM-STATE so that
> every time I run a function the random see starts again at the same point.

To get a repeatable random state, you have to construct it from a fixed
seed. Unfortunately, the only seed that MAKE-RANDOM-STATE takes is a
random state. So you have to stash a random state object somewhere,
and don't touch that object. Whenever you enter the function you can
then rebind the *random-state* special variable:

(let ((*random-state* (make-random-state my-stashed-random-state)))
... code goes here ...)

If you don't want interference (third party functions using your
*random-state* in ways you don't control) then pass down your own
random state context and use that in all the calls to random.
(As an argument that you pass everywhere, or via your own special
variable similar to *random-state*).

> In my case I want to exercise a function through several hundred random numbers.
> But when I re-run the function, I want the same sequence of random numbers, and tomorrow
> when I exit lisp and restart, I still want the same random numbers as yesterday.
>
> Is this possible, or do I simply need to generate a list of several 100 random numbers
> and hard code that list into my program?

When you start the Lisp, snapshot the random state:

(defparameter *my-stashed-random-state* (make-random-state))

excelemailer

1/26/2016 4:12:00 PM

0

On Tuesday, January 26, 2016 at 7:28:26 AM UTC-8, Jim Newton wrote:
> Can someone explain to me how to use RANDOM and MAKE-RANDOM-STATE so that
> every time I run a function the random see starts again at the same point.
> In my case I want to exercise a function through several hundred random numbers.
> But when I re-run the function, I want the same sequence of random numbers, and tomorrow
> when I exit lisp and restart, I still want the same random numbers as yesterday.
>
> Is this possible, or do I simply need to generate a list of several 100 random numbers
> and hard code that list into my program?

Although, I haven't verified whether you get the same randomness from one day to the next, (random) appears to use the same seed every time without having to configure anything, producing the same results from one run to the next. I'm using SBCL.

Kaz Kylheku

1/26/2016 4:14:00 PM

0

On 2016-01-26, excelemailer@gmail.com <excelemailer@gmail.com> wrote:
> On Tuesday, January 26, 2016 at 7:28:26 AM UTC-8, Jim Newton wrote:
>> Can someone explain to me how to use RANDOM and MAKE-RANDOM-STATE so that
>> every time I run a function the random see starts again at the same point.
>> In my case I want to exercise a function through several hundred random numbers.
>> But when I re-run the function, I want the same sequence of random numbers, and tomorrow
>> when I exit lisp and restart, I still want the same random numbers as yesterday.
>>
>> Is this possible, or do I simply need to generate a list of several 100 random numbers
>> and hard code that list into my program?
>
> Although, I haven't verified whether you get the same randomness from
> one day to the next, (random) appears to use the same seed every time
> without having to configure anything, producing the same results from
> one run to the next. I'm using SBCL.

That's where "one run" means restarting the Lisp image, not calling the
same function.

The PRNG in any darn programming language better have this property as a
default: same sequence unless otherwise seeded.

Pascal J. Bourguignon

1/26/2016 8:02:00 PM

0

Kaz Kylheku <609-576-4089@kylheku.com> writes:

> On 2016-01-26, excelemailer@gmail.com <excelemailer@gmail.com> wrote:
>> On Tuesday, January 26, 2016 at 7:28:26 AM UTC-8, Jim Newton wrote:
>>> Can someone explain to me how to use RANDOM and MAKE-RANDOM-STATE so that
>>> every time I run a function the random see starts again at the same point.
>>> In my case I want to exercise a function through several hundred random numbers.
>>> But when I re-run the function, I want the same sequence of random numbers, and tomorrow
>>> when I exit lisp and restart, I still want the same random numbers as yesterday.
>>>
>>> Is this possible, or do I simply need to generate a list of several 100 random numbers
>>> and hard code that list into my program?
>>
>> Although, I haven't verified whether you get the same randomness from
>> one day to the next, (random) appears to use the same seed every time
>> without having to configure anything, producing the same results from
>> one run to the next. I'm using SBCL.
>
> That's where "one run" means restarting the Lisp image, not calling the
> same function.
>
> The PRNG in any darn programming language better have this property as a
> default: same sequence unless otherwise seeded.

It's unspecified how *random-state* is initialized. On the other hand,
with ccl, clisp, and sbcl you can save random states in fasl files.
So you can use this implementation dependant way to save random states:

----------------------------------------------------------------------------------

(defvar *saved-random-state-file* nil
"A temporary used by load-random-state.")

#-(or ccl clisp sbcl)
(eval-when (:compile-toplevel :load-toplevel :execute)
(error "Not implemented yet on ~A" (lisp-implementation-type)))

#+(or ccl clisp sbcl)
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun save-a-random-random-state (pathname random-state)
"Saves the RANDOM-STATE to the PATHNAME (file type is replaced
with \"random-state\").
Returns the actual pathname of the saved file.
Note: this writes a temporary lisp source file with the \"lisp\" file type."
(compile-file (with-open-file (source (make-pathname :type "lisp"
:defaults pathname)
:direction :output
:if-does-not-exist :create
:if-exists :supersede)
(print `(eval-when (:compile-toplevel :load-toplevel :execute)
(defparameter *saved-random-state-generator*
(let ((random-state ',random-state))
(lambda () (make-random-state random-state)))))
source)
(terpri source)
source)
:output-file (make-pathname :type "random-state"
:defaults pathname)))
(defun load-random-state (pathname)
"Loads and return the random-state saved in the file at PATHNAME."
(let ((*saved-random-state-generator*
(lambda () (make-random-state *random-state*))))
(load pathname)
*saved-random-state-generator*)))


(defvar *my-random-state-generator*)

(defun randomize-my-random-state ()
(setf *my-random-state-generator*
(load-random-state
(setf *saved-random-state-file*
(save-a-random-random-state
(merge-pathnames (make-pathname :directory '(:relative ".config")
:name "my-random"
:version nil
:defaults (user-homedir-pathname))
(user-homedir-pathname))
*random-state*)))))

(defun get-my-random-state ()
(funcall *my-random-state-generator*))



(defmacro with-my-random-state (&body body)
`(let ((*random-state* (get-my-random-state)))
,@body))


(defun test-my-random-state ()
(with-my-random-state (print (loop repeat 10 collect (random 256))))
(with-my-random-state (print (loop repeat 10 collect (random 256))))
(with-my-random-state (print (loop repeat 10 collect (random 256))))
(randomize-my-random-state)
(with-my-random-state (print (loop repeat 10 collect (random 256))))
(with-my-random-state (print (loop repeat 10 collect (random 256))))
(with-my-random-state (print (loop repeat 10 collect (random 256)))))


(randomize-my-random-state)
----------------------------------------------------------------------------------
;; (test-my-random-state)
;; prints eg.:
;; (97 27 27 80 30 123 236 117 250 87)
;; (97 27 27 80 30 123 236 117 250 87)
;; (97 27 27 80 30 123 236 117 250 87)
;; (191 14 195 48 99 237 87 150 9 50)
;; (191 14 195 48 99 237 87 150 9 50)
;; (191 14 195 48 99 237 87 150 9 50)


--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Alan Bawden

1/26/2016 8:35:00 PM

0

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:
> It's unspecified how *random-state* is initialized. On the other hand,
> with ccl, clisp, and sbcl you can save random states in fasl files.
> So you can use this implementation dependant way to save random states:

Doesn't Common Lisp guarantee that random state objects can be read and
printed? That would give you an implementation independent way of
saving them in ordinary text files.

--
Alan Bawden

Pascal J. Bourguignon

1/26/2016 8:49:00 PM

0

Alan Bawden <alan@csail.mit.edu> writes:

> "Pascal J. Bourguignon" <pjb@informatimago.com> writes:
>> It's unspecified how *random-state* is initialized. On the other hand,
>> with ccl, clisp, and sbcl you can save random states in fasl files.
>> So you can use this implementation dependant way to save random states:
>
> Doesn't Common Lisp guarantee that random state objects can be read and
> printed? That would give you an implementation independent way of
> saving them in ordinary text files.

That's correct, I forgot. So a mere print/read with *print-readably*
bound to true would be enough.



--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

smh

1/29/2016 10:48:00 AM

0

It would be sufficient simply to paste the printed representation of a random state into the program source, e.g. as the value subform of a defparameter.

But beware that reproducible behavior of random and make-random-state is guaranteed only over that particular lisp platform, implementation, and version. Your benchmarks may get different random numbers in some future release or in some different implementation or platform. For insurance, the 32 and 64 bit versions of the same lisp might produce very different random sequences, and a printed random state from one platform might not even be readable on another.

Barry Margolin

1/29/2016 3:10:00 PM

0

In article <af3afd89-c273-48f1-8bff-19f4d8f68dce@googlegroups.com>,
smh <shaflich@gmail.com> wrote:

> It would be sufficient simply to paste the printed representation of a random
> state into the program source, e.g. as the value subform of a defparameter.
>
> But beware that reproducible behavior of random and make-random-state is
> guaranteed only over that particular lisp platform, implementation, and
> version. Your benchmarks may get different random numbers in some future
> release or in some different implementation or platform. For insurance, the
> 32 and 64 bit versions of the same lisp might produce very different random
> sequences, and a printed random state from one platform might not even be
> readable on another.

The same is generally true in any programming language. Whatever you
provide as a random seed will only produce the same sequence if you're
using the same RNG implementation.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Pascal Costanza

1/29/2016 7:11:00 PM

0

On 29/01/2016 16:10, Barry Margolin wrote:
> In article <af3afd89-c273-48f1-8bff-19f4d8f68dce@googlegroups.com>,
> smh <shaflich@gmail.com> wrote:
>
>> It would be sufficient simply to paste the printed representation of a random
>> state into the program source, e.g. as the value subform of a defparameter.
>>
>> But beware that reproducible behavior of random and make-random-state is
>> guaranteed only over that particular lisp platform, implementation, and
>> version. Your benchmarks may get different random numbers in some future
>> release or in some different implementation or platform. For insurance, the
>> 32 and 64 bit versions of the same lisp might produce very different random
>> sequences, and a printed random state from one platform might not even be
>> readable on another.
>
> The same is generally true in any programming language. Whatever you
> provide as a random seed will only produce the same sequence if you're
> using the same RNG implementation.

That's not generally true. See for example
http://en.cppreference.com/w/cpp/nume...

Pascal

--
My website: http:/...
Common Lisp Document Repository: http://cdr.eu...
Closer to MOP & ContextL: http://common-lisp.net/proje...
The views expressed are my own, and not those of my employer.

Barry Margolin

1/29/2016 7:36:00 PM

0

In article <dh1rpiFqnb3U1@mid.individual.net>,
Pascal Costanza <pc@p-cos.net> wrote:

> On 29/01/2016 16:10, Barry Margolin wrote:
> > In article <af3afd89-c273-48f1-8bff-19f4d8f68dce@googlegroups.com>,
> > smh <shaflich@gmail.com> wrote:
> >
> >> It would be sufficient simply to paste the printed representation of a
> >> random
> >> state into the program source, e.g. as the value subform of a
> >> defparameter.
> >>
> >> But beware that reproducible behavior of random and make-random-state is
> >> guaranteed only over that particular lisp platform, implementation, and
> >> version. Your benchmarks may get different random numbers in some future
> >> release or in some different implementation or platform. For insurance,
> >> the
> >> 32 and 64 bit versions of the same lisp might produce very different
> >> random
> >> sequences, and a printed random state from one platform might not even be
> >> readable on another.
> >
> > The same is generally true in any programming language. Whatever you
> > provide as a random seed will only produce the same sequence if you're
> > using the same RNG implementation.
>
> That's not generally true. See for example
> http://en.cppreference.com/w/cpp/nume...
>
> Pascal

I think that's an exception, not the general rule.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***