Here's a clean-up of that function:
Function PoissonInv(dProb As Double, dMean As Double) As Variant
' shg 2011, 2012-0519
' For a Poisson process with mean dMean, returns the largest
' integer N such that POISSON(N, dMean, True) <= dProb
' E.g., POISSON(5, 10, TRUE) returns 0.0670859629
' PoissonInv(0.0670859629, 10) returns 5
' Returns #NUM! if
' dProb < 0 or dProb >= 1
' Exp(-dMean) = 0 (i.e., dMean > 746)
' The factor dK blows up
' Returns -1 if dProb > POISSON(0, dMean, TRUE) = Exp(-Mean)
Dim N As Long ' number of events
Dim dCDF As Double ' cumulative distribution function at N
' These two variables are used to simplify this summation:
' dCDF = dCDF + Exp(-dMean) * dMean ^ N / N!
Dim dExpMean As Double ' =Exp(-dMean)
Dim dK As Double ' incremental power & factorial
If dProb <= 0# Or dProb >= 1# Then
PoissonInv = CVErr(xlErrNum)
Else
dExpMean = Exp(-dMean)
If dExpMean = 0# Then
' dMean is too large ...
PoissonInv = CVErr(xlErrNum)
ElseIf dExpMean > dProb Then
' dProb > POISSON(0, dMean, TRUE)
PoissonInv = -1&
Else
dK = 1#
On Error GoTo Oops
Do While dCDF <= dProb
dCDF = dCDF + dExpMean * dK
N = N + 1&
dK = dK * dMean / N
Loop
PoissonInv = N - 2&
End If
Exit Function
Oops:
' dK blew up ...
PoissonInv = CVErr(xlErrNum)
End If
End Function
Bookmarks