home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mod201j.zip / modula2.exe / os2src / random.mod < prev    next >
Text File  |  1995-07-30  |  2KB  |  107 lines

  1. IMPLEMENTATION MODULE Random;
  2. (*
  3.     Title     : An implementation of pseudo random numbers
  4.     Author    : I.R. Matters (Ian.Matters@anu.edu.au)
  5.     System    : Juergen Neuhoff's Modula-2 compiler on OS/2
  6.     Reference : Alan R. Miller,
  7.                 "Pascal Programs for Scientists and Engineers",
  8.                 Sybex, 1981, pp 29
  9.     Version   : 1.00
  10.     Last Edit : 30 July 1995
  11. *)
  12.  
  13.  
  14. FROM MathLib0 IMPORT exp, ln;
  15. FROM OS2DEF   IMPORT APIRET;
  16.  
  17. (*$XL+ language extensions: allow extended import syntax *)
  18.  
  19. IMPORT FROM DOS;
  20.  
  21.  
  22. PROCEDURE Randomize;
  23. (*
  24.   Initialize the random number generator seed with a
  25.   pseudo-random value (obtained from the system clock).
  26. *)
  27. VAR t  : DATETIME;
  28.     rc : APIRET;
  29. BEGIN
  30.   rc := DosGetDateTime (t);
  31.   Seed := ((FLOAT (t.seconds) * 100.0) + FLOAT (t.hundredths)) / 750.0;
  32. END Randomize;
  33.  
  34.  
  35. PROCEDURE RandomReal(): REAL;
  36. (*
  37.    Return a random number in the range 0.0 <= RandomReal < 1.0 
  38. *)
  39. CONST Pi = 3.14159265358979;
  40. VAR x : REAL;
  41. BEGIN
  42.   x := Seed + Pi;
  43.   x := exp (5.0 * ln (x));
  44.   Seed := x - FLOAT (LONGTRUNC (x));
  45.   RETURN (Seed);
  46. END RandomReal;
  47.  
  48.  
  49. PROCEDURE RandomGaussReal(): REAL;
  50. (*
  51.    Return a random number with a Gaussian distribution
  52.    in the range 0.0 <= RandomGaussReal < 1.0 
  53. *)
  54. VAR r : REAL;
  55.  
  56.   PROCEDURE RandomGauss(): REAL;
  57.   CONST IdealMean      = 0.5;  (* for a range 0.0 .. 1.0 *)
  58.         IdealDeviation = 0.2887;
  59.   VAR i   : CARDINAL;
  60.       sum : REAL;
  61.   BEGIN
  62.     sum := 0.0;
  63.     FOR i := 1 TO 12 DO
  64.       sum := sum + RandomReal();
  65.     END;  (* FOR *)
  66.     RETURN ((sum - 6.0) * IdealDeviation + IdealMean);
  67.   END RandomGauss;
  68.  
  69. BEGIN
  70.  
  71.   (* Make absolutely sure that the value lies within the desired range *)
  72.  
  73.   REPEAT
  74.     r := RandomGauss();
  75.   UNTIL ((r >= 0.0) AND (r < 1.0));
  76.  
  77.   RETURN (r);
  78. END RandomGaussReal;
  79.  
  80.  
  81. PROCEDURE RandomCard (Range: CARDINAL): CARDINAL;
  82. (*
  83.    Return a random number in the range 0 <= RandomCard < Range 
  84. *)
  85. VAR i : LONGCARD;
  86. BEGIN
  87.   i := LONGTRUNC (RandomReal() * FLOAT (Range));
  88.   RETURN (SHORT (i));
  89. END RandomCard;
  90.  
  91.  
  92. PROCEDURE RandomGaussCard (Range: CARDINAL): CARDINAL;
  93. (*
  94.    Return a random number with a Gaussian distribution
  95.    in the range 0 <= RandomGaussCard < Range 
  96. *)
  97. VAR i : LONGCARD;
  98. BEGIN
  99.   i := LONGTRUNC (RandomGaussReal() * FLOAT (Range));
  100.   RETURN (SHORT (i));
  101. END RandomGaussCard;
  102.  
  103.  
  104. BEGIN  (* Initialization *)
  105.   Seed := 4.0;
  106. END Random.
  107.