Skip to content

Instantly share code, notes, and snippets.

@muhuk
Created June 24, 2016 19:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muhuk/3e7ec40c8e00d7c3f5d08df54f567feb to your computer and use it in GitHub Desktop.
Save muhuk/3e7ec40c8e00d7c3f5d08df54f567feb to your computer and use it in GitHub Desktop.
#!/usr/bin/env stack
-- stack runghc --package random
import Control.Monad (replicateM)
import System.Random (randomRIO)
main :: IO ()
main = do
let n = 1000000
samples <- genSamples n
let a = fastMethod samples
let b = preciseMethod samples
putStrLn $ show a
putStrLn $ show b
putStrLn $ show $ abs $ a - b
genSamples :: Int -> IO [Float]
genSamples n = replicateM n $ randomRIO (0.0, 1.0)
-- Fast method is not necessarily faster to run. It's called fast
-- because we have access to average at all times. During sampling
-- we would need to decide if the new average is sufficiently
-- different thant the old average. This is omitted here.
fastMethod :: [Float] -> Float
fastMethod (x:xs) = f x 1 xs where
f ave n [] = ave
f ave n (x:xs) = f (((ave * n) + x) / (succ n)) (succ n) xs
preciseMethod :: [Float] -> Float
preciseMethod (x:xs) = f x 1 xs where
f sum n [] = sum / n
f sum n (x:xs) = f (sum + x) (succ n) xs
-- Typically difference is 1e-6 ~ 1e-7 for Float and 1e-14 ~ 1e-15 for Double.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment