Permalink
Browse files

Add table generation forn binomial distribution

  • Loading branch information...
1 parent e62ae0d commit c47610bd3b22804588bfa84720c2bb4391ac7404 @Shimuuar Shimuuar committed Feb 9, 2012
Showing with 70 additions and 4 deletions.
  1. +19 −0 System/Random/MWC/CondensedTable.hs
  2. +6 −0 benchmarks/Benchmark.hs
  3. +20 −1 test/ChiSquare.hs
  4. +18 −1 test/visual.R
  5. +7 −2 test/visual.hs
@@ -17,6 +17,7 @@ module System.Random.MWC.CondensedTable (
, tableFromIntWeights
-- ** Disrete distributions
, tablePoisson
+ , tableBinomial
) where
import Control.Arrow (second,(***))
@@ -226,6 +227,24 @@ tablePoisson = tableFromProbabilities . make
)
minP = 1.1641532182693481e-10 -- 2**(-33)
+-- | Create lookup table for binomial distribution
+tableBinomial :: Int -- ^ Number of tries
+ -> Double -- ^ Probability of success
+ -> CondensedTableU Int
+tableBinomial n p = tableFromProbabilities makeBinom
+ where
+ makeBinom
+ | n <= 0 = error "System.Random.MWC.CondesedTable.tableBinomial: nonpositive number of tryes"
+ | p == 0 = U.singleton (0,1)
+ | p == 1 = U.singleton (n,1)
+ | p > 0 && p < 1 = U.unfoldrN (n + 1) unfolder ((1-p)^n, 0)
+ | otherwise = error "System.Random.MWC.CondesedTable.tableBinomial: probability is out of range"
+ where
+ h = p / (1 - p)
+ unfolder (t,i) = Just ( (i,t)
+ , (t * (fromIntegral $ n + 1 - i1) * h / fromIntegral i1, i1) )
+ where i1 = i + 1
+
-- $references
--
View
@@ -69,6 +69,9 @@ main = do
, [ bench ("poisson " ++ show l) (genFromTable (tablePoisson l) mwc :: IO Int)
| l <- [0.01, 0.2, 0.8, 1.3, 2.4, 8, 12, 100, 1000]
]
+ , [ bench ("binomial " ++ show p ++ " " ++ show n) (genFromTable (tableBinomial n p) mwc :: IO Int)
+ | (n,p) <- [ (4, 0.5), (10,0.1), (10,0.6), (10, 0.8), (100,0.4)]
+ ]
]
, bgroup "CT/table" $ concat
[ [ bench ("uniform " ++ show i) $ whnf makeTableUniform i
@@ -77,6 +80,9 @@ main = do
, [ bench ("poisson " ++ show l) $ whnf tablePoisson l
| l <- [0.01, 0.2, 0.8, 1.3, 2.4, 8, 12, 100, 1000]
]
+ , [ bench ("binomial " ++ show p ++ " " ++ show n) $ whnf (tableBinomial n) p
+ | (n,p) <- [ (4, 0.5), (10,0.1), (10,0.6), (10, 0.8), (100,0.4)]
+ ]
]
]
, bgroup "random"
View
@@ -18,6 +18,7 @@ import qualified System.Random.MWC.CondensedTable as MWC
import Statistics.Test.ChiSquared
import Statistics.Distribution
import Statistics.Distribution.Poisson
+import Statistics.Distribution.Binomial
import Test.HUnit hiding (Test)
import Test.Framework
@@ -48,6 +49,12 @@ tests g = testGroup "Chi squared tests"
, poissonTest 1.32 g
, poissonTest 6.8 g
, poissonTest 100 g
+ -- ** Binomial
+ , binomialTest 4 0.5 g
+ , binomialTest 10 0.1 g
+ , binomialTest 10 0.6 g
+ , binomialTest 10 0.8 g
+ , binomialTest 100 0.3 g
]
----------------------------------------------------------------
@@ -117,4 +124,16 @@ poissonTest lam g =
, probabilites = U.generate nMax (probability pois)
}
r <- sampleTest gen (10^4) g
- assertEqual "Significant!" NotSignificant r
+ assertEqual "Significant!" NotSignificant r
+
+binomialTest :: Int -> Double -> MWC.GenIO -> Test
+binomialTest n p g =
+ testCase ("binomialTest: " ++ show p ++ " " ++ show n) $ do
+ let binom = binomial n p
+ gen = Generator
+ { generator = MWC.genFromTable (MWC.tableBinomial n p)
+ , probabilites = U.generate (n+1) (probability binom)
+ }
+ r <- sampleTest gen (10^4) g
+ assertEqual "Significant!" NotSignificant r
+
View
@@ -15,7 +15,10 @@ view.dumps <- function() {
# plots for discrete distribution
plot.ds <- function( name, xs, prob) {
smp <- load.d( name )
- h <- hist( smp, breaks = xs - 0.5, freq=FALSE )
+ h <- hist( smp,
+ breaks = c( max(xs) + 0.5, xs - 0.5),
+ freq=FALSE, main = name
+ )
dh <- sqrt( h$count ) / max( 1, sum( h$count ) )
arrows( xs, h$density + dh,
xs, h$density - dh,
@@ -85,4 +88,18 @@ view.dumps <- function() {
plot.ds( "distr/poisson-30", 0:100, function(x) dpois(x, lambda=30) )
readline()
#
+ ################################################################
+ # Binomial
+ plot.ds( "distr/binom-4-0.5", 0:4, function(x) dbinom(x, 4, 0.5) )
+ readline()
+ #
+ plot.ds( "distr/binom-10-0.1", 0:10, function(x) dbinom(x, 10, 0.1) )
+ readline()
+ #
+ plot.ds( "distr/binom-10-0.6", 0:10, function(x) dbinom(x, 10, 0.6) )
+ readline()
+ #
+ plot.ds( "distr/binom-10-0.8", 0:10, function(x) dbinom(x, 10, 0.8) )
+ readline()
+ #
}
View
@@ -13,10 +13,10 @@ dumpSample :: Show a => Int -> FilePath -> IO a -> IO ()
dumpSample n fname gen =
withFile fname WriteMode $ \h ->
replicateM_ n (hPutStrLn h . show =<< gen)
-
+
main :: IO ()
main = MWC.withSystemRandom $ \g -> do
- let n = 10000
+ let n = 30000
dir = "distr"
createDirectoryIfMissing True dir
setCurrentDirectory dir
@@ -37,3 +37,8 @@ main = MWC.withSystemRandom $ \g -> do
dumpSample n "poisson-1.0" $ MWC.genFromTable (MWC.tablePoisson 1.0) g
dumpSample n "poisson-4.5" $ MWC.genFromTable (MWC.tablePoisson 4.5) g
dumpSample n "poisson-30" $ MWC.genFromTable (MWC.tablePoisson 30) g
+ -- Binomial
+ dumpSample n "binom-4-0.5" $ MWC.genFromTable (MWC.tableBinomial 4 0.5) g
+ dumpSample n "binom-10-0.1" $ MWC.genFromTable (MWC.tableBinomial 10 0.1) g
+ dumpSample n "binom-10-0.6" $ MWC.genFromTable (MWC.tableBinomial 10 0.6) g
+ dumpSample n "binom-10-0.8" $ MWC.genFromTable (MWC.tableBinomial 10 0.8) g

0 comments on commit c47610b

Please sign in to comment.