Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate n random numbers from a normal distribution using random-fu (Haskell)?

The question seems straightforward to me, yet I couldn't find easily an answer.

Lets say that you want to take a sample of size n from a normal distribution with mean 10 and variance 1 and then get their average and variance to verify that the sample is from a normal distribution.

It would be something like this, I suppose:

values = take n $ sample (normal 10 1)
(avg values, variance values)

I'm trying to use the library random-fu, so if you can provide an answer using that lib, I would really appreciate it.

like image 251
Lay González Avatar asked Feb 05 '23 05:02

Lay González


1 Answers

There is the awkwardness here that is always present with randomness in Haskell - since Haskell is pure, you'll need to have some sort of "random" source. random-fu uses RandomSource for this purpose, then you work inside this monad when you want to manipulate random values.

import Data.Random
import Control.Monad (replicateM)

average :: [Double] -> Double
average xs = sum xs / fromIntegral (length xs)

variance :: [Double] -> Double
variance xs = average [ (x - m)^2  | x <- xs ] 
  where m = average xs

main :: IO ()
main = do
  sample <- runRVar (replicateM 10 (normal 10 1)) StdRandom :: IO [Double]
  putStrLn $ "Average: " ++ show (average sample)
  putStrLn $ "Variance: " ++ show (variance sample)

Trial runs seem to be giving me reasonable output:

ghci> main
Average: 10.294887142436771
Variance: 0.7129578122237161
ghci> main
Average: 9.677325092160597
Variance: 0.9894150286175698
ghci> main
Average: 9.714089727813253
Variance: 1.0279068711054316
ghci> main
Average: 10.32028785267642
Variance: 0.8574243439019995
ghci> main
Average: 9.696843993234065
Variance: 0.45301180269725994
like image 148
Alec Avatar answered Feb 16 '23 04:02

Alec