Commits

Aleksey Khudyakov committed 3f9179c

Add workaround proposed by @dzhus for bug #16

For some reason normal written this way works fast. But old was
~250 times slower than standard.

  • Participants
  • Parent commits 184eaad

Comments (0)

Files changed (1)

System/Random/MWC/Distributions.hs

        -> Gen (PrimState m)
        -> m Double
 {-# INLINE normal #-}
-normal m s gen = do
-  x <- standard gen
-  return $! m + s * x
-
--- | Generate a normally distributed random variate with zero mean and
--- unit variance.
---
--- The implementation uses Doornik's modified ziggurat algorithm.
--- Compared to the ziggurat algorithm usually used, this is slower,
--- but generates more independent variates that pass stringent tests
--- of randomness.
-standard :: PrimMonad m => Gen (PrimState m) -> m Double
-{-# INLINE standard #-}
-standard gen = loop
+-- We express standard in terms of normal and not other way round
+-- because of bug in GHC. See bug #16 for more details.
+normal m s gen = loop >>= (\x -> return $! m + s * x)
   where
     loop = do
       u  <- (subtract 1 . (*2)) `liftM` uniform gen
                 then tailing
                 else return $! if neg then x - r else r - x
 
+-- | Generate a normally distributed random variate with zero mean and
+-- unit variance.
+--
+-- The implementation uses Doornik's modified ziggurat algorithm.
+-- Compared to the ziggurat algorithm usually used, this is slower,
+-- but generates more independent variates that pass stringent tests
+-- of randomness.
+standard :: PrimMonad m => Gen (PrimState m) -> m Double
+{-# INLINE standard #-}
+standard = normal 0 1
+
 
 -- | Generate an exponentially distributed random variate.
 exponential :: PrimMonad m