From help-octave-request at bevo dot che dot wisc dot edu Tue Jul 13 22:41:09 1999 Subject: Re: bad random numbers From: lash at tellabs dot com To: mbmiller at taxa dot psyc dot missouri dot edu (Mike Miller) Cc: help-octave at bevo dot che dot wisc dot edu Date: Tue, 13 Jul 1999 22:40:30 -0500 (CDT) > > Not everyone is getting it. Look at these two lines: > > echo 'rand(3)' | octave -q > echo 'rand("seed",time);rand(3)' | octave -q > > Question: If rand gets its seed from the clock when octave starts, then > why does the first command line above give aberrant results while the > second command works beautifully? > > Answer: There is an error in the generation of the initial seed. > > Am I wrong? Well, the difference is the in the second example, time (on architectures that support gettimeofday()) has fractions of seconds of resolution. If you tried this on a system that does not support gettimeofday(), I think you would see that you would get the same numbers from time to time assuming that the while loop was running more than once a second. If you like, you can try the patch attatched below, that attempts to seed the random number generator in the same way that the second example does. I tend to agree with the folks who say that you shouldn't count on the first value that you get from each run being randomly distributed in any useable sense. Also remember that this will not really be better on platforms that do not have gettimeofday(). Bill Lash lash at tellabs dot com -----------Patch against octave 2.1.14 for file src/DLD-FUNCTION/rand.cc----- *** rand.cc.orig Tue Jul 13 22:27:02 1999 --- rand.cc Tue Jul 13 21:58:13 1999 *************** *** 33,38 **** --- 33,39 ---- #include "defun-dld.h" #include "error.h" + #include "systime.h" #include "gripes.h" #include "oct-obj.h" #include "unwind-prot.h" *************** *** 125,144 **** { time_t now; struct tm *tm; - time (&now); - tm = localtime (&now); - - int hour = tm->tm_hour + 1; - int minute = tm->tm_min + 1; - int second = tm->tm_sec + 1; ! int s0 = tm->tm_mday * hour * minute * second; ! int s1 = hour * minute * second; ! s0 = force_to_fit_range (s0, 1, 2147483563); ! s1 = force_to_fit_range (s1, 1, 2147483399); F77_XFCN (setall, SETALL, (s0, s1)); initialized = 1; --- 126,161 ---- { time_t now; struct tm *tm; + union d2i { double d; int i[2]; }; + union d2i u; + double fraction = 0.0; + int s0,s1; ! #if defined (HAVE_GETTIMEOFDAY) ! struct timeval tp; + #if defined (GETTIMEOFDAY_NO_TZ) + gettimeofday (&tp); + #else + gettimeofday (&tp, 0); + #endif + + now = tp.tv_sec; + + fraction = tp.tv_usec / 1e6; + + #else + + now = time (0); + + #endif + + u.d = static_cast (now) + fraction; + s0 = force_to_fit_range (u.i[0], 1, 2147483563); + s1 = force_to_fit_range (u.i[1], 1, 2147483399); + F77_XFCN (setall, SETALL, (s0, s1)); initialized = 1; --------------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. To ensure that development continues, see www.che.wisc.edu/octave/giftform.html Instructions for unsubscribing: www.che.wisc.edu/octave/archive.html ---------------------------------------------------------------------