Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: st: Random seeder
From
[email protected] (William Gould, StataCorp LP)
To
[email protected]
Subject
Re: st: Random seeder
Date
Wed, 29 Sep 2010 10:36:19 -0500
Antoine Terracol <[email protected]> writes,
> some time ago, there was a discussion on Statalist about
> getting a random seed for Stata's PRNG. Bill Gould suggested
> that someone should write a little program to obtain (true)
> random numbers from random.org
> (see http://www.stata.com/statalist/archive/2010-08/msg00930.html)
>
> Based on R's random package, here's a first try, for anyone interrested
I like it.
In what follows,
1. I make some minor but important fixes to Antoine's program,
and explain.
2. I improve and rename Antoine's program. The improvement
deals with making sure the command fails if random.org
someday changes their syntax or how they return results.
Everything is below. I suspect from here on out, Antoine and I should
work privately and just report the final result when we are done.
In my version of Antoine's program, I renamed the command -setrngseed-, and I
reversed Antoine's -setseed- option so that the option is now -nosetseed-
and default is to reset the random-number seed. The command has syntax
setrngseed [, nosetseed min(#) max(#)]
The options are useful for debugging -setrngseed- and are probably not
worth documenting. I suggest that when Antoine writes the documentation,
or he makes me write it, we document the syntax as simply being
setrngseed
Here's what happens when you type it:
. setrngseed
(contacting http://www.random.org)
(random-number seed set to 697429737)
Antoine's program, fixed
------------------------
Here is Antoine's original program, updated,
-----------------------------------------------------------------
program define truernd, rclass
syntax [, min(integer 1) max(integer 1000000000) setseed]
tempfile rndseed
tempname myseed
quietly copy "http://www.random.org/integers/?num=1&min=`min'&max=`max'&col=1&base=10&format=plain&rnd=new" "`rndseed'", replace
file open `myseed' using "`rndseed'", read text
file read `myseed' value
file close `myseed'
return scalar rndvalue=`value'
di "The value returned by www.random.org is `value'"
if "`setseed'"!="" {
set seed `value'
display "The seed was set to `value'"
return scalar seed=`value'
}
end
-----------------------------------------------------------------
Warning: the line in the middle that begins -quietly copy- is a single,
long line and there are no blanks within the quioted string "http://...".
I made trhee small changes, two important and the third more a
matter of style.
1. Antoine used the temporary filename `rndseed'.txt; I use `rndseed'.
This is important. Stata assumes you use temporary file
names in the form Stata supplied them. When your program concludes,
Stata erases files with those names. When Antoine
used `rndseed'.txt, Stata still attempted to erase `rndseed'
when the program concluded, and never even attempted to erase
`rndseed'.txt.
2. I enclose the temporary filename `rndseed' in double quotes everytime
I use it; I code "`rndseed'" rather than `rndseed'.
This is important because, on some computers, the system
directory that contains the temporary files has blanks (spaces)
in its name.
3. Antoine used -`value'- and -``value''-; I used -value- and -`value'-.
-value- in Antoine's code, and my update, is a macro. Antoine put a
temporary name in -value- and used macro `value' thereafter,
meaning the contents of `value' were ``value''. That was unnecessary;
macros are private anyway.
setrngseed
----------
Here is the -setrngseed- code.
------------------------------------------------------------------------
program define setrngseed, rclass
version 11
syntax [, MIN(integer 1) MAX(integer 1000000000) noSETseed]
get_random_number `min' `max'
local value "`r(result)'"
if ("`setseed'"=="") {
set seed `value'
di as txt "(random-number seed set to `value')"
}
else {
di as txt " random.org returns `value' (seed not set)"
}
return scalar seed = `value'
end
program get_random_number, rclass
args min max
tempfile rndseed
tempname myseed
display as txt "(contacting http://www.random.org)"
quietly copy "http://www.random.org/integers/?num=2&min=`min'&max=`max'&col=1&base=10&format=plain&rnd=new" "`rndseed'"
file open `myseed' using "`rndseed'", read text
file read `myseed' value1
file read `myseed' value2
file close `myseed'
check_integer_result `value1'
check_integer_result `value2'
if (`value1' != `value2') {
return local result `value1'
exit
}
di as err "{p 0 4 2}"
di as err "random.org behaved unexpectedly{break}"
di as err "random.org returned the same random"
di as err "valiue twice, so the values are not"
di as err "random or a very unlikely event occured."
di as err "{p_end}"
exit 674
end
program check_integer_result
args value
capture confirm integer number `value'
if (_rc) {
di as err "{p 0 4 2}"
di as err "random.org behaved unexpectedly{break}"
di as err `"value returned was "`value'", which"'
di as err "was not an integer."
di as err "{p_end}"
exit 674
}
end
------------------------------------------------------------------------
The code looks different from Antoine's, but it's not much changed.
It looks different because I made my additions by adding subroutines,
which I think makes the code more readable.
Here is what is substantively different:
1. I verify that the results returned by random.org really are
integers.
2. I ask random.org for two random numbers rather than one.
I verify that they are different.
I'm worried that random.org might someday change their syntax or what
they return. If random.org did that, Antoine's original program would
probably break, but I wanted to make sure the program broke if results
were not as expected.
By the way, I tried to make another change, but failed.
I tried changing
syntax [, MIN(integer 1) MAX(integer 1000000000) noSETseed]
to
syntax [, MIN(integer 1) MAX(integer 2147483647) noSETseed]
but when I did that, www.random.org reported an error. I then tried
syntax [, MIN(integer 1) MAX(integer 2000000000) noSETseed]
and random.org still reported an error. So I changed back to how
Antoine had it.
Antoine, do you know how many bits random.org bases their random number on?
-- Bill
[email protected]
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/