home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / function / 1075 < prev    next >
Encoding:
Internet Message Format  |  1992-09-08  |  2.6 KB

  1. Path: sparky!uunet!gatech!bloom-beacon!eru.mt.luth.se!lunic!sunic!chalmers.se!cs.chalmers.se!augustss
  2. From: augustss@cs.chalmers.se (Lennart Augustsson)
  3. Newsgroups: comp.lang.functional
  4. Subject: Re: Random number generator for Haskell (wanted)
  5. Keywords: Random numbers, code, Haskelln
  6. Message-ID: <1992Sep7.193930.19632@cs.chalmers.se>
  7. Date: 7 Sep 92 19:39:30 GMT
  8. References: <bruce.715827183@probitas>
  9. Sender: news@cs.chalmers.se (News administrator)
  10. Organization: Chalmers University of Technology
  11. Lines: 65
  12.  
  13. In article <bruce.715827183@probitas> waugh@probitas.cs.utas.edu.au (Sam Waugh) writes:
  14. >Hi.
  15. >
  16. >I was wondering if anybody has implemented a random number generator
  17. >in Haskell?  I am trying to use Haskell for some neural network
  18. >applications and definitely need a good random function.  Otherwise
  19. >its back to Pascal and C (sob, sob).
  20. Yes it's been done.  It comes with hbc.  And here it is!!
  21.  
  22. {-
  23.    This module implements a (good) random number generator.
  24.  
  25.    The June 1988 (v31 #6) issue of the Communications of the ACM has an
  26.    article by Pierre L'Ecuyer called, "Efficient and Portable Combined
  27.    Random Number Generators".  Here is the Portable Combined Generator of
  28.    L'Ecuyer for 32-bit computers.  It has a period of roughly 2.30584e18.
  29.  
  30.    Transliterator: Lennart Augustsson
  31. -}
  32.  
  33. module Random(randomInts, randomDoubles) where
  34. -- Use seeds s1 in 1..2147483562 and s2 in 1..2147483398 to generate
  35. -- an infinite list of random Ints.
  36. randomInts :: Int -> Int -> [Int]
  37. randomInts s1 s2 =
  38.     if 1 <= s1 && s1 <= 2147483562 then
  39.     if 1 <= s2 && s2 <= 2147483398 then
  40.         rands s1 s2
  41.     else
  42.         error "randomInts: Bad second seed."
  43.     else
  44.     error "randomInts: Bad first seed."
  45.  
  46. rands :: Int -> Int -> [Int]
  47. rands s1 s2 =
  48.     let
  49.     k    = s1 `div` 53668
  50.     s1'  = 40014 * (s1 - k * 53668) - k * 12211
  51.     s1'' = if s1' < 0 then s1' + 2147483563 else s1'
  52.     
  53.     k'   = s2 `div` 52774
  54.     s2'  = 40692 * (s2 - k' * 52774) - k' * 3791
  55.     s2'' = if s2' < 0 then s2' + 2147483399 else s2'
  56.  
  57.     z    = s1'' - s2''
  58. {-
  59.     z'   = if z < 1 then z + 2147483562 else z
  60.  
  61.     in  z' : rands s1'' s2''
  62. -}
  63. -- Use this instead; it is a little stricter and generates much better code
  64.     in  if z < 1 then z + 2147483562 : rands s1'' s2'' 
  65.                  else z : rands s1'' s2''
  66.  
  67. -- For those of you who don't have fromInt
  68. -- fromInt = fromInteger . toInteger
  69.  
  70. -- Same values for s1 and s2 as above, generates an infinite
  71. -- list of Doubles uniformly distibuted in (0,1).
  72. randomDoubles :: Int -> Int -> [Double]
  73. randomDoubles s1 s2 = map (\x -> fromInt x * 4.6566130638969828e-10) (randomInts s1 s2)
  74. -- 
  75.  
  76.     -- Lennart Augustsson
  77. [This signature is intentionally left blank.]
  78.