module Stochastic.Normal(mkNormal, Normal) where

import Data.Maybe
import Stochastic.Distribution
import Stochastic.Uniform
import Helpers

data Normal = Normal Double Double (Maybe Double) Uniform

mkNormal :: Uniform -> Double -> Double -> Normal
mkNormal uni mean dev = Normal mean dev Nothing uni

toDbl :: Int -> Double
toDbl = fromInteger . toInteger

instance ContinuousDistribution Normal where
  randDouble (Normal mean dev m uni) = f m
    where
      f (Just x) = (x, (Normal mean dev Nothing uni))
      f Nothing  = (y, (Normal mean dev (Just z) uni))
      ([u1, u2], uni') = randDoubles 2 uni
      from_u g = mean + dev * (sqrt (-2 * (log u1))) * ( g (2 * pi * u2) )
      y = from_u (sin)
      z = from_u (cos)