using System;
namespace Legalsoft.Truffer
{
public class Poissondist : Gamma
{
private double lam { get; set; }
public Poissondist(double llam)
{
this.lam = llam;
if (lam <= 0.0)
{
throw new Exception("bad lam in Poissondist");
}
}
public double p(int n)
{
if (n < 0)
{
throw new Exception("bad n in Poissondist");
}
return Math.Exp(-lam + n * Math.Log(lam) - Globals.gammln(n + 1.0));
}
public double cdf(int n)
{
if (n < 0)
{
throw new Exception("bad n in Poissondist");
}
if (n == 0)
{
return 0.0;
}
return gammq((double)n, lam);
}
public int invcdf(double p)
{
int inc = 1;
if (p <= 0.0 || p >= 1.0)
{
throw new Exception("bad p in Poissondist");
}
if (p < Math.Exp(-lam))
{
return 0;
}
int n = (int)Math.Max(Math.Sqrt(lam), 5.0);
int nl;
int nu;
if (p < cdf(n))
{
do
{
n = Math.Max(n - inc, 0);
inc *= 2;
} while (p < cdf(n));
nl = n;
nu = n + inc / 2;
}
else
{
do
{
n += inc;
inc *= 2;
} while (p > cdf(n));
nu = n;
nl = n - inc / 2;
}
while (nu - nl > 1)
{
n = (nl + nu) / 2;
if (p < cdf(n))
{
nu = n;
}
else
{
nl = n;
}
}
return nl;
}
}
}