random number generator random() questionable!!!?
Alex Martelli
staff at cadlab.sublink.ORG
Fri Sep 7 02:05:55 AEST 1990
ben at dit.lth.se (Ben Smeets) writes:
>Hi:
>After doing some simulations I got suspicious about the UNIX random
>number generator random() available on the SUN3-xx machines (ver 4.1).
...
> 2) Has anybody else noted some stange things with
> this random number generator.?
Don't know about this particular one, but random number generators are
notoriously easy-to-botch...
> 3) Are the people who can provide me with a good random
> number generator?
Knuth, "Art of Computer programming", volume 2, is a great reference.
Here's an implementation which is SLOW (boy, is it ever!) but gives
random uniform variates with GREAT spectral characteristics, and
(very important to ME) the SAME sequence of numbers on ANY platform
whatsoever (should not be hard to recode in C):
FUNCTION RAN1(IDUM)
*
* PORTABLE random-number generation routine, computationally costly
* but with nonpareil characteristics. From "Numerical recipes", p.196;
* identifiers as in the original; added explicit declarations & SAVE.
*
* Call with IDUM < 0 to re-seed (not needed the first time), IDUM == 0
* for normal operation.
*
* Note the SAME sequence is generated on ANY machine (crucial for use
* of random numbers for any intra-machine test!).
*
REAL*4 RAN1,R(97),RM1,RM2
INTEGER*4 IDUM,M1,M2,M3,IA1,IA2,IA3,IC1,IC2,IC3,IFF,IX1,IX2,IX3,J
PARAMETER (M1=259200,IA1=7141,IC1=54773,RM1=1.0/M1)
PARAMETER (M2=134456,IA2=8121,IC2=28411,RM2=1.0/M2)
PARAMETER (M3=243000,IA3=4561,IC3=51349)
SAVE IFF, R, IX1, IX2, IX3
DATA IFF /0/
*
* Initialize on first call, or whenever the parm is negative
*
IF(IDUM.lt.0 .or. IFF.eq.0) THEN
IFF=1
* seed first routine
IX1=MOD(IC1-IDUM,M1)
IX1=MOD(IA1*IX1+IC1,M1)
* seed second routine
IX2=MOD(IX1,M2)
IX1=MOD(IA1*IX1+IC1,M1)
* seed third routine
IX3=MOD(IX1,M3)
* fill table w. 1st/2nd routines
DO 11, J=1,97
IX1=MOD(IA1*IX1+IC1,M1)
IX2=MOD(IA2*IX2+IC2,M2)
* combine hi with lo
R(J)=(FLOAT(IX1)+FLOAT(IX2)*RM2)*RM1
11 CONTINUE
IDUM=1
ENDIF
NCALLS = NCALLS + 1
*
* Starting point, save when (re)initializing: get next number on
* each of the three sequences
*
IX1=MOD(IA1*IX1+IC1,M1)
IX2=MOD(IA2*IX2+IC2,M2)
IX3=MOD(IA3*IX3+IC3,M3)
* take index from 3rd sequence
J=1+(97*IX3)/M3
* sanity check, may omit in production
IF(J.GT.97.OR.J.LT.1) THEN
WRITE(*,*) 'RAN1: J=',J,' IX3=',IX3
STOP
ENDIF
* return this entry of table...
RAN1=R(J)
* ...and refill it
R(J)=(FLOAT(IX1)+FLOAT(IX2)*RM2)*RM1
RETURN
END
--
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 45, Bologna, Italia
Email: (work:) staff at cadlab.sublink.org, (home:) alex at am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434;
Fax: ++39 (51) 366964 (work only; any time of day or night).
More information about the Comp.unix.questions
mailing list