private static double PValueForSmallN(int n, int m, double u) { int q = (int)Math.Floor(u + 1e-9); int nm = Math.Max(n, m); var w = new long[nm + 1, nm + 1, q + 1]; for (int i = 0; i <= nm; i++) { for (int j = 0; j <= nm; j++) { for (int k = 0; k <= q; k++) { if (i == 0 || j == 0 || k == 0) { w[i, j, k] = k == 0 ? 1 : 0; } else if (k > i * j) { w[i, j, k] = 0; } else if (i > j) { w[i, j, k] = w[j, i, k]; } else if (j > 0 && k < j) { w[i, j, k] = w[i, k, k]; } else { w[i, j, k] = w[i - 1, j, k - j] + w[i, j - 1, k]; } } } } long denominator = BinomialCoefficientHelper.GetBinomialCoefficient(n + m, m); long p = 0; if (q <= n * m / 2) { for (int i = 0; i <= q; i++) { p += w[n, m, i]; } } else { q = n * m - q; for (int i = 0; i < q; i++) { p += w[n, m, i]; } p = denominator - p; } return(p * 1.0 / denominator); }
public double Pmf(int k) { if (k < 0 || k > N) { return(0); } return(Math.Exp( BinomialCoefficientHelper.GetLogBinomialCoefficient(N, k) + k * Math.Log(P) + (N - k) * Math.Log(1 - P) )); }
public void BinomialCoefficientTest(int n, int k, long expected) { long actual = BinomialCoefficientHelper.GetBinomialCoefficient(n, k); Assert.Equal(expected, actual); }