Skip to content

Commit eafbefc

Browse files
committed
Remove all mulitples of wheel basis from bitset
[CI SKIP]
1 parent f39a4d8 commit eafbefc

File tree

3 files changed

+47
-18
lines changed

3 files changed

+47
-18
lines changed

include/boost/math/special_functions/detail/interval_prime_sieve.hpp

+42-13
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ using uint128_t = boost::multiprecision::uint128_t;
7373
Integer delta_;
7474
Integer left_;
7575
Integer right_;
76+
77+
// The adjusted value of left that represent the beginning value of the bitset based off the next spoke in the wheel after left_
78+
Integer mod_left_;
7679

7780
OutputIterator resultant_primes_;
7881

@@ -143,17 +146,33 @@ void IntervalSieve<Integer, OutputIterator>::Settdlimit() noexcept
143146
template<typename Integer, typename OutputIterator>
144147
void IntervalSieve<Integer, OutputIterator>::SeiveLength(const Integer d) noexcept
145148
{
146-
Integer r {left_ % d};
147-
Integer start {0};
148-
149-
if(r != 0)
149+
// Find the first multiple of d in the bitset to use as the entry point
150+
Integer current_multiple {mod_left_};
151+
Integer current_spoke {mod_left_};
152+
std::size_t i {};
153+
while(current_multiple % d != 0)
150154
{
151-
start = d - r;
155+
++current_multiple;
156+
if(current_spoke < current_multiple)
157+
{
158+
current_spoke = w_.Next(current_spoke);
159+
++i;
160+
}
152161
}
153162

154-
for(Integer i {start}; i >= 0 && i < b_.size(); i += d)
163+
while(i < b_.size())
155164
{
156-
b_.clear(static_cast<std::size_t>(i));
165+
if(current_multiple == current_spoke)
166+
{
167+
b_.clear(i);
168+
}
169+
170+
current_multiple += d;
171+
while(current_spoke < current_multiple)
172+
{
173+
current_spoke = w_.Next(current_spoke);
174+
++i;
175+
}
157176
}
158177
}
159178

@@ -172,11 +191,11 @@ void IntervalSieve<Integer, OutputIterator>::Sieve() noexcept
172191
}
173192

174193
// Sieve with pre-computed (or small) primes and then use the wheel for the remainder
175-
std::size_t i {};
194+
// Start with the first prime being 7 as the wheel basis (2,3,5) is not represented in b_
195+
std::size_t i {2};
176196
Integer j;
177197
if(plimit_ <= pss_.prime.back())
178198
{
179-
SeiveLength(static_cast<Integer>(2));
180199
for(; pss_.prime[i] < primes_range; ++i)
181200
{
182201
SeiveLength(pss_.prime[i]);
@@ -187,6 +206,7 @@ void IntervalSieve<Integer, OutputIterator>::Sieve() noexcept
187206

188207
else
189208
{
209+
++i; // linear_sieve begins with 2 whereas pss_.prime begins with 3
190210
primes_.resize(static_cast<std::size_t>(prime_approximation(right_)));
191211
linear_sieve(primes_range, primes_.begin());
192212

@@ -207,12 +227,14 @@ void IntervalSieve<Integer, OutputIterator>::Sieve() noexcept
207227
template<typename Integer, typename OutputIterator>
208228
decltype(auto) IntervalSieve<Integer, OutputIterator>::WriteOutput() noexcept
209229
{
210-
for(std::size_t i {left_ % 2 == 0 ? 1 : 0}; i < b_.size(); i += 2)
230+
Integer current_spoke {mod_left_};
231+
for(std::size_t i {}; i < b_.size(); ++i)
211232
{
212233
if(b_[i])
213234
{
214-
*resultant_primes_++ = left_ + i;
235+
*resultant_primes_++ = current_spoke;
215236
}
237+
current_spoke = w_.Next(current_spoke);
216238
}
217239
return resultant_primes_;
218240
}
@@ -223,7 +245,13 @@ decltype(auto) IntervalSieve<Integer, OutputIterator>::WriteOutput() noexcept
223245
template<typename Integer, typename OutputIterator>
224246
bool IntervalSieve<Integer, OutputIterator>::Psstest(const std::size_t pos) noexcept
225247
{
226-
const Integer n {static_cast<Integer>(left_ + pos)};
248+
// Convert a bitset position (pos) into the corresponding numerical value using the wheel
249+
Integer n {mod_left_};
250+
for(std::size_t i {}; i < pos; ++i)
251+
{
252+
n = w_.Next(n);
253+
}
254+
227255
const Integer exponent {(n - 1) / 2};
228256
const std::int_fast64_t nmod8 = static_cast<std::int_fast64_t>(n % 8);
229257

@@ -283,8 +311,9 @@ void IntervalSieve<Integer, OutputIterator>::Setup(const Integer left, const Int
283311
left_ = left;
284312
right_ = right;
285313
delta_ = right_ - left_;
314+
mod_left_ = w_.Next(left_ - 1); // Subtract one in the case that left_ resides on a spoke
286315

287-
b_.resize(static_cast<std::size_t>(delta_));
316+
b_.resize(static_cast<std::size_t>(delta_) * w_.PrimeRatio());
288317
b_.reset();
289318
Settdlimit();
290319
Sieve();

include/boost/math/special_functions/prime_sieve_iter.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <boost/math/special_functions/detail/linear_prime_sieve.hpp>
1212
#include <boost/math/special_functions/detail/interval_prime_sieve.hpp>
1313
#include <boost/math/special_functions/prime_approximation.hpp>
14-
#include <boost/math/special_functions/prime_sieve.hpp>
1514
#include <execution>
1615
#include <vector>
1716
#include <future>

test/test_prime_sieve.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,9 @@ int main()
435435
// Test SFINAE
436436
std::vector<int> test;
437437
auto test_ref = &test;
438-
static_assert(boost::math::detail::is_container<std::remove_pointer_t<decltype(test_ref)>>::value == 1, "INOP");
438+
static_assert(boost::math::detail::prime_sieve::is_container_t<std::remove_pointer_t<decltype(test_ref)>> == 1, "INOP");
439439

440+
/*
440441
// Individual Algorithms
441442
test_linear_sieve<int>();
442443
test_linear_sieve<int32_t>();
@@ -459,14 +460,14 @@ int main()
459460
test_linear_sieve_iterator<uint32_t>();
460461
test_linear_sieve_iterator<boost::multiprecision::cpp_int>();
461462
test_linear_sieve_iterator<boost::multiprecision::mpz_int>();
462-
463+
*/
463464
test_interval_sieve_iterator<int>();
464465
test_interval_sieve_iterator<int32_t>();
465466
test_interval_sieve_iterator<int64_t>();
466467
test_interval_sieve_iterator<uint32_t>();
467468
test_interval_sieve_iterator<boost::multiprecision::cpp_int>();
468469
test_interval_sieve_iterator<boost::multiprecision::mpz_int>();
469-
470+
/*
470471
test_stepanov_sieve<int>();
471472
472473
test_wheel_sieve_of_eratosthenes<int>();
@@ -558,6 +559,6 @@ int main()
558559
559560
boost::math::set_l1d_size(100'000);
560561
BOOST_ASSERT_MSG(boost::math::detail::prime_sieve::L1D_SIZE == 100'000, "L1 Size not set");
561-
562+
*/
562563
boost::report_errors();
563564
}

0 commit comments

Comments
 (0)