private static double dpois_wrap(double x_plus_1, double lambda, bool give_log) { double x; if (!lambda.IsFinite()) { return(give_log ? double.NegativeInfinity : 0.0); } if (x_plus_1 > 1) { return(PoissonDistribution.dpois_raw(x_plus_1 - 1, lambda, give_log)); } if (lambda > Math.Abs(x_plus_1 - 1) * M_cutoff) { x = -lambda - Functions.LogGamma(x_plus_1); return(give_log ? (x) : Math.Exp(x)); } else { double d = PoissonDistribution.dpois_raw(x_plus_1, lambda, give_log); return(give_log ? d + Math.Log(x_plus_1 / lambda) : d *(x_plus_1 / lambda)); } }
/* R file: pgamma.c * * Abramowitz and Stegun 6.5.29 [right] */ private static double pgamma_smallx(double x, double alph, bool lower_tail, bool log_p) { double sum = 0, c = alph, n = 0, term; /* * Relative to 6.5.29 all terms have been multiplied by alph * and the first, thus being 1, is omitted. */ do { n++; c *= -x / n; term = c / (alph + n); sum += term; } while (Math.Abs(term) > DBL_EPSILON * Math.Abs(sum)); if (lower_tail) { double f1 = log_p ? log1p(sum) : 1 + sum; double f2; if (alph > 1) { f2 = PoissonDistribution.dpois_raw(alph, x, log_p); f2 = log_p ? f2 + x : f2 *Math.Exp(x); } else if (log_p) { f2 = alph * Math.Log(x) - lgamma1p(alph); } else { f2 = Math.Pow(x, alph) / Math.Exp(lgamma1p(alph)); } return(log_p ? f1 + f2 : f1 *f2); } else { double lf2 = alph * Math.Log(x) - lgamma1p(alph); if (log_p) { return(R_Log1_Exp(log1p(sum) + lf2)); } else { double f1m1 = sum; double f2m1 = expm1(lf2); return(-(f1m1 + f2m1 + f1m1 * f2m1)); } } } /* pgamma_smallx() */
/* R file: dgamma.c */ /* Pdf */ public static double DGammaFromScale(double x, double shape, double scale, bool giveLog) { double pr; if (double.IsNaN(x) || double.IsNaN(shape) || double.IsNaN(scale)) { return(x + shape + scale); } if (shape < 0 || scale <= 0) { return(double.NaN); // ML_ERR_return_NAN; } if (x < 0) { return(giveLog ? double.NegativeInfinity : 0.0); } if (shape == 0) /* point mass at 0 */ { return((x == 0) ? double.NegativeInfinity : (giveLog ? double.NegativeInfinity : 0.0)); } if (x == 0) { if (shape < 1) { return(double.NegativeInfinity); } if (shape > 1) { return(giveLog ? double.NegativeInfinity : 0.0); } /* else */ return(giveLog ? -Math.Log(scale) : 1 / scale); } if (shape < 1) { pr = PoissonDistribution.dpois_raw(shape, x / scale, giveLog); return(giveLog ? pr + Math.Log(shape / x) : pr *shape / x); } /* else shape >= 1 */ pr = PoissonDistribution.dpois_raw(shape - 1, x / scale, giveLog); return(giveLog ? pr - Math.Log(scale) : pr / scale); }