I am implementing an approximate counting algorithm where we:
Maintains a counter đť‘‹ using log log đť‘› bits
• Initialize đť‘‹ to 0
• When an item arrives, increase X by 1 with probability (1/2)^đť‘‹
• When the stream is over, output 2^(X) - 1 so that 𝔼[2^đť‘‹] = đť‘› + 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 p s = (q <= 100*p, s')
where (q,s') = randomR (1,100) s
toses :: Prob -> Tosses -> StdGen -> [(Bool,StdGen)]
toses _ 0 _ = []
toses p n s = let t@(b,s') = tos p s in t : toses p (pred n) s'
toses' :: Prob -> Tosses -> StdGen -> [Bool]
toses' p n = fmap fst . toses p n
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) s
n' = 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, and it seems like for all StdGen and |stream| > 1000, $X = 7$.
I tested the same algorithm in Matlab and it works there, so I assume it's an issue with my random number generator, what gives?
Aucun commentaire:
Enregistrer un commentaire