packages feed

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 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