on develop help sign in
Preserve timing intervals. Document.
commit93cd04576b02782836bb9bfdab22c512cbd81429 authorGreg Hale <imalsogreg@gmail.com> dateSat 16 May 2015, 20:08 (11 years ago) parentbea6bed
1 file changed+31−10
src/Reflex/Dom/Time.hs+31−10
src/Reflex/Dom/Time.hs+31−10
@@ -21,7 +21,7 @@ data TickInfo
2121 , _tickInfo_alreadyElapsed :: NominalDiffTime
2222 -- ^ Amount of time already elapsed in the current tick period.
2323 }
24− deriving (Eq)
24+ deriving (Eq, Show)
2525
2626-- | Special case of tickLossyFrom that uses the post-build event to start the
2727-- tick thread.
@@ -98,29 +98,50 @@ inhomogeneousPoissonFrom
9898 -> Event t a
9999 -> m (Event t TickInfo)
100100inhomogeneousPoissonFrom rnd rate maxRate t0 e = do
101+
102+ -- Create a thread for producing homogeneous poisson events
103+ -- along with random Doubles (usage of Double's explained below)
101104 ticksWithRateRand <- performEventAsync $
102105 fmap callAtNextInterval e
106+
107+ -- Filter homogeneous events according to associated
108+ -- random values and the current rate parameter
103109 return $ attachWithMaybe filterFun rate ticksWithRateRand
104110
105111 where
106112
113+ -- Inhomogeneous poisson processes are built from faster
114+ -- homogeneous ones by randomly dropping events from the
115+ -- fast process. For each fast homogeneous event, choose
116+ -- a uniform random sample from (0, rMax). If the
117+ -- inhomogeneous rate at this moment is greater than the
118+ -- random sample, then keep this event, otherwise drop it
107119 filterFun :: Double -> (TickInfo, Double) -> Maybe TickInfo
108120 filterFun r (tInfo, p)
109121 | r >= p = Just tInfo
110122 | otherwise = Nothing
111123
112− callAtNextInterval _ cb = void $ liftIO $ forkIO $ go rnd cb
124+ callAtNextInterval _ cb = void $ liftIO $ forkIO $ go t0 rnd cb 0
113125
114− go lastGen cb = do
126+ go tTargetLast lastGen cb lastN = do
115127 t <- getCurrentTime
116− let (u, nextGen) = randomR (0,1) lastGen
128+
129+ -- Generate random numbers for this poisson interval (u)
130+ -- and sample-retention likelihood (p)
131+ let (u, nextGen) = randomR (0,1) lastGen
117132 (p :: Double, nextGen') = randomR (0,maxRate) nextGen
118− dt = realToFrac $ -1 * log(u)/maxRate :: NominalDiffTime
119− offset = t `diffUTCTime` t0
120− (n, alreadyElapsed) = offset `divMod'` dt
121− threadDelay $ ceiling $ (dt - alreadyElapsed) * 1000000
122− void $ cb $ (TickInfo t n alreadyElapsed, p)
123− go nextGen' cb
133+
134+ -- Inter-event interval is drawn from exponential
135+ -- distribution accourding to u
136+ let dt = realToFrac $ -1 * log(u)/maxRate :: NominalDiffTime
137+ offset = t `diffUTCTime` t0
138+ nEvents = lastN + 1
139+ alreadyElapsed = diffUTCTime t tTargetLast
140+ tTarget = addUTCTime dt tTargetLast
141+ thisDelay = realToFrac $ diffUTCTime tTarget t :: Double
142+ threadDelay $ ceiling $ thisDelay * 1000000
143+ void $ cb $ (TickInfo t nEvents alreadyElapsed, p)
144+ go tTarget nextGen' cb nEvents
124145
125146-- | Send events with inhomogeneous Poisson timing with the given basis
126147-- and variable rate. Provide a maxRate that you expect to support