@@ -1,3 +1,6 @@
1+{-# LANGUAGe ScopedTypeVariables #-}
2+{-# LANGUAGE TypeFamilies #-}
1module Reflex.Dom.Time where
4module Reflex.Dom.Time where
3import Reflex
6import Reflex
@@ -78,6 +81,7 @@ poissonLossyFrom rnd rate t0 e = performEventAsync $ fmap callAtNextInterval e
78 void $ cb $ TickInfo t n alreadyElapsed
81 void $ cb $ TickInfo t n alreadyElapsed
79 go nextGen cb
82 go nextGen cb
81-- | Send events with Poisson timing with the given basis and rate
85-- | Send events with Poisson timing with the given basis and rate
82-- Each occurence of the resulting event will contain the index of
86-- Each occurence of the resulting event will contain the index of
83-- the current interval, with 0 representing the basis time.
87-- the current interval, with 0 representing the basis time.
@@ -91,3 +95,50 @@ poissonLossy
91 -- ^ Baseline time for events
95 -- ^ Baseline time for events
92 -> m (Event t TickInfo)
96 -> m (Event t TickInfo)
93poissonLossy rnd rate t0 = poissonLossyFrom rnd rate t0 =<< getPostBuild
97poissonLossy rnd rate t0 = poissonLossyFrom rnd rate t0 =<< getPostBuild
99+-- | Send events with inhomogeneous Poisson timing with the given basis
100+-- and variable rate. Provide a maxRate that you expect to support.
101+inhomogeneousPoissonFrom
102+ :: (RandomGen g, MonadWidget t m)
104+ -> Behavior t Double
108+ -> m (Event t TickInfo)
109+inhomogeneousPoissonFrom rnd rate maxRate t0 e = do
110+ ticksWithRateRand <- performEventAsync $
111+ fmap callAtNextInterval e
112+ return $ attachWithMaybe filterFun rate ticksWithRateRand
116+ filterFun :: Double -> (TickInfo, Double) -> Maybe TickInfo
117+ filterFun r (tInfo, p)
118+ | r >= p = Just tInfo
119+ | otherwise = Nothing
121+ callAtNextInterval _ cb = void $ liftIO $ forkIO $ go rnd cb
125+ let (u, nextGen) = randomR (0,1) lastGen
126+ (p :: Double, nextGen') = randomR (0,maxRate) nextGen
127+ dt = realToFrac $ -1 * log(u)/maxRate :: NominalDiffTime
128+ offset = t `diffUTCTime` t0
129+ (n, alreadyElapsed) = offset `divMod'` dt
130+ threadDelay $ ceiling $ (dt - alreadyElapsed) * 1000000
131+ void $ cb $ (TickInfo t n alreadyElapsed, p)
134+-- | Send events with inhomogeneous Poisson timing with the given basis
135+-- and variable rate. Provide a maxRate that you expect to support
137+ :: (RandomGen g, MonadWidget t m)
139+ -> Behavior t Double
142+ -> m (Event t TickInfo)
143+inhomogeneousPoisson rnd rate maxRate t0 =
144+ inhomogeneousPoissonFrom rnd rate maxRate t0 =<< getPostBuild