*DECK RUNIF FUNCTION RUNIF (T, N) C***BEGIN PROLOGUE RUNIF C***PURPOSE Generate a uniformly distributed random number. C***LIBRARY SLATEC (FNLIB) C***CATEGORY L6A21 C***TYPE SINGLE PRECISION (RUNIF-S) C***KEYWORDS FNLIB, RANDOM NUMBER, SPECIAL FUNCTIONS, UNIFORM C***AUTHOR Fullerton, W., (LANL) C***DESCRIPTION C C This random number generator is portable among a wide variety of C computers. It generates a random number between 0.0 and 1.0 accord- C ing to the algorithm presented by Bays and Durham (TOMS, 2, 59, C 1976). The motivation for using this scheme, which resembles the C Maclaren-Marsaglia method, is to greatly increase the period of the C random sequence. If the period of the basic generator (RAND) is P, C then the expected mean period of the sequence generated by RUNIF is C given by new mean P = SQRT (PI*FACTORIAL(N)/(8*P)), C where FACTORIAL(N) must be much greater than P in this asymptotic C formula. Generally, N should be around 32 if P=4.E6 as for RAND. C C Input Argument -- C N ABS(N) is the number of random numbers in an auxiliary table. C Note though that ABS(N)+1 is the number of items in array T. C If N is positive and differs from its value in the previous C invocation, then the table is initialized for the new value of C N. If N is negative, ABS(N) is the number of items in an C auxiliary table, but the tables are now assumed already to C be initialized. This option enables the user to save the C table T at the end of a long computer run and to restart with C the same sequence. Normally, RUNIF would be called at most C once with negative N. Subsequent invocations would have N C positive and of the correct magnitude. C C Input and Output Argument -- C T an array of ABS(N)+1 random numbers from a previous invocation C of RUNIF. Whenever N is positive and differs from the old C N, the table is initialized. The first ABS(N) numbers are the C table discussed in the reference, and the N+1 -st value is Y. C This array may be saved in order to restart a sequence. C C Output Value -- C RUNIF a random number between 0.0 and 1.0. C C***REFERENCES (NONE) C***ROUTINES CALLED RAND C***REVISION HISTORY (YYMMDD) C 770401 DATE WRITTEN C 890531 Changed all specific intrinsics to generic. (WRB) C 890531 REVISION DATE from Version 3.2 C 891214 Prologue converted to Version 4.0 format. (BAB) C 910819 Added EXTERNAL statement for RAND due to problem on IBM C RS 6000. (WRB) C***END PROLOGUE RUNIF DIMENSION T(*) EXTERNAL RAND SAVE NOLD, FLOATN DATA NOLD /-1/ C***FIRST EXECUTABLE STATEMENT RUNIF IF (N.EQ.NOLD) GO TO 20 C NOLD = ABS(N) FLOATN = NOLD IF (N.LT.0) DUMMY = RAND (T(NOLD+1)) IF (N.LT.0) GO TO 20 C DO 10 I=1,NOLD T(I) = RAND (0.) 10 CONTINUE T(NOLD+1) = RAND (0.) C 20 J = T(NOLD+1)*FLOATN + 1. T(NOLD+1) = T(J) RUNIF = T(J) T(J) = RAND (0.) C RETURN END