haskell / statistics

A fast, high quality library for computing with statistics in Haskell.
http://hackage.haskell.org/package/statistics
BSD 2-Clause "Simplified" License
300 stars 67 forks source link

Easier random number generation #87

Open schiegl opened 8 years ago

schiegl commented 8 years ago

I am not sure if this is the case for everyone (as I am fairly new to Haskell) but I'd appreciate it if generating random numbers would be easier. In R it is as easy as runif(n). But with this library I have to find out what PrimMonads are and (I assume) creating my own random number generator.

What do you think about a function that gives you a vector of random numbers (based on a distribution you specify) in the IO Monad? Something like randomSample 10 myDistribution.

This is what I could come up with (it uses mersenne-random-pure64 for the generators)

-- | Generate a vector of random numbers based on a distribution
randomSample :: (Distribution d) => Int -> d -> IO (U.Vector Double)
randomSample n distribution = map (`quantile` distribution) <$> randomUniform n

-- | Generate a vector of uniformly randomly distributed numbers
randomUniform :: Int -> IO (U.Vector Double)
randomUniform n = U.unfoldrN n (Just . randomDouble) <$> newPureMT
jsermeno commented 8 years ago

Not one function, but you can do something like this.

ghci> import Control.Monad
ghci> import System.Random.MWC (create)
ghci> import Statistics.Distribution (genContVar)
ghci> import Statistics.Distribution.Normal (standard)
ghci> g <- create
ghci> replicateM 10 $ genContVar standard g
Shimuuar commented 8 years ago

AFAIU R uses PRNG with global state. It's not a problem since R is single threaded. But in haskell you'll have to guard PRNG state with lock which will lead to poor performance. So one have to initialize PRGN explicitly.

On the other hand API of mwc-random isn't very pleasant to use and could be improved. Question is how to do it.

P.S. PrimMonad is price for ability to work in both IO and ST monads.