I use an approximate calculation algorithm, where we:
Maintain X counter using the log (log n) bit
Initialize X to 0
When an item arrives, increase X by 1 with the probability of (& frac12;) X
When the stream is finished, print 2 X & minus; 1, so that E [2 X ] = n + 1
My implementation is as follows:
import System.Random type Prob = Double type Tosses = Int -- * for sake of simplicity we assume 0 <= p <= 1 tos :: Prob -> StdGen -> (Bool,StdGen) tos ps = (q <= 100*p, s') where (q,s') = randomR (1,100) s toses :: Prob -> Tosses -> StdGen -> [(Bool,StdGen)] toses _ 0 _ = [] toses pns = let t@ (b,s') = tos ps in t : toses p (pred n) s' toses' :: Prob -> Tosses -> StdGen -> [Bool] toses' pn = fmap fst . toses pn morris :: StdGen -> [a] -> Int morris s xs = go s xs 0 where go _ [] n = n go s (_:xs) n = go s' xs n' where (h,s') = tos (0.5^n) sn' = if h then succ n else n main :: IO Int main = do s <- newStdGen return $ morris s [1..10000]
The problem is that my X is always incorrect for any |stream| > 2 |stream| > 2 , and it seems that for all StdGen and |stream| > 1000 |stream| > 1000 , X = 7
I tested the same algorithm in Matlab and it works there, so I assume that it
Please suggest a way forward?
source share