Unbias a random generator: Difference between revisions

→‎{{header|Haskell}}: Changed to universal monadic solution
m (→‎{{header|Perl 6}}: plain arrays as input to 'map')
(→‎{{header|Haskell}}: Changed to universal monadic solution)
Line 681:
 
=={{header|Haskell}}==
 
Crappy implementation using <code>IO</code>
<lang haskell>import Control.Monad.Random
import RandomControl.Monad
import Data.IORef
import Text.Printf
 
randN :: IntegerMonadRandom m => Int -> IOm BoolInt
randN n = randomRIOfromList [(10, fromIntegral n-1) >>= return ., (==1, 1)]
 
-- works for any random generator
unbiased :: Integer -> IO Bool
unbias :: (MonadRandom m, Eq x) => m x -> m x
unbiased n = do
unbias g a= do x <- randN ng
b y <- randN ng
if ax /= by then return ay else unbiasedunbias ng
 
main ::= IOforM_ ()[3..6] showCounts
where
main = forM_ [3..6] $ \n -> do
showCounts b = do
cb <- newIORef 0
cu r1 <- newIORefcounts (randN 0b)
r2 <- counts (unbias (randN b))
replicateM_ trials $ do
printf "n = %d biased: %d%% unbiased: %d%%\n" b r1 r2
b <- randN n
u <- unbiased n
counts g = (`div` 100) . length . filter (== 1) <$> replicateM 10000 g</lang>
when b $ modifyIORef cb (+ 1)
when u $ modifyIORef cu (+ 1)
tb <- readIORef cb
tu <- readIORef cu
printf "%d: %5.2f%% %5.2f%%\n" n
(100 * fromIntegral tb / fromIntegral trials :: Double)
(100 * fromIntegral tu / fromIntegral trials :: Double)
where trials = 50000</lang>
 
Output:
 
<pre>
n = 3 biased: 33.72% 50.08unbiased: 49%
n = 4 biased: 25.2624% unbiased: 50.15%
n = 5 biased: 19.99% unbiased: 50.07%
n = 6 biased: 16.67% 50.10unbiased: 49%
</pre>
 
Anonymous user