# HG changeset patch # User Alexey Khudyakov # Date 1379252313 -14400 # Node ID 3f9179c41a887f6ecd3bb8547463ac2575d823fb # Parent 184eaad284908d0220b24ec0567759c712dd562c 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. diff --git a/System/Random/MWC/Distributions.hs b/System/Random/MWC/Distributions.hs --- a/System/Random/MWC/Distributions.hs +++ b/System/Random/MWC/Distributions.hs @@ -45,20 +45,9 @@ -> 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 @@ -97,6 +86,17 @@ 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