From 8013afc28cd2f372bada51bd4f1d5f57209834e0 Mon Sep 17 00:00:00 2001 From: janos Date: Sat, 18 Jul 2020 16:00:48 +0200 Subject: [PATCH] Math: add binomial coefficient function. --- src/Magnum/CMakeLists.txt | 2 +- src/Magnum/Math/Functions.cpp | 18 +++++++++++++++++ src/Magnum/Math/Functions.h | 12 ++++++++++++ src/Magnum/Math/Test/FunctionsTest.cpp | 27 ++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index 49be7a307..f38bf29d2 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -111,11 +111,11 @@ set(MagnumMath_SRCS Math/Angle.cpp Math/Color.cpp Math/Half.cpp - Math/Functions.cpp Math/Packing.cpp Math/instantiation.cpp) set(MagnumMath_GracefulAssert_SRCS + Math/Functions.cpp Math/PackingBatch.cpp) # Objects shared between main and math test library diff --git a/src/Magnum/Math/Functions.cpp b/src/Magnum/Math/Functions.cpp index b547cc12a..a52819446 100644 --- a/src/Magnum/Math/Functions.cpp +++ b/src/Magnum/Math/Functions.cpp @@ -23,6 +23,8 @@ DEALINGS IN THE SOFTWARE. */ +#include + #include "Functions.h" namespace Magnum { namespace Math { @@ -41,4 +43,20 @@ UnsignedInt log2(UnsignedInt number) { return log; } + +UnsignedLong binomialCoefficient(UnsignedInt n, UnsignedInt k) { + if (k > n) return 0; + if (k * 2 > n) + k = n-k; + if (k == 0) return 1; + + UnsignedLong result = n; + for(UnsignedInt i = 2; i <= k; ++i ) { + CORRADE_ASSERT(result < ~UnsignedLong{} / (n-i+1), "Math::binomialCoefficient(): overflow for (" << Corrade::Utility::Debug::nospace << n << "choose" << k << Corrade::Utility::Debug::nospace << ")", 0ul); + result *= (n-i+1); + result /= i; + } + return result; +} + }} diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 92d8e9cb1..2fe2cf1fc 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -410,6 +410,18 @@ template inline Vector ceil(const Vector