From 6c1c279a2a14752a30f6b64e2126e938c705b165 Mon Sep 17 00:00:00 2001
From: Christian Godenschwager <christian.godenschwager@fau.de>
Date: Mon, 22 May 2017 12:21:17 +0200
Subject: [PATCH] Added function to get all divisors of an integer

---
 src/core/math/Primes.cpp       | 38 ++++++++++++++++++++++++++++++++++
 src/core/math/Primes.h         |  2 ++
 tests/core/math/PrimesTest.cpp | 13 +++++++++++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/core/math/Primes.cpp b/src/core/math/Primes.cpp
index b0070b017..81cad6dff 100644
--- a/src/core/math/Primes.cpp
+++ b/src/core/math/Primes.cpp
@@ -132,5 +132,43 @@ std::vector<uint_t> getPrimeFactors( const uint_t n )
    return primeFactors;
 }
 
+
+/*******************************************************************************************************************//**
+ * \brief   Gets all devisors of a number n.
+ *
+ * Computes all unique products of n's prime factors.
+ *
+ * \param   n  The number the devisors are computed for.
+ *
+ * \pre     n > 0
+ *
+ * \return  A set of the devisors including 1 and n
+ **********************************************************************************************************************/
+std::set<uint_t> getDevisors( const uint_t n )
+{
+   if( n == uint_t(0) )
+      return std::set<uint_t>();
+
+   std::vector<uint_t> factors = getPrimeFactors( n );
+
+   std::set<uint_t> devisors;
+   std::vector<uint_t> tmpDevisors;
+
+   devisors.insert( uint_t(1) );
+   tmpDevisors.reserve( ( size_t(1) << factors.size() ) - size_t(1) );
+
+   for( auto fIt = factors.begin(); fIt != factors.end(); ++fIt )
+   {
+      tmpDevisors.clear();
+      for(auto pIt = devisors.begin(); pIt != devisors.end(); ++pIt)
+      {
+         tmpDevisors.push_back( *pIt * *fIt );
+      }
+      devisors.insert( tmpDevisors.begin(), tmpDevisors.end() );
+   }
+
+   return devisors;
+}
+
 } // namespace math
 } // namespace walberla
diff --git a/src/core/math/Primes.h b/src/core/math/Primes.h
index 648b81f48..153b7f67e 100644
--- a/src/core/math/Primes.h
+++ b/src/core/math/Primes.h
@@ -24,6 +24,7 @@
 
 #include "core/DataTypes.h"
 
+#include <set>
 #include <vector>
 
 
@@ -33,6 +34,7 @@ namespace math {
 bool                isPrime        ( const uint_t n );
 std::vector<uint_t> getPrimes      ( const uint_t n );
 std::vector<uint_t> getPrimeFactors( const uint_t n );
+std::set<uint_t>    getDevisors    ( const uint_t n );
 
 } // namespace math
 } // namespace walberla
diff --git a/tests/core/math/PrimesTest.cpp b/tests/core/math/PrimesTest.cpp
index c2eff8dca..9e8a776a0 100644
--- a/tests/core/math/PrimesTest.cpp
+++ b/tests/core/math/PrimesTest.cpp
@@ -44,9 +44,20 @@ bool is_sorted( InputIterator begin, InputIterator end )
 void runTests( const uint_t n )
 {
    auto primes = math::getPrimes(n);
+   auto devisors = math::getDevisors(n);
+
    WALBERLA_CHECK( ::is_sorted( primes.begin(), primes.end() ) );
-   for(uint_t i = 0; i <= n; ++i)
+   for(uint_t i = 1; i <= n; ++i)
+   {
       WALBERLA_CHECK_EQUAL( walberla::math::isPrime(i), std::binary_search( primes.begin(), primes.end(), i ) );
+      WALBERLA_CHECK_EQUAL( n % i == 0, devisors.find( i ) != devisors.end() );
+   }
+
+   for( auto it = primes.begin(); it != primes.end(); ++it )
+      WALBERLA_CHECK( math::isPrime( *it ) );
+
+   for( auto it = devisors.begin(); it != devisors.end(); ++it )
+      WALBERLA_CHECK( n % *it == 0 );
 
    if( n != 0 )
    {
-- 
GitLab