/// <inheritdoc /> /// <param name="k">The order of moment to compute.</param> public override double RawMoment(int k) { if (k < 0) { throw new ArgumentOutOfRangeException(nameof(k)); } else if (k == 0) { return(1.0); } else { // The (falling) factorial moments of the negative binomial distribution // are F_k = (p/q)^m (r)_m, where (r)_m is a rising factorial. // We can use this plus the Stirling numbers, which convert factorial // to raw moments. double[] s = AdvancedIntegerMath.StirlingNumbers2(k); double f = p / q; double t = 1.0; double M = 0.0; for (int i = 1; i <= k; i++) { t *= f * (r + i - 1); M += s[i] * t; } return(M); } }
public void StirlingNumbers2RowSum() { foreach (int n in TestUtilities.GenerateIntegerValues(1, 100, 4)) { double sum = 0.0; foreach (double s in AdvancedIntegerMath.StirlingNumbers2(n)) { sum += s; } Assert.IsTrue(TestUtilities.IsNearlyEqual(sum, AdvancedIntegerMath.BellNumber(n))); } }
public void StirlingNumberMatrixInverse() { int n = 8; SquareMatrix S1 = new SquareMatrix(n); for (int i = 0; i < n; i++) { double[] s = AdvancedIntegerMath.StirlingNumbers1(i); for (int j = 0; j < s.Length; j++) { if ((i - j) % 2 == 0) { S1[i, j] = s[j]; } else { S1[i, j] = -s[j]; } } } SquareMatrix S2 = new SquareMatrix(n); for (int i = 0; i < n; i++) { double[] s = AdvancedIntegerMath.StirlingNumbers2(i); for (int j = 0; j < s.Length; j++) { S2[i, j] = s[j]; } } SquareMatrix S12 = S1 * S2; SquareMatrix I = new SquareMatrix(n); for (int i = 0; i < n; i++) { I[i, i] = 1.0; } Assert.IsTrue(TestUtilities.IsNearlyEqual(S12, I)); }
/// <inheritdoc /> public override double RawMoment(int r) { if (r < 0) { throw new ArgumentOutOfRangeException(nameof(r)); } else if (r == 0) { return(1.0); } else { if (n < 2 * r) { // If n is small, just do a weighted sum over the support. return(ExpectationValue(delegate(int k) { return (MoreMath.Pow(k, r)); })); } else { // If n >> r, convert analytically known factorial moments to raw moments // using Sterling numbers of the 2nd kind. The (falling) factorial moment // F_r = (n)_r p^r // where (n)_r is a falling factorial. double[] s = AdvancedIntegerMath.StirlingNumbers2(r); double t = 1.0; double M = 0.0; for (int k = 1; k <= r; k++) { // s[0] = 0 (except for r=0, in which case we have already returned above) t *= (n - (k - 1)) * p; M += s[k] * t; } return(M); } } }