Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prime Number Functions #400

Draft
wants to merge 117 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
4015fbc
Initial Commit
mborland Jul 9, 2020
3ee737b
Changed init of least_divisors
mborland Jul 10, 2020
9512bb6
Cleanup
mborland Jul 10, 2020
d762398
Cleanup
mborland Jul 10, 2020
5375a1d
Added additional tests, benchmarks, and overflow checks
mborland Jul 10, 2020
a684dbd
Fix include guard naming
mborland Jul 10, 2020
3e4db8a
Complete revamp of algorithm. Hide implementation behind detail names…
mborland Jul 12, 2020
dd8a61c
Re-added support and tests for boost::multiprecision::cpp_int [CI SKIP]
mborland Jul 12, 2020
4debd0d
Changed benchmarks to support threading [CI SKIP]
mborland Jul 13, 2020
2a7e031
Added execution policies. Increased performance for dynamically linke…
mborland Jul 14, 2020
a68910e
Added massively parallel section to prime_sieve. Increased length of …
mborland Jul 14, 2020
386cc4d
Add test for multi-threading section and add to Jamfile [CI SKIP]
mborland Jul 15, 2020
d79eddb
Added prime sieve to existing prime numbers documentation [CI SKIP]
mborland Jul 15, 2020
3fdf917
Revisions to documentation and send to CI
mborland Jul 15, 2020
6ca245b
Changed include guards to be compatible with C++11 and 14.
mborland Jul 15, 2020
7d3a520
Fixed doc, and ensured that primes are sorted
mborland Jul 15, 2020
a1ac504
Fixed documentation. Complete re-design of mask_sieve algo. Pre-gener…
mborland Jul 16, 2020
35d2aa1
All vectors now init {}. Change include guards. Replace raw pointer.
mborland Jul 17, 2020
243a299
Changed from [lower_bound, upper_bound] to [lower_bound, upper_bound)…
mborland Jul 18, 2020
2eadeff
Fixed documentation [CI SKIP]
mborland Jul 18, 2020
173ce0d
segmented_sieve now runs using std::async. [CI SKIP]
mborland Jul 18, 2020
23fba36
Removed extraneous operations [CI SKIP]
mborland Jul 19, 2020
f7b45fd
Cleanup style, and delete unused function. Enable par_unseq mask_siev…
mborland Jul 19, 2020
d687d5e
Small Cleanup and limit reduction for sieving methods.
mborland Jul 20, 2020
e51d727
Add pritchard's sub-linear algo [WIP][CI SKIP]
mborland Jul 25, 2020
1245d27
Added pritchards segmented sieve [WIP][CI SKIP]
mborland Jul 26, 2020
2052081
Implemented binary search in SetS [WIP][CI SKIP]
mborland Jul 27, 2020
9f81e0d
Tests and performance compairsons [WIP][CI SKIP]
mborland Jul 27, 2020
55ea045
More tests. Segmented sieve small cases fix
mborland Jul 27, 2020
31a2105
Imporve segmented performance [WIP][CI SKIP]
mborland Jul 29, 2020
f545928
Replaced SetS members with stl algos [WIP][CI SKIP]
mborland Jul 29, 2020
d780db5
Replace searching with tracked index. General performance improvement…
mborland Jul 31, 2020
2639bed
Minor change to SetS remove [WIP][CI SKIP]
mborland Aug 1, 2020
94fc1ac
Pritchard segmented performance improvements [WIP][CI SKIP]
mborland Aug 1, 2020
6ebb906
Fixed failed test [WIP][CI SKIP]
mborland Aug 1, 2020
0521854
Various performance improvements [WIP][CI SKIP]
mborland Aug 2, 2020
b233a80
Build primes in situ [WIP][CI SKIP]
mborland Aug 2, 2020
f95c2cf
Refactoring. Now requires C++17
mborland Aug 2, 2020
8e2e29a
Add segmented bit sieve [WIP][CI SKIP]
mborland Aug 4, 2020
1a24f16
Removed segmented bit sieve and excess headers [CI SKIP]
mborland Aug 6, 2020
c63f1f1
Added wheel class [WIP][CI SKIP]
Aug 15, 2020
b7d4256
Added fixed mod 210 wheel [WIP][CI SKIP]
Aug 23, 2020
fbc38c8
New segmented sieve algorithm [WIP][CI SKIP]
Aug 23, 2020
2e46b81
Added interval sieve to performance test [CI SKIP]
Aug 23, 2020
6759ede
Added unit tests [WIP][CI SKIP]
Aug 23, 2020
1b40403
Implemented interval sieve [CI SKIP]
Aug 23, 2020
97244be
Performance improvements and bug fixes [CI SKIP]
Aug 24, 2020
fa04133
Significant refactoring [WIP][CI SKIP]
Aug 25, 2020
c4a89c8
Seq policy actually sequential [CI SKIP]
Aug 25, 2020
91836f6
Fixes for multiprecision and policies [CI SKIP]
Aug 25, 2020
6d6b19f
cpp_int now passes all tests [CI SKIP]
Aug 27, 2020
81e4a6c
mpz_int passes unit tests [CI SKIP]
Aug 27, 2020
0b8f1d5
Documentation edits [CI SKIP]
mborland Aug 30, 2020
5ba0a1d
Replace magic number w variable template [CI SKIP]
mborland Aug 31, 2020
8e240f7
Better prime_range implementation [WIP][CI SKIP]
mborland Aug 31, 2020
7c0cbbf
Merge branch 'develop' into prime_functions
mborland Sep 1, 2020
3d9b77c
Minor changes and doc updates
mborland Sep 2, 2020
302fb5f
Merge branch 'develop' into prime_functions
mborland Sep 5, 2020
9792a23
Minor change to policy handling [CI SKIP]
mborland Sep 6, 2020
84a69f0
diffs from @jzmaddock [CI SKIP]
mborland Sep 8, 2020
5dc3523
Implemented linear sieve with iterators
mborland Sep 9, 2020
0dbe69c
Sanitize linear prime sieve and add wheel
mborland Sep 9, 2020
eee2c86
Added container method
mborland Sep 26, 2020
f5d789a
Improved Linear Algo and testing
mborland Sep 27, 2020
f2277e3
Merge branch 'prime_iterator' into mborland/prime_iterator
mborland Sep 27, 2020
1d2f03c
Linear sieve with output iterator and refactoring [CI SKIP][WIP]
mborland Sep 27, 2020
0d9d31b
Merge branch 'prime_functions' into mborland/prime_functions
mborland Sep 27, 2020
c361cde
Linear output iterator and refactoring [CI SKIP]
mborland Sep 27, 2020
66c2642
Added prime approximation function
mborland Sep 27, 2020
de1f331
prime approximation function for a range
mborland Sep 27, 2020
eaea5f9
Added interval sieve for output iterators
mborland Sep 27, 2020
e8196f3
Merge remote-tracking branch 'origin/develop' into prime_iterator
mborland Sep 27, 2020
cb5d978
Interval sieve with OI passes unit tests [CI SKIP]
mborland Sep 27, 2020
830ccc4
Merge branch 'prime_iterator' into prime_functions
mborland Sep 27, 2020
4dc3eb2
Add sequential composite sieve with OI [CI SKIP]
mborland Sep 30, 2020
90be100
Add threaded method. Currently INOP [CI SKIP]
mborland Sep 30, 2020
a772782
Threaded method completed and validated [CI SKIP]
mborland Oct 1, 2020
2d1461f
Resolves issue #439 [CI SKIP]
mborland Oct 1, 2020
e7cdb32
Updated benchmarks [CI SKIP]
mborland Oct 2, 2020
29eef88
Correct benchmark memory allocation [CI SKIP]
mborland Oct 3, 2020
b5a28b5
Add linear sieve direct from stepanov [CI SKIP]
mborland Oct 4, 2020
6c26b53
First draft of eratosthenes w/ wheel [CI SKIP]
mborland Oct 4, 2020
980bfe7
Fixes for multiprecision types [CI SKIP]
mborland Oct 4, 2020
07e6f58
wheel sieve passes standard battery [CI SKIP]
mborland Oct 4, 2020
86b9e5a
Add prime sieve wrapper [CI SKIP]
mborland Oct 5, 2020
f19149e
Implement dual interface for prime sieve [CI SKIP]
mborland Oct 7, 2020
1ad0d51
Implement dual interface for prime_range [CI SKIP]
mborland Oct 7, 2020
5f6d06a
Remove uneeded vals from wheel [CI SKIP]
mborland Nov 22, 2020
670b06d
Internal data structure changes [CI SKIP]
mborland Nov 22, 2020
7c7a491
Rename type alias [CI SKIP]
mborland Nov 23, 2020
e507ba5
Swap mod 210 wheel for mod 30 wheel [CI SKIP]
mborland Nov 23, 2020
c9cb41c
Add simple bitset file [CI SKIP]
mborland Nov 23, 2020
e8b71a0
Reduced unnecessary traversing of bitset [CI SKIP]
mborland Nov 24, 2020
d649f65
Updated bitset [CI SKIP]
mborland Nov 24, 2020
ed98892
Add resize to simple_bitset [CI SKIP]
mborland Nov 26, 2020
c3b3934
Implement simple_bitset as internal data structure
mborland Nov 26, 2020
e9aa05d
Add prime-composite ratio to wheel to size bitset
mborland Nov 27, 2020
7c5d792
minor refactoring [CI SKIP]
mborland Nov 27, 2020
2bbfad2
Fix PrimeRatio [CI SKIP]
mborland Nov 27, 2020
ddc5c8a
Improved prime range [CI SKIP]
mborland Nov 27, 2020
f517c00
Add hamming weight calc to simple bitset [CI SKIP]
mborland Nov 28, 2020
a356b47
Add forward and reverse bit scan to simple bitset
mborland Nov 28, 2020
2212e45
Fix count, enable bit scan by type, cleanup
mborland Nov 28, 2020
b12e2dc
Add dual interface. Avoid using multiprecision
mborland Nov 28, 2020
f39a4d8
Seperate approximation for multiprecision types
mborland Nov 29, 2020
eafbefc
Remove all mulitples of wheel basis from bitset
mborland Nov 29, 2020
cb36b89
IntervalSieve performance improvements [CI SKIP]
mborland Nov 29, 2020
16c2354
Add small prime optimization [CI SKIP]
mborland Dec 5, 2020
0b1a690
Add small primes to full sieve [CI SKIP]
mborland Dec 8, 2020
8c883d1
Merge remote-tracking branch 'origin/develop' into prime_functions
mborland Dec 12, 2020
f357e0f
Implement bit scanning in sieve [CI SKIP]
mborland Dec 12, 2020
a4f2d89
Fix minor errors
mborland Dec 12, 2020
d16e562
Add trial divison to verify tests [CI SKIP]
mborland Dec 12, 2020
91be2c3
Fix small primes [CI SKIP]
mborland Dec 12, 2020
d9ae8c2
Revert interval_prime_sieve.hpp to f39a4d8
mborland Dec 13, 2020
7d22010
Remove cruft [CI SKIP]
mborland Dec 13, 2020
b541987
Continue cleanup [CI SKIP]
mborland Dec 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ inspect.html
test/cuda
*.DS_Store
/**/*.dSYM/
build/*
*.json

58 changes: 56 additions & 2 deletions doc/sf/number_series.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,63 @@ Passing a value greater than `max_prime` results in a __domain_error being raise

This function is `constexpr` only if the compiler supports C++14 constexpr functions.

[endsect] [/section:primes]
[endsect] [/section:primes Prime Numbers]

[endsect] [/Number Series]
[section:prime_sieve Prime Sieve]

[h4 Synopsis]

``
#include <boost/math/special_functions/prime_sieve.hpp>
``

namespace boost { namespace math {

template<class ExecutionPolicy, typename Z, class OutputIterator>
auto prime_sieve(ExecutionPolicy&& policy, Z upper_bound, OutputIterator output) -> decltype(output)

template<class ExecutionPolicy, class Z, class OutputIterator>
auto prime_range(ExecutionPolicy&& policy, Z lower_bound, Z upper_bound, OutputIterator output) -> decltype(output)

template<typename Z, class OutputIterator>
auto prime_sieve(Z upper_bound, OutputIterator output) -> decltype(output)

template<class Z, class OutputIterator>
auto prime_range(Z lower_bound, Z upper_bound, OutputIterator output) -> decltype(output)


}} // End namespaces

[h4 Description]

There are two sets of functions available `prime_sieve` and `prime_range`. `prime_sieve` will return all primes in the
range [2, `upper_bound`). `prime_range` will return all the primes in the range [lower_bound, upper_bound).

If you have a C++17 compatible compiler you are able to pass an execution policy to both functions. Any
policy besides `std::execution::seq` will enable internal multi-threading. If your compiler is not C++17 compatible the
mborland marked this conversation as resolved.
Show resolved Hide resolved
sequential overloads will be used.
mborland marked this conversation as resolved.
Show resolved Hide resolved

For upper_bound <= 2[super 24] two threads will be used. For any value larger than 2[super 24] `std::thread::hardware_concurrency()` will be called,
mborland marked this conversation as resolved.
Show resolved Hide resolved
and all available concurrency will be used. Additionally, the memory requirements are `bigo[](sqrt(N))`.
mborland marked this conversation as resolved.
Show resolved Hide resolved

/Nota bene:/ If `std::thread::hardware_concurrency()` returns 0 the max number of threads will be set to 2.

[h4 Examples]
// To calculate primes 2 - 1,000,000 in parallel
mborland marked this conversation as resolved.
Show resolved Hide resolved
std::vector<int64_t> primes;
boost::math::prime_sieve(std::execution::par, 1000000, std::back_inserter(primes));

// To calculate primes 100 - 1,000 sequentially
std::vector<int64_t> primes;
boost::math::prime_range(100, 1000, std::back_inserter(primes));

[h4 References]
* Sorensen, Jonathan [@https://research.cs.wisc.edu/techreports/1990/TR909.pdf An Introduction to Prime Number Sieves]
* Gries, David and Misra, Jayadev [@https://www.cs.utexas.edu/users/misra/scannedPdf.dir/linearSieve.pdf A Linear Sieve Algorithm for Finding Prime Numbers]

[endsect] [/section:primes Prime Sieve]

[endsect] [/section:number_series Number Series]

[/
Copyright 2013, 2014 Nikhar Agrawal, Christopher Kormanyos, John Maddock, Paul A. Bristow.
Expand Down
309 changes: 309 additions & 0 deletions include/boost/math/special_functions/interval_sieve.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
// Copyright 2020 Matt Borland and Jonathan Sorenson
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_INTERVAL_SIEVE_HPP
#define BOOST_MATH_SPECIAL_FUNCTIONS_INTERVAL_SIEVE_HPP

#include <boost/dynamic_bitset.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/math/special_functions/prime_wheel.hpp>
#include <cmath>
#include <memory>
#include <array>
#include <cstdint>
#include <bitset>

namespace boost::math::detail
{

#if defined(__MPIR_VERSION) || defined(__GNU_MP_VERSION)
// GNU GMP C or MPIR
inline double get_double(const mpz_t &x) noexcept
{
return mpz_get_d(x);
}
#endif

#if defined(__GNU_MP_VERSION)
#if __has_include(<gmpxx.h>)
// GNU GMP C++ bindings
inline double get_double(const mpz_class &x) noexcept
{
return x.get_d()
mborland marked this conversation as resolved.
Show resolved Hide resolved
}
#endif
#endif

// boost::multiprecision and POD
template<class Integer>
inline double get_double(const Integer &x) noexcept
{
return static_cast<double>(x);
}

template<class Integer, class PrimeContainer, class Container>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you understand the difference, what you have called PrimeContainer is not actually a container. Or more precisely, the concrete type that instantiates here does not have to model all the interface of the Container concept.
primes_ just has to model a RandomAccessRange, i.e. it has begin(), end(), size() and T& operator[](std::size_t i). A container can model that, but a pair of iterators, or an iterator-size pair can too.
So, to be precise, that template parameter is not a (Prime)Container, it's a (Prime)RandomAccessRange.

class IntervalSieve
{
#ifdef __SIZEOF_INT128__ // Defined in GCC 4.6+, clang, intel. MSVC does not define.
mborland marked this conversation as resolved.
Show resolved Hide resolved
using int_128t = __int128; // One machine word smaller than the boost equivalent
#else
using int_128t = boost::multiprecision::int128_t;
#endif

private:
// Table of pseudo-sqares (https://mathworld.wolfram.com/Pseudosquare.html)
// This table is from page 421, table 16.3.1, Hugh Williams' book
// Last 8 entries added from Wooding's MS thesis, 2003, pp. 92-93
struct pssentry
{
static constexpr std::size_t len {49};
static constexpr std::array<std::int_fast16_t, len> prime
{
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 67, 71, 79, 83, 101, 103, 107, 113, 131, 149, 157,
173, 181, 193, 197, 211, 227, 229, 233, 239, 241, 251, 257, 263, 277, 281, 283, 293, 311, 331, 337, 347, 353
};

static constexpr std::array<int_128t, len> ps
{
73, 241, 1'009, 2'641, 8'089, 18'001, 53'881, 87'481, 117'049, 515'761, 1'083'289, 3'206'641, 3'818'929,
9'257'329, 22'000'801, 48'473'881, 175'244'281, 427'733'329, 898'716'289, 2'805'544'681, 10'310'263'441,
23'616'331'489, 85'157'610'409, 196'265'095'009, 2'871'842'842'801, 26'250'887'023'729, 112'434'732'901'969,
178'936'222'537'081, 696'161'110'209'049, 2'854'909'648'103'881, 6'450'045'516'630'769, 11'641'399'247'947'921,
190'621'428'905'186'449, 196'640'148'121'928'601, 712'624'335'095'093'521, 1'773'855'791'877'850'321,
2'327'687'064'124'474'441, 6'384'991'873'059'836'689, 8'019'204'661'305'419'761, 10'198'100'582'046'287'689,
69'848'288'320'900'186'969, 208'936'365'799'044'975'961, 533'552'663'339'828'203'681, 936'664'079'266'714'697'089,
2'142'202'860'370'269'916'129, 13'649'154'491'558'298'803'281, 34'594'858'801'670'127'778'801,
99'492'945'930'479'213'334'049, 295'363'187'400'900'310'880'401
};
};

static constexpr pssentry pss_{};
static constexpr boost::math::detail::MOD210Wheel<Integer> w_{};
std::size_t tdlimit_;

Integer delta_;
Integer left_;
Integer right_;

// https://www.researchgate.net/publication/220803585_Performance_of_C_bit-vector_implementations
boost::dynamic_bitset<> b_;

const PrimeContainer& primes_;
std::int_fast64_t plimit_;

void Settdlimit() noexcept;
void SeiveLength(const Integer d) noexcept;
void Sieve() noexcept;
bool Psstest(const std::size_t pos) noexcept;
void Psstestall() noexcept;
void WriteOutput(Container &resultant_primes) noexcept;

public:
IntervalSieve(const Integer left, const Integer right, const PrimeContainer &primes, Container &resultant_primes) noexcept;
void NewRange(const Integer left, const Integer right, Container &resultant_primes) noexcept;
};

template<class Integer, class PrimeContainer, class Container>
void IntervalSieve<Integer, PrimeContainer, Container>::Settdlimit() noexcept
{
const double dr = get_double(right_);
const double delta = get_double(delta_);
const double tdest = delta * std::log(dr);

// Small cases
if(tdest * tdest >= dr)
{
tdlimit_ = static_cast<std::size_t>(std::sqrt(dr));
plimit_ = 0;
return;
}

// First guess
if(tdest <= 1ul<<30)
{
tdlimit_ = static_cast<std::size_t>(tdest);
}

else
{
tdlimit_ = 1ul<<30;
}

// Find the corresponding prime
std::size_t i;
for(i = pss_.len - 1; i > 0; --i)
{
if(static_cast<double>(pss_.ps[i]) * tdlimit_ < dr)
{
break;
}
}
plimit_ = pss_.prime[i];

double tdlimit_guess = 1 + std::fmod(dr, pss_.ps[i]);
if(tdlimit_guess * tdlimit_guess >= dr)
{
tdlimit_ = static_cast<std::size_t>(std::sqrt(dr));
plimit_ = 0;
}
}

template<class Integer, class PrimeContainer, class Container>
void IntervalSieve<Integer, PrimeContainer, Container>::SeiveLength(const Integer d) noexcept
{
Integer r {left_ % d};
Integer start {0};

if(r != 0)
{
start = d - r;
}

for(Integer i {start}; i >= 0 && i < b_.size(); i += d)
{
b_[static_cast<std::size_t>(i)] = 0;
}
}

template<class Integer, class PrimeContainer, class Container>
void IntervalSieve<Integer, PrimeContainer, Container>::Sieve() noexcept
{
std::int_fast64_t primes_range {};
if(plimit_ <= 10)
{
primes_range = 10;
}

else
{
primes_range = plimit_;
}

// Sieve with pre-computed primes and then use the wheel for the remainder
std::size_t i {};
for(; primes_[i] < primes_range; ++i)
{
SeiveLength(primes_[i]);
}

for(Integer j = w_.Next(primes_[--i]); j <= tdlimit_; j = w_.Next(j))
{
SeiveLength(j);
}
}

template<class Integer, class PrimeContainer, class Container>
void IntervalSieve<Integer, PrimeContainer, Container>::WriteOutput(Container &resultant_primes) noexcept
{
for(std::size_t i {}; i < b_.size(); ++i)
{
if(b_[i])
{
resultant_primes.emplace_back(left_ + i);
}
}
}

// Performs the pseduosqaure prime test on n = left + pos
// return 1 if prime or prime power, 0 otherwise
// Begins with a base-2 test
template<class Integer, class PrimeContainer, class Container>
bool IntervalSieve<Integer, PrimeContainer, Container>::Psstest(const std::size_t pos) noexcept
{
const Integer n {left_ + pos};
const Integer exponent {(n - 1) / 2};
const std::int_fast64_t nmod8 = n % 8;

std::int_fast64_t negative_one_count {0};

for(std::size_t i {}; i < primes_.size(); ++i)
{
Integer temp = primes_[i];
temp = static_cast<Integer>(std::pow(get_double(temp), get_double(n)));

if(temp == 1)
{
if(i == 0 && nmod8 == 5)
{
return false;
}
}

else
{
++temp;
if(temp == n)
{
if(i > 0)
{
++negative_one_count;
}
}
else
{
return false;
}
}
}

return (nmod8 != 1 || negative_one_count > 0);
}

template<class Integer, class PrimeContainer, class Container>
void IntervalSieve<Integer, PrimeContainer, Container>::Psstestall() noexcept
{
for(std::size_t i {}; i < b_.size(); ++i)
{
if(b_[i])
{
if(!Psstest(i))
{
b_[i] = 0;
}
}
}
}

template<class Integer, class PrimeContainer, class Container>
IntervalSieve<Integer, PrimeContainer, Container>::IntervalSieve(const Integer left, const Integer right, const PrimeContainer &primes, Container &resultant_primes) noexcept :
left_ {left}, right_ {right}, primes_ {primes}
{
delta_ = right_ - left_;
b_.resize(static_cast<std::size_t>(delta_), 1);
Settdlimit();
Sieve();

if(plimit_ != 0 )
{
Psstestall();
}

WriteOutput(resultant_primes);
}

template<class Integer, class PrimeContainer, class Container>
void IntervalSieve<Integer, PrimeContainer, Container>::NewRange(const Integer left, const Integer right, Container &resultant_primes) noexcept
{
left_ = left;
right_ = right;
delta_ = right_ - left_;

b_.resize(static_cast<std::size_t>(delta_));
b_.set();
Settdlimit();
Sieve();

if(plimit_ != 0)
{
Psstestall();
}

WriteOutput(resultant_primes);
}
}

#endif // BOOST_MATH_SPECIAL_FUNCTIONS_INTERVAL_SIEVE_HPP
Loading