eopen System.Numericeopen System.Numerics
| _ -> [1I..BigInteger(n)] |> Seq.reduce ( * )
let CumulativeDistribution (x : int) (n : int) (p : float) =
let EssentiallyZero = 10E-12
let m = (float(n) * p) |> truncate |> int
let CalcCurrent value k =
value * float(n - k + 1) * p / (float(k) * (1. - p))
value * float(k + 1) * (1. - p) / (float(n - k) * p)
let Done k = if k > m then k > n else k < 0
let NextK k = if k > m then k + 1 else k - 1
let rec Calculate k totalUnscaledProbability previous unscaled =
let current = CalcCurrent previous k
let totalUnscaledProbability' = totalUnscaledProbability + current
if (Done k) && (current <= EssentiallyZero) then
unscaled', totalUnscaledProbability'
Calculate (NextK k) totalUnscaledProbability' current unscaled'
let InitialUnscaled = if (m <= x) then 1. else 0.
let UnscaledResultAboveM, TotalUnscaledProbabilityAboveM = Calculate (m+1) 1. 1. InitialUnscaled
let UnscaledResult, TotalUnscaledProbability = Calculate (m-1) TotalUnscaledProbabilityAboveM 1. UnscaledResultAboveM
UnscaledResult / TotalUnscaledProbability
printfn "Binomial %f" (CumulativeDistribution 10 13 0.5)