Skip to content

Commit

Permalink
Update to latest libprimesieve
Browse files Browse the repository at this point in the history
  • Loading branch information
kimwalisch committed Jan 9, 2024
1 parent 49b82b1 commit 0151d6f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 14 deletions.
6 changes: 3 additions & 3 deletions lib/primesieve/include/primesieve/StorePrimes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

namespace primesieve {

/// primeCountApprox(x) >= pi(x)
inline std::size_t prime_count_approx(uint64_t start, uint64_t stop)
/// prime_count_upper(x) >= pi(x)
inline std::size_t prime_count_upper(uint64_t start, uint64_t stop)
{
if (start > stop)
return 0;
Expand Down Expand Up @@ -83,7 +83,7 @@ inline void store_primes(uint64_t start,
if (stop > std::numeric_limits<V>::max())
throw primesieve_error("store_primes(): " + getTypeName<V>() + " is too narrow for generating primes up to " + std::to_string(stop));

std::size_t size = primes.size() + prime_count_approx(start, stop);
std::size_t size = primes.size() + prime_count_upper(start, stop);
primes.reserve(size);

primesieve::iterator it(start, stop);
Expand Down
12 changes: 6 additions & 6 deletions lib/primesieve/include/primesieve/pmath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ inline B inBetween(A min, B x, C max)
return x;
}

/// primeCountApprox(x) >= pi(x).
/// primeCountUpper(x) >= pi(x).
/// In order to prevent having to resize vectors with prime numbers
/// (which would incur additional overhead) it is important that
/// primeCountApprox(x) >= pi(x). Also for our purpose, it is
/// actually beneficial if primeCountApprox(x) is a few percent
/// primeCountUpper(x) >= pi(x). Also for our purpose, it is
/// actually beneficial if primeCountUpper(x) is a few percent
/// larger (e.g. 3%) than pi(x), this reduces the number of memory
/// allocations in PrimeGenerator::fillPrevPrimes().
///
inline std::size_t primeCountApprox(uint64_t start, uint64_t stop)
inline std::size_t primeCountUpper(uint64_t start, uint64_t stop)
{
if (start > stop)
return 0;
Expand All @@ -163,9 +163,9 @@ inline std::size_t primeCountApprox(uint64_t start, uint64_t stop)
return (std::size_t) pix;
}

inline std::size_t primeCountApprox(uint64_t stop)
inline std::size_t primeCountUpper(uint64_t stop)
{
return primeCountApprox(0, stop);
return primeCountUpper(0, stop);
}

/// Approximation of the maximum prime gap near n
Expand Down
2 changes: 1 addition & 1 deletion lib/primesieve/src/EratSmall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void EratSmall::init(uint64_t stop,
stop_ = stop;
maxPrime_ = maxPrime;
l1CacheSize_ = (std::size_t) l1CacheSize;
std::size_t count = primeCountApprox(maxPrime);
std::size_t count = primeCountUpper(maxPrime);
primes_.reserve(count);
}

Expand Down
8 changes: 4 additions & 4 deletions lib/primesieve/src/PrimeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ void PrimeGenerator::initPrevPrimes(Vector<uint64_t>& primes,
// When sieving backwards the number of primes inside [start, stop]
// slowly increases in each new segment as there are more small
// than large primes. Our new size has been calculated using
// primeCountApprox(start, stop) which is usually too large by 4%
// primeCountUpper(start, stop) which is usually too large by 4%
// near 10^12 and by 2.5% near 10^19. Hence if the new size is less
// than 1% larger than the old size we do not increase the primes
// buffer as it will likely be large enough to fit all primes.
Expand All @@ -177,7 +177,7 @@ void PrimeGenerator::initPrevPrimes(Vector<uint64_t>& primes,
}
};

std::size_t pix = primeCountApprox(start_, stop_);
std::size_t pix = primeCountUpper(start_, stop_);

if (start_ <= maxCachedPrime())
{
Expand Down Expand Up @@ -235,7 +235,7 @@ void PrimeGenerator::initNextPrimes(Vector<uint64_t>& primes,
// algorithm aborts as soon as there is not
// enough space to store 64 more primes.
std::size_t minSize = *size + 64;
std::size_t pix = primeCountApprox(start_, stop_) + 64;
std::size_t pix = primeCountUpper(start_, stop_) + 64;
pix = inBetween(minSize, pix, maxSize);
pix = std::max(*size, pix);
resize(primes, pix);
Expand All @@ -252,7 +252,7 @@ void PrimeGenerator::initNextPrimes(Vector<uint64_t>& primes,
// algorithm aborts as soon as there is not
// enough space to store 64 more primes.
std::size_t minSize = 64;
std::size_t pix = primeCountApprox(start_, stop_) + 64;
std::size_t pix = primeCountUpper(start_, stop_) + 64;
pix = inBetween(minSize, pix, maxSize);
resize(primes, pix);
}
Expand Down
11 changes: 11 additions & 0 deletions lib/primesieve/src/nthPrimeApprox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ uint64_t Ri_inverse(uint64_t x)
return (uint64_t) res;
}

/// primePiApprox(x) is a very accurate approximation of PrimePi(x)
/// with |PrimePi(x) - primePiApprox(x)| < sqrt(x).
/// Since primePiApprox(x) may be smaller than PrimePi(x) it
/// cannot be used to calculate the size of a primes array, for
/// this use case primeCountUpper() should be used.
///
uint64_t primePiApprox(uint64_t x)
{
// Li(x) is faster but less accurate than Ri(x).
Expand All @@ -277,6 +283,11 @@ uint64_t primePiApprox(uint64_t x)
return Ri(x);
}

/// nthPrimeApprox(n) is a very accurate approximation of the nth
/// prime with |nth prime - nthPrimeApprox(n)| < sqrt(nth prime).
/// Please note that nthPrimeApprox(n) may be smaller or larger than
/// the actual nth prime.
///
uint64_t nthPrimeApprox(uint64_t n)
{
// Li_inverse(n) is faster but less accurate than Ri_inverse(n).
Expand Down

0 comments on commit 0151d6f

Please sign in to comment.