*! version 2.0.1 04oct2010 /* setrngseed Authors: Antoine Terracol, Université Paris 1, Centre d'Économie de la Sorbonne William Gould, StataCorp -setrngseed- sets Stata's uniform pseudo-random-number generator's seed to a value returned from http://www.random.org. */ program define setrngseed, rclass version 10 syntax [, noSETseed Verify Query] /* ------------------------------------------------------------ */ /* check syntax */ if ("`query'"!="" & ("`setseed'"!="" | "`verify'"!="")) { di as error /// "option query cannot be used concurrently with options nosetseed and verify" exit 198 } /* ------------------------------------------------------------ */ /* check quota */ if ("`query'"!="") { check_quota local quota=r(quota) return scalar quota=`quota' exit } /* ------------------------------------------------------------ */ /* obtain real random seed */ get_random_seed "`verify'" local value "`r(result)'" /* ------------------------------------------------------------ */ /* set seed */ 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 check_quota, rclass tempfile rndquota tempname myquota local site "http://www.random.org" display as txt "(contacting `site', checking quota)" qui copy "`site'/quota/?format=plain" "`rndquota'" file open `myquota' using "`rndquota'", read text file read `myquota' quota file close `myquota' local quotanum=floor(`quota'/31) di as txt /// "current IP's 24-hour quota is `quota' bits, about `quotanum' random seeds" return scalar quota=`quota' end program get_random_seed, rclass args check tempfile rndseed tempname myseed /* ------------------------------------------------------------ */ /* obtain random number(s) */ local min -1000000000 local max 1000000000 local toadd 1000000000 local num = cond("`check'"=="", 1, 2) local site "http://www.random.org" local args "/integers/?num=`num'&min=`min'&max=`max'" local args "`args'&col=1&base=10&format=plain&rnd=new" display as txt "(contacting `site')" qui copy "`site'`args'" "`rndseed'" file open `myseed' using "`rndseed'", read text file read `myseed' value1 if ("`check'" != "") { file read `myseed' value2 } file close `myseed' /* ------------------------------------------------------------ */ /* check results */ check_integer_result `"`value1'"' local value1 = `value1' + `toadd' if ("`check'" == "") { return local result `value1' exit } /* ------------------------------------------------------------ */ /* check second value, and compare with the first */ check_integer_result `"`value2'"' local value2 = `value2' + `toadd' 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" di as err "value 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