safe-coupling-0.1.0.0: test/Spec/Bins.hs
module Spec.Bins where
import Test.HUnit ( assertEqual
, (@?)
, (@?=)
, Assertion
)
import Data.Sort ( sort )
import Numeric.Probability.Distribution
hiding ( map )
import Spec.Utils
import Monad.PrM hiding ( fmap )
import Bins.Bins
p, q :: Double
p = 0.5
q = 0.625
coupling :: Double -> Double -> PrM (Bool, Bool)
coupling p q =
fromFreqs [((True, True), p), ((False, True), q - p), ((False, False), 1 - q)]
mockbins :: PrM (Bool, Bool) -> Int -> PrM (Int, Int)
mockbins _ 0 = return (0, 0)
mockbins c n = do
(xl, xr) <- c
(yl, yr) <- mockbins c (n - 1)
return (yl + toInt xl, yr + toInt xr)
where toInt x = if x then 1 else 0
binsIter1 = sort [ ((1, 1), p)
, ((0, 1), q - p)
, ((0, 0), 1 - q)
]
binsIter2 = sort [ ((2, 2), p ^ 2)
, ((1, 2), 2 * p * (q - p))
, ((1, 1), 2 * p * (1 - q))
, ((0, 2), (q - p) ^ 2)
, ((0, 1), 2 * (q - p) * (1 - q))
, ((0, 0), (1 - q) ^ 2)
]
unit_mockbins_1_it :: Assertion
unit_mockbins_1_it =
bins @?= binsIter1
where
bins = clean $ decons $ mockbins (coupling p q) 1
unit_mockbins_2_it :: Assertion
unit_mockbins_2_it =
bins @?= binsIter2
where
bins = clean $ decons $ mockbins (coupling p q) 2
unit_bins_1_it :: Assertion
unit_bins_1_it = do
resl @?= clean (map (\((a, _), p) -> (fromIntegral a, p)) binsIter1)
resr @?= clean (map (\((_, b), p) -> (fromIntegral b, p)) binsIter1)
where
resl = clean $ decons $ bins p 1
resr = clean $ decons $ bins q 1
unit_bins_2_it :: Assertion
unit_bins_2_it = do
resl @?= clean (map (\((a, _), p) -> (fromIntegral a, p)) binsIter2)
resr @?= clean (map (\((_, b), p) -> (fromIntegral b, p)) binsIter2)
where
resl = clean $ decons $ bins p 2
resr = clean $ decons $ bins q 2
unit_exp_dist_mockbins :: Assertion
unit_exp_dist_mockbins =
expDist == fromIntegral n * (q - p)
@? "want: E[dist (bins p n) (bins q n)] <= n * (q - p), got: " ++ show expDist
where
n = 10
bins = mockbins (coupling p q) n
dist = fmap (\(a, b) -> fromIntegral (b - a)) bins
expDist = expected dist