mersenne-random 0.1.3 → 1.0
raw patch · 2 files changed
+76/−1 lines, 2 files
Files
- System/Random/Mersenne.hs +71/−0
- mersenne-random.cabal +5/−1
System/Random/Mersenne.hs view
@@ -35,6 +35,11 @@ -- $notes , MTRandom(..) + -- $globalrng+ , getStdRandom+ , getStdGen+ , setStdGen+ -- * Miscellaneous , version @@ -58,6 +63,7 @@ import Data.Int import Data.Bits import Data.Char+import Data.IORef ------------------------------------------------------------------------ -- $example@@ -187,65 +193,90 @@ return (x : xs) -} + -- | A variant of 'random' that uses the global random number generator+ -- (see "System.Random#globalrng").+ -- Essentially a convenience function if you're already in IO.+ --+ -- Note that there are performance penalties calling randomIO in an+ -- inner loop, rather than 'random' applied to a global generator. The+ -- cost comes in retrieving the random gen from an IORef, which is+ -- non-trivial. Expect a 3x slow down in speed of random generation.+ randomIO :: IO a+ randomIO = getStdRandom random+ {-# INLINE randomIO #-}+ ------------------------------------------------------------------------ -- Efficient basic instances instance MTRandom Word where random !_ = randomWord+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalWord g (fromIntegral lo) (fromIntegral hi) instance MTRandom Word64 where random !_ = fmap fromIntegral randomWord64+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalWord g (fromIntegral lo) (fromIntegral hi) instance MTRandom Word32 where random !_ = fmap fromIntegral randomWord+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalWord g (fromIntegral lo) (fromIntegral hi) instance MTRandom Word16 where random !_ = fmap fromIntegral randomWord+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalWord g (fromIntegral lo) (fromIntegral hi) instance MTRandom Word8 where random !_ = fmap fromIntegral randomWord+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalWord g (fromIntegral lo) (fromIntegral hi) ------------------------------------------------------------------------ instance MTRandom Double where random !_ = randomDouble+ {-# INLINE random #-} -- randomR (lo,hi) g = randomIvalDouble g lo hi id ------------------------------------------------------------------------ instance MTRandom Int where random !_ = randomInt+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalInt g lo hi instance MTRandom Int64 where random !_ = fmap fromIntegral randomInt64+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalInt g (fromIntegral lo) (fromIntegral hi) instance MTRandom Int32 where random !_ = fmap fromIntegral randomInt+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalInt g (fromIntegral lo) (fromIntegral hi) instance MTRandom Int16 where random !_ = fmap fromIntegral randomInt+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalInt g (fromIntegral lo) (fromIntegral hi) instance MTRandom Int8 where random !_ = fmap fromIntegral randomInt+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalInt g (fromIntegral lo) (fromIntegral hi) instance MTRandom Integer where random !_ = fmap fromIntegral randomInt+ {-# INLINE random #-} -- randomR (lo,hi) !g = randomIvalInt g (fromIntegral lo) (fromIntegral hi) ------------------------------------------------------------------------ instance MTRandom Bool where random !_ = do x <- randomWord; return $! x .&. 1 /= 0+ {-# INLINE random #-} {- randomR (a,b) !g = int2Bool `fmap` randomIvalInt g (bool2Int a) (bool2Int b)@@ -327,6 +358,46 @@ intRange :: Integer intRange = toInteger (maxBound::Int) - toInteger (minBound::Int) -}+------------------------------------------------------------------------+--+-- Using a single global random number generator+--++{- $globalrng #globalrng#++There is a single, implicit, global random number generator of type+'StdGen', held in some global variable maintained by the 'IO' monad. It is+initialised automatically in some system-dependent fashion. To get+deterministic behaviour, use 'setStdGen'.+-}++theStdGen :: IORef MTGen+theStdGen = unsafePerformIO $ do+ rng <- newMTGen Nothing+ newIORef rng+{-# NOINLINE theStdGen #-}++-- |Sets the global random number generator.+setStdGen :: MTGen -> IO ()+setStdGen = writeIORef theStdGen++-- |Gets the global random number generator.+getStdGen :: IO MTGen+getStdGen = readIORef theStdGen++-- | Uses the supplied function to get a value from the current global+-- random generator, and updates the global generator with the new+-- generator returned by the function. For example, @rollDice@ gets a+-- random integer between 1 and 6:+--+-- > rollDice :: IO Int+-- > rollDice = getMTRandom (randomR (1,6))+--+getStdRandom :: (MTGen -> IO a) -> IO a+getStdRandom f = do+ st <- readIORef theStdGen+ f st+{-# INLINE getStdRandom #-} ------------------------------------------------------------------------
mersenne-random.cabal view
@@ -1,5 +1,5 @@ name: mersenne-random-version: 0.1.3+version: 1.0 homepage: http://code.haskell.org/~dons/code/mersenne-random synopsis: Generate high quality pseudorandom numbers using a SIMD Fast Mersenne Twister description:@@ -13,6 +13,10 @@ It is designed to be fast when it runs on 128-bit SIMD. It can be compiled with either SSE2 and PowerPC AltiVec support, to take advantage of these instructions.+ .+ > cabal install -fuse_sse2+ .+ On an x86 system, for performance win. . By default the period of the function is 2^19937-1, however, you can compile in other defaults. Note that this algorithm on its own