diff --git a/src/core/math/Primes.cpp b/src/core/math/Primes.cpp index b0070b0178be7f264d06d7365371e666f423e792..81cad6dffaf1de0b03a4e6b17f5b657449b7c369 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 648b81f487df9d8eee210e63b3356beaf5658acc..153b7f67ee6a6a0d22e309d80ac7f0f44dba3c84 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 c2eff8dca2319edb29e203f129ef022c3cc504ec..9e8a776a05e536d62cf04797fc5d5d4753bb08a7 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 ) {