1 #include <symengine/prime_sieve.h>
2 #if __cplusplus <= 201703L
12 #ifdef HAVE_SYMENGINE_PRIMESIEVE
13 #include <primesieve.hpp>
19 static std::vector<unsigned> &sieve_primes()
21 static std::vector<unsigned> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
25 bool Sieve::_clear =
true;
26 unsigned Sieve::_sieve_size = 32 * 1024 * 8;
28 void Sieve::set_clear(
bool clear)
35 std::vector<unsigned> &_primes = sieve_primes();
36 _primes.erase(_primes.begin() + 10, _primes.end());
39 void Sieve::set_sieve_size(
unsigned size)
41 #ifdef HAVE_SYMENGINE_PRIMESIEVE
42 primesieve::set_sieve_size(size);
44 _sieve_size = size * 1024 * 8;
48 void Sieve::_extend(
unsigned limit)
50 std::vector<unsigned> &_primes = sieve_primes();
51 #ifdef HAVE_SYMENGINE_PRIMESIEVE
52 if (_primes.back() < limit)
53 primesieve::generate_primes(_primes.back() + 1, limit, &_primes);
55 const unsigned sqrt_limit
56 =
static_cast<unsigned>(std::floor(
std::sqrt(limit)));
57 unsigned start = _primes.back() + 1;
60 if (sqrt_limit >= start) {
62 start = _primes.back() + 1;
65 unsigned segment = _sieve_size;
66 std::valarray<bool> is_prime(segment);
67 for (; start <= limit; start += 2 * segment) {
68 unsigned finish = std::min(start + segment * 2 + 1, limit);
69 is_prime[std::slice(0, segment, 1)] =
true;
72 for (
unsigned index = 1; index < _primes.size()
73 and _primes[index] * _primes[index] <= finish;
75 unsigned n = _primes[index];
76 unsigned multiple = (start / n + 1) * n;
77 if (multiple % 2 == 0)
79 if (multiple > finish)
81 std::slice sl = std::slice((multiple - start) / 2,
82 1 + (finish - multiple) / (2 * n), n);
87 for (
unsigned n = start + 1; n <= finish; n += 2) {
88 if (is_prime[(n - start) / 2])
98 std::vector<unsigned> &_primes = sieve_primes();
99 auto it = std::upper_bound(_primes.begin(), _primes.end(), limit);
102 primes.reserve(it - _primes.begin());
103 std::copy(_primes.begin(), it, std::back_inserter(primes));
108 Sieve::iterator::iterator(
unsigned max)
114 Sieve::iterator::iterator()
120 Sieve::iterator::~iterator()
126 unsigned Sieve::iterator::next_prime()
128 std::vector<unsigned> &_primes = sieve_primes();
129 if (_index >= _primes.size()) {
130 unsigned extend_to = _primes[_index - 1] * 2;
131 if (_limit > 0 and _limit < extend_to) {
135 if (_index >= _primes.size()) {
139 return _primes[_index++];
static void generate_primes(std::vector< unsigned > &primes, unsigned limit)
Main namespace for SymEngine package.
RCP< const Basic > max(const vec_basic &arg)
Canonicalize Max:
RCP< const Basic > sqrt(const RCP< const Basic > &arg)