Skip to content

Instantly share code, notes, and snippets.

@eulerfx
Last active May 10, 2018 14:37
Show Gist options
  • Select an option

  • Save eulerfx/e6c9d76f65026d3279432fc89c06c7cb to your computer and use it in GitHub Desktop.

Select an option

Save eulerfx/e6c9d76f65026d3279432fc89c06c7cb to your computer and use it in GitHub Desktop.

Revisions

  1. eulerfx revised this gist May 10, 2018. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion poisson.fs
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,6 @@ let ofDelays (delays:TimeSpan seq) : IObservable<DateTimeOffset> =
    setNext ()
    disposable dispose }


    /// Returns a sequence of time spans which fillow an exponential distribution based on the
    /// specified rate parameter.
    let expInterArrivalSequence (ratePerSec:float) : TimeSpan seq = seq {
  2. eulerfx revised this gist May 10, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion poisson.fs
    Original file line number Diff line number Diff line change
    @@ -24,13 +24,13 @@ let ofDelays (delays:TimeSpan seq) : IObservable<DateTimeOffset> =
    obs.OnError ex
    dispose ()
    let tick (_:obj) =
    printfn "tick"
    obs.OnNext DateTimeOffset.UtcNow
    setNext ()
    timer <- new Timer(TimerCallback(tick))
    setNext ()
    disposable dispose }


    /// Returns a sequence of time spans which fillow an exponential distribution based on the
    /// specified rate parameter.
    let expInterArrivalSequence (ratePerSec:float) : TimeSpan seq = seq {
  3. eulerfx created this gist May 10, 2018.
    47 changes: 47 additions & 0 deletions poisson.fs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    open System
    open System.Threading

    let private disposable (dispose:unit -> unit) =
    { new IDisposable with member __.Dispose () = dispose () }

    /// Creates an observable which triggers based on intervals specified by the input sequence.
    let ofDelays (delays:TimeSpan seq) : IObservable<DateTimeOffset> =
    { new IObservable<_> with
    member __.Subscribe obs =
    let en = delays.GetEnumerator ()
    let mutable timer : Timer = Unchecked.defaultof<_>
    let dispose () =
    if not (isNull timer) then timer.Dispose ()
    en.Dispose ()
    let setNext () =
    try
    if en.MoveNext () then
    timer.Change (int en.Current.TotalMilliseconds, Timeout.Infinite) |> ignore
    else
    obs.OnCompleted ()
    dispose ()
    with ex ->
    obs.OnError ex
    dispose ()
    let tick (_:obj) =
    printfn "tick"
    obs.OnNext DateTimeOffset.UtcNow
    setNext ()
    timer <- new Timer(TimerCallback(tick))
    setNext ()
    disposable dispose }

    /// Returns a sequence of time spans which fillow an exponential distribution based on the
    /// specified rate parameter.
    let expInterArrivalSequence (ratePerSec:float) : TimeSpan seq = seq {
    let rng = Random()
    let delay () = -log (1.0 - rng.NextDouble ()) / ratePerSec
    while true do
    yield delay () |> TimeSpan.FromSeconds }

    /// Creates an event which triggers based on exponentially distributed intervals
    /// thereby simulating a poisson process.
    let poissonEvent (ratePerSec:float) : IObservable<DateTimeOffset> =
    ratePerSec
    |> expInterArrivalSequence
    |> ofDelays