/// <inheritdoc /> public override double ProbabilityDensity(double x) { if (x < 0.0) { return(0.0); } else { double z = x / s; // use Gamma(a) or Ln(Gamma(a)) form depending on size of a if (ga > 0.0) { return(Math.Pow(z, a - 1.0) * Math.Exp(-z) / ga / s); } else { // The standard Gamma distribution p(\alpha, x) is the same as the // Poisson distribution P(\lambda, k) with k \leftarrow \alpha - 1 // and \lambda \leftarrow x. Use this fact plus our Poisson // machinery to accurately compute probabilities for large \alpha. return(Stirling.PoissonProbability(z, a - 1.0) / s); //return (Math.Exp((a - 1.0) * Math.Log(z) - z + ga) / s); } } }
/// <inheritdoc /> public override double ProbabilityMass(int k) { if (k < 0) { return(0.0); } else { // These are the same expression, but the form for small arguments is faster, // while the form for large arguments avoids overflow and cancellation errors. if (k < 16) { return(Math.Exp(-mu) * MoreMath.Pow(mu, k) / AdvancedIntegerMath.Factorial(k)); } else { return(Stirling.PoissonProbability(mu, k)); } } }