diff --git a/src/Numerics/SpecialFunctions/Factorial.cs b/src/Numerics/SpecialFunctions/Factorial.cs
index 6807062a..d3d9a976 100644
--- a/src/Numerics/SpecialFunctions/Factorial.cs
+++ b/src/Numerics/SpecialFunctions/Factorial.cs
@@ -93,6 +93,38 @@ namespace MathNet.Numerics
return GammaLn(x + 1.0);
}
+ ///
+ /// Computes the binomial coefficient: n choose k.
+ ///
+ /// A nonnegative value n.
+ /// A nonnegative value h.
+ /// The binomial coefficient: n choose k.
+ public static double Binomial(int n, int k)
+ {
+ if (k < 0 || n < 0 || k > n)
+ {
+ return 0.0;
+ }
+
+ return Math.Floor(0.5 + Math.Exp(FactorialLn(n) - FactorialLn(k) - FactorialLn(n - k)));
+ }
+
+ ///
+ /// Computes the natural logarithm of the binomial coefficient: ln(n choose k).
+ ///
+ /// A nonnegative value n.
+ /// A nonnegative value h.
+ /// The logarithmic binomial coefficient: ln(n choose k).
+ public static double BinomialLn(int n, int k)
+ {
+ if (k < 0 || n < 0 || k > n)
+ {
+ return Double.NegativeInfinity;
+ }
+
+ return FactorialLn(n) - FactorialLn(k) - FactorialLn(n - k);
+ }
+
private static double[] GenerateFactorials(int max)
{
var cache = new double[max + 1];
diff --git a/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs b/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs
index 38dc6448..7c1ec6b9 100644
--- a/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs
+++ b/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs
@@ -78,5 +78,29 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests
AssertHelpers.AlmostEqual(307933.81973375485425, SpecialFunctions.FactorialLn(1 << 15), 14);
AssertHelpers.AlmostEqual(1413421.9939462073242, SpecialFunctions.FactorialLn(1 << 17), 14);
}
+
+ [Test]
+ public void CanComputeBinomial()
+ {
+ AssertHelpers.AlmostEqual(1, SpecialFunctions.Binomial(1, 1), 14);
+ AssertHelpers.AlmostEqual(10, SpecialFunctions.Binomial(5, 2), 14);
+ AssertHelpers.AlmostEqual(35, SpecialFunctions.Binomial(7, 3), 14);
+ AssertHelpers.AlmostEqual(1, SpecialFunctions.Binomial(1, 0), 14);
+ AssertHelpers.AlmostEqual(0, SpecialFunctions.Binomial(0, 1), 14);
+ AssertHelpers.AlmostEqual(0, SpecialFunctions.Binomial(5, 7), 14);
+ AssertHelpers.AlmostEqual(0, SpecialFunctions.Binomial(5, -7), 14);
+ }
+
+ [Test]
+ public void CanComputeBinomialLn()
+ {
+ AssertHelpers.AlmostEqual(Math.Log(1), SpecialFunctions.BinomialLn(1, 1), 14);
+ AssertHelpers.AlmostEqual(Math.Log(10), SpecialFunctions.BinomialLn(5, 2), 14);
+ AssertHelpers.AlmostEqual(Math.Log(35), SpecialFunctions.BinomialLn(7, 3), 14);
+ AssertHelpers.AlmostEqual(Math.Log(1), SpecialFunctions.BinomialLn(1, 0), 14);
+ AssertHelpers.AlmostEqual(Math.Log(0), SpecialFunctions.BinomialLn(0, 1), 14);
+ AssertHelpers.AlmostEqual(Math.Log(0), SpecialFunctions.BinomialLn(5, 7), 14);
+ AssertHelpers.AlmostEqual(Math.Log(0), SpecialFunctions.BinomialLn(5, -7), 14);
+ }
}
}
\ No newline at end of file