vector-random 0.1 → 0.2
raw patch · 3 files changed
+152/−15 lines, 3 filesdep +mersenne-random-pure64dep −mersenne-randomdep ~basedep ~vectorPVP ok
version bump matches the API change (PVP)
Dependencies added: mersenne-random-pure64
Dependencies removed: mersenne-random
Dependency ranges changed: base, vector
API changes (from Hackage documentation)
+ Data.Vector.Random.Mersenne: class PureMTRandom a
+ Data.Vector.Random.Mersenne: instance PureMTRandom Bool
+ Data.Vector.Random.Mersenne: instance PureMTRandom Double
+ Data.Vector.Random.Mersenne: instance PureMTRandom Float
+ Data.Vector.Random.Mersenne: instance PureMTRandom Int
+ Data.Vector.Random.Mersenne: instance PureMTRandom Int16
+ Data.Vector.Random.Mersenne: instance PureMTRandom Int32
+ Data.Vector.Random.Mersenne: instance PureMTRandom Int64
+ Data.Vector.Random.Mersenne: instance PureMTRandom Int8
+ Data.Vector.Random.Mersenne: instance PureMTRandom Integer
+ Data.Vector.Random.Mersenne: instance PureMTRandom Word
+ Data.Vector.Random.Mersenne: instance PureMTRandom Word16
+ Data.Vector.Random.Mersenne: instance PureMTRandom Word32
+ Data.Vector.Random.Mersenne: instance PureMTRandom Word64
+ Data.Vector.Random.Mersenne: instance PureMTRandom Word8
+ Data.Vector.Random.Mersenne: randoms :: (PureMTRandom a, Vector v a) => PureMT -> Int -> v a
- Data.Vector.Random.Mersenne: random :: (MTRandom a, Vector v a) => MTGen -> Int -> IO (v a)
+ Data.Vector.Random.Mersenne: random :: PureMTRandom a => PureMT -> (a, PureMT)
Files
- Data/Vector/Random/Mersenne.hs +140/−8
- tests/test.hs +6/−5
- vector-random.cabal +6/−2
Data/Vector/Random/Mersenne.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE BangPatterns #-} -------------------------------------------------------------------- -- | -- Module : Data.Vector.Random.Mersenne@@ -12,30 +13,138 @@ -- Generator for vectors of differen types -- -module Data.Vector.Random.Mersenne (random) where+module Data.Vector.Random.Mersenne ( -import qualified System.Random.Mersenne as R+ -- * Fill a vector with randoms.+ randoms, + -- * Class of MT random types+ PureMTRandom(..)++ ) where++-- import qualified System.Random.Mersenne as R+import qualified System.Random.Mersenne.Pure64 as R++ import qualified Data.Vector.Generic as G import qualified Data.Vector.Generic.Mutable as GM -import Control.Monad.ST+import qualified Data.Vector.Fusion.Stream as Stream+import qualified Data.Vector.Fusion.Stream.Monadic as S+import qualified Data.Vector.Fusion.Stream.Size as S+import Data.Vector.Fusion.Util +-- import System.IO.Unsafe+-- import GHC.IOBase+import Data.Bits+import Data.Int+import Data.Word+ -- | Return a random vector of length @n@, filled with random elements -- of type @a@ generated by the mersenne-twister. -- -- E.g. to compute the sum of 100 million random Double values in a vector: ----- > import qualified Data.Vector.Unboxed as U--- > import System.Random.Mersenne+-- > import qualified Data.VectorUnboxed as U+-- > import System.Random.Mersenne.Pure64 -- > import qualified Data.Vector.Random.Mersenne as G -- > -- > main = do--- > g <- newMTGen Nothing--- > a <- G.random g 10000000 :: IO (U.Vector Double) -- 100 M+-- > g <- newPureMT+-- > let a = G.random g 10000000 :: U.Vector Double -- > print (U.sum a) ---random :: (R.MTRandom a, G.Vector v a) => R.MTGen -> Int -> IO (v a)+-- The generator will fuse under stream fusion, so e.g. sum . random g+-- will allocate no intermediate array.+--++randoms :: (PureMTRandom a, G.Vector v a) => R.PureMT -> Int -> v a+randoms g n = G.unstream (randomS g n)+{-# INLINE randoms #-}++-- A stream of 'n' random numbers.+--+randomS :: PureMTRandom a => R.PureMT -> Int -> Stream.Stream a+{-# INLINE [1] randomS #-}+randomS g n = S.Stream (return . step) (n, g) (S.Exact (delay_inline max n 0))+ where+ {-# INLINE [0] step #-}+ step (i,g) | i <= 0 = S.Done+ | otherwise = g `seq` case random g of+ (r, g') -> S.Yield r (i-1, g')++------------------------------------------------------------------------++-- | Class of types that we have efficient generators for.+class PureMTRandom a where++ -- | Given a pure mersenne twister state, yield a new random value,+ -- and the next state.+ random :: R.PureMT -> (a, R.PureMT)+ {-# INLINE random #-}++instance PureMTRandom Double where+ random = R.randomDouble+ {-# INLINE random #-}++-- XXX this doesn't inline properly under ghc 6.12+instance PureMTRandom Float where+ random !g = case R.randomDouble g of+ (i, g') -> (realToFrac i, g')+ {-# INLINE random #-}++instance PureMTRandom Word where+ random = R.randomWord+ {-# INLINE random #-}++instance PureMTRandom Word8 where+ random g = case R.randomWord g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++instance PureMTRandom Word16 where+ random g = case R.randomWord g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++instance PureMTRandom Word32 where+ random g = case R.randomWord g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++instance PureMTRandom Word64 where+ random = R.randomWord64+ {-# INLINE random #-}++instance PureMTRandom Int where+ random = R.randomInt+ {-# INLINE random #-}++instance PureMTRandom Int8 where+ random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++instance PureMTRandom Int16 where+ random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++instance PureMTRandom Int32 where+ random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++instance PureMTRandom Int64 where+ random = R.randomInt64+ {-# INLINE random #-}++instance PureMTRandom Bool where+ random g = case R.randomWord g of (i, g') -> (i .&. i /= 0, g')+ {-# INLINE random #-}++instance PureMTRandom Integer where+ random g = case R.randomInt g of (i, g') -> (fromIntegral i, g')+ {-# INLINE random #-}++------------------------------------------------------------------------++{- random g n = do v <- GM.new n fill v 0@@ -47,3 +156,26 @@ GM.unsafeWrite v i x fill v (i+1) | otherwise = return ()+-}++------------------------------------------------------------------------++{-+-- A stream of random 'n' random numbers.+--+randomS :: (R.MTRandom a) => R.PureMT -> Int -> Stream.Stream a+{-# INLINE [1] randomS #-}+randomS g n = S.Stream (return . step) n (S.Exact (delay_inline max n 0))+ where+ {-# INLINE [0] step #-}+ step i | i <= 0 = S.Done+ | otherwise =+ case unsafeDupablePerformIO (R.random' i g) of+ r -> S.Yield r (i-1)+++random' :: R.MTRandom a => Int -> R.PureMT -> IO a+{-# NOINLINE random' #-}+random' _ gen = R.random gen++-}
tests/test.hs view
@@ -1,10 +1,11 @@ import qualified Data.Vector.Unboxed as U-import System.Random.Mersenne+import System.Random.Mersenne.Pure64 import qualified Data.Vector.Random.Mersenne as G+import Data.Int main = do- g <- newMTGen Nothing- a <- G.random g 10000000 :: IO (U.Vector Double) -- 100 M- print (U.sum a)-+ g <- newPureMT+-- let a = U.map realToFrac (G.randoms g 10000000 :: U.Vector Double) :: U.Vector Float -- 100 M+ let a = G.randoms g 10000000 -- :: U.Vector Int8 -- 100 M+ print (U.and a)
vector-random.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version: 0.1+Version: 0.2 -- A short (one-line) description of the package. Synopsis: Generate vectors filled with high quality pseudorandom numbers@@ -57,6 +57,10 @@ -- Packages needed in order to build this package. Build-depends: base <= 5,- mersenne-random,+ mersenne-random-pure64, vector >= 0.5++ if impl(ghc<6.13)+ Ghc-Options: -finline-if-enough-args -fno-method-sharing + GHC-options: -O2