Two Algorithms to Find Primes in Patterns

07/23/2018 ∙ by Jonathan P. Sorenson, et al. ∙ Butler University 0

Let k> 1 be an integer, and let (f_1(x), ..., f_k(x) ) be k admissible linear polynomials over the integers. We present two algorithms that find all integers x where {f_i(x) }< n and all the f_i(x) are prime. Our first algorithm takes at most O(nk/( n)^k) arithmetic operations using O(k√(n)) space. Our second algorithm takes slightly more time, O(nk/( n)^k-1) arithmetic operations, but uses only O( n/ n) space. This result is unconditional for k>6; for 2<k< 6, the proof of its running time, but not the correctness of its output, relies on an unproven but reasonable conjecture due to Bach and Huelsbergen. We are unaware of any previous complexity results for this problem beyond the use of a prime sieve. We also implemented several parallel versions of our second algorithm to show it is viable in practice. In particular, we found some new Cunningham chains of length 15, and we found all quadruplet primes up to 10^17.



There are no comments yet.


page 1

page 2

page 3

page 4

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1. Introduction

Mathematicians have long been interested in prime numbers and how they appear in patterns. (See, for example, [12, ch. A].) In this paper, we are interested in the complexity of the following algorithmic problem:

Given a pattern and a bound , find all primes that fit the pattern.

To address this, first we will discuss and define a pattern of primes, then we will look at what is known about the distribution of primes in patterns to see what we can reasonably expect for the complexity of this problem, and finally we will discuss previous work and state our new results.

1.1. Prime Patterns

Perhaps the simplest of patterns of primes are the twin primes, which satisfy the pattern where both and are prime. Examples include 59,61 and 101,103.

We can, of course, generalize this to larger patterns. For example, prime quadruplets have the form , and examples include 11,13,17,19 and 1481,1483,1487,1489.

Larger patterns of primes are called prime -tuples. If the -tuple has the smallest possible difference between its first and last primes (its diameter), it is also called a prime constellation. The pattern is a constellation, as is the smallest possible diameter for a pattern of length 4. There are two constellations of length 3: and . See, for example, [7, §1.2.2] or [24, ch. 3].

Sophie Germain studied the pattern , which was later generalized to Cunningham chains of two kinds. Chains of the first kind have the pattern , and chains of the second kind have the pattern .

Chernick [6] showed that any prime pattern of the form gives a Carmichael number composed of the product of these three primes.

Let be an integer. A prime pattern of size is a list of linear polynomials over the integers with positive leading coefficients, . A pattern of size is admissible if for every prime , there is an integer such that does not divide any of the .

We restrict our notion of pattern to linear polynomials in this paper.

1.2. The Distribution of Primes in Patterns

The unproven twin prime conjecture states there are infinitely many twin primes. Yitang Zhang [31] recently showed that there is a positive integer such that the pattern is satisfied by infinitely many primes.

The Hardy-Littlewood -tuple conjecture [14] implies that each pattern, with leading coefficients of 1, that is admissible, will be satisfied by primes infinitely often. Further, the conjecture implies that the number of primes in such a pattern of length is roughly proportional to .

For twin primes, then, the Hardy-Littlewood conjecture gives an estimate of

for the number of twin primes , where is the twin primes constant. Brun’s theorem gives an upper bound for the number of twin primes . For each , there is a corresponding conjectured constant of proportionality, generalizing the twin primes constant.

Dickson’s conjecture [8] states that there are infinitely many primes satisfying any fixed admissible pattern, even with leading coefficients . Thus, it applies to fixed-length Cunningham chains as well.

We have the following upper bound, due to Halberstam and Richert [13, Theorem 2.4].

Lemma 1.

Given an admissible pattern of length , the number of integers such that the are all simultaneously prime and is .

Here the implied constant of the big- can depend on , but does not depend on the coefficients of the .

1.3. Previous Work

We can obtain a rather straightforward analysis by simply finding all primes , and then scanning to see how many tuples match the pattern. Since the scan phase is fast, the bottleneck would be finding the primes using a sieve. The Atkin-Bernstein sieve [2] does this using at most arithmetic operations and space. Galway [10] showed how to reduce space further to roughly , but this version could not use the wheel data structure and requires arithmetic operations.

We follow the convention of not charging for space used by the output of the algorithm.

A more specialized algorithm that searches for only the primes in the pattern, and not all the primes, should do much better. Günter Löh [19] and Tony Forbes [9] described algorithms to do exactly this, but gave no runtime analysis. It seems likely their algorithms are faster than , but without an analysis, we don’t know if this is true or not. Note that Forbes outlined an odometer-like data structure that is similar to the wheel data structure we employ.

Of course, by the prime number theorem, there are only about primes , so the current best prime sieves use arithmetic operations per prime on average. We do not know if anything smaller is possible. Applying this average cost to the results of Lemma 1, we can hope for an algorithm that takes arithmetic operations to find all primes in a fixed pattern of length .

In essence, this is what we prove as our main result.

1.4. New Results

Our contribution is the following.

Theorem 1.

There is an algorithm that, when given a list of distinct linear polynomials over the integers, with positive leading coefficients, (the pattern), and a search bound , finds all integers such that and all the are prime. This algorithm uses at most arithmetic operations and bits of space.

This algorithm extends the Atkin-Bernstein prime sieve with our space-saving wheel sieve. See [27, 28, 29].

The space needed by this algorithm limits its practicality. By replacing the Atkin-Bernstein sieve with the sieve of Eratosthenes combined with prime tests, we can greatly reduce the need for space.

Theorem 2.

There is an algorithm that, when given a list of distinct linear polynomials over the integers, with positive leading coefficients, (the pattern), and a search bound , finds all integers such that and all the are prime. This algorithm uses at most arithmetic operations and bits of space.

This second version requires to be unconditional. We use the sieve of Eratosthenes with primes up to a bound , after which we apply a base-2 pseudoprime test and then a version of the AKS prime test [1] that was improved to take time [18]. The algorithm works for , but to keep the cost of prime testing low enough, we replace the AKS prime test with the the pseudosquares prime test of Lukes, Patterson, and Williams [20]. This prime test takes only time under the condition of an unproven but reasonable conjecture on the distribution of pseudosquares due to Bach and Huelsbergen [3]. Note that correctness does not rely on any unproven conjectures.

The pseudosquare is the smallest positive integer that is not a square,

, and is a quadratic residue modulo every odd prime


Conjecture 1 (Bach and Huelsbergen [3]).

Let be the largest pseudosquare . Then .

Theorem 3.

There is an algorithm that, given a list of distinct linear polynomials over the integers, with positive leading coefficients, (the pattern), and a search bound , finds all integers such that and all the are prime. If Conjecture 1 is true, this algorithm uses at most arithmetic operations and bits of space.

We performed a few computations with this last version of our algorithm to show its practicality. A couple of these computational results are new.

The rest of this paper is organized as follows. In §2 we present our proof of Theorem 1, including our model of computation in §2.1, a description of our first algorithm in §2.2, and its running time analysis in §2.3. In §3 we discuss our second algorithm in §3.1, and its analysis in §3.2, thereby proving Theorems 2 and 3. We present our computational results in §4, including our work on twin primes in §4.1, our work on prime quadruplets in §4.2, and our results on Cunningham chains in §4.3. We wrap up with a discussion of possible future work in §5.

2. Theory

2.1. Model of Computation

Our model of computation is a standard random access machine with infinite, direct-access memory. Memory can be addressed at the bit level or at the word level, and the word size is bits, if is the input. Arithmetic operations on integers of bits take constant time, as do memory/array accesses, comparisons, and other basic operations.

We count space used in bits, and we do not include the size of the output.

2.2. Our First Algorithm

In this section we present the version of our algorithm with the smallest running time; we perform the analysis in the next section.

The input to the algorithm is the search bound and the pattern, which consists of the value of and the list of linear polynomials . We write for the multiplier and for the offset for each form . For simplicity, we often assume that and , but this convenience is not required to obtain our complexity bound. So for example, for Cunningham chains of the first kind we would have and .

  1. We begin by finding the list of primes up to and choosing a subset to be the wheel primes . Define . Generally, we put all primes up to a bound into , with maximal such that that . Then by the prime number theorem [15] we have

    This implies .

    In practice, if there is a prime that provides poor filtering for the pattern, we consider dropping it from and increasing to include another prime.

    We must also check all primes to see if they participate in a prime pattern.

  2. Next, we construct the wheel data structure so that it will generate all acceptable residues modulo .

    The data structure is initialized with a list of pairwise coprime moduli, and for each such modulus , a list of acceptable residues mod

    , encoded as a bit vector of length

    . The wheel modulus is then the product of these moduli. Once initialized, the wheel has the ability to enumerate suitable residues modulo in amortized constant time per residue. The residues do not appear in any particular order.

    Therefore, for each prime we compute a bit vector (ones[]) that encodes the list of acceptable residues. For any integral , we want to not be divisible by . So if divides , or equivalently if does not divide and so , then bit position must be a zero.

    vector<bool> ones(); // length , all s to start
    for(; ; )
                  ones[ (-) ];

    Continuing the example above, for Cunningham chains of the first kind, gives the vector 001, and gives the vector 0010111.

    We then construct the wheel data structure as described in [27, §4].

  3. For each residue generated by the wheel, we sieve arithmetic progressions for primes up to , , or for . We do this using the Atkin-Bernstein sieve. (See [2, §5] for how to use the sieve to find primes in an arithmetic progression.)

    For each , this yields bit vectors of length which are combined using a bitwise AND operation to obtain the bit positions for where the pattern is satisfied by primes.


Let us find the prime quadruplets (, ) up to using a wheel of size .

We generate just the one quadruplet that contains wheel primes.

The only acceptable residue mod is , for it is (if then is divisible by ), giving , and for it is , giving . For there are three acceptable residues, , giving us by the Chinese remainder theorem.

For , we sieve the progression for primes, getting the bit vector 10110; 11, 431, and 641 are prime, 221 and 851 are not. We then sieve for primes, getting 11111; they are all prime. Sieving gives 11011, and gives 11101.

Bitwise AND-ing these four vectors together gives 10000. The only quadruplet we find is .

Doing the same for , we get the following,

which gives us the quadruplet .

Finally for we get

and we get two quadruplets, and .

2.3. Complexity Analysis

We’ll look at the cost for each step of the algorithm above.

  1. We can use the Atkin-Bernstein sieve to find the primes up to in arithmetic operations using space.

  2. Recall that the largest wheel prime is roughly . Constructing the bit vector ones[] for one prime takes time to initially write all ones, and then time to mark the zeros. Summing over all wheel primes gives operations.

    From [27, Theorem 4.1] the total cost to build the wheel is operations and it occupies space.

  3. The Atkin-Bernstein sieve finds all primes in an arithmetic progression in an interval of size or larger in time linear in the length of the interval using space proportional to [2, §5]. Therefore, sieving for primes takes operations for each of the residue classes , for a total of . The cost to generate each value of using the wheel is negligible in comparison. The space used is bits.

    Next we show that the total number of residues is roughly asymptotic to . For a pattern of size , all but finitely many primes will have possible residues. Let be a constant, depending on the pattern , such that all primes larger than have residues. Then the total number of residues will be asymptotically bounded by

    By Bernoulli’s inequality we have , so that

    The first product is bounded by a constant that depends on . If , then by [25, (3.26)] we know that

    As shown above, if is the largest prime in , we have . Asymptotically, is a very safe underestimate. Pulling this all together, we obtain the bound

    for the total number of residues .

    Multiplying the sieving cost by the number of residues gives operations.

We have proved Theorem 1.

It is possible to pin down the implied constant that depends on (and ). We can use [25, (3.30)] and, assuming (note that ), we have

Bringing in the factor of introduced in the sieving, an upper bound for the implied constant is

It remains to get a bound for . Set , an upper bound on all the coefficients in the pattern. Set . For a prime , if has repeated roots modulo , then . But then for some with , which means divides , and hence . Thus , and we have the bound

for the implied constant. For specific patterns, the constant can be computed explicitly, typically giving much better results than this. In particular, we assumed every prime contributed all its residues (which happens if a prime divides all the s), which is unusual.

As an example, for our pattern , we have , and our constant would be

Here the and multipliers are included because and have only one residue each, instead of and respectively.

Note that one of the anonymous referees deserves the primary credit for this bound.

3. Practice

The primary difficulty in reaching large values of with our first algorithm is the amount of space it requires. One way to address this is to create a larger wheel, sieve more but shorter arithmetic progressions for primes, and rely less on sieving and more on primality tests (in the style of [27]) when searching for -tuples.

We use the sieve of Eratosthenes instead of the Atkin-Bernstein sieve for the arithmetic progressions, and this is the source of the factor slowdown. The gain here is less space needed by a factor of , and the effective trial division performs a quantifiable filtering out of non-primes.

Instead of sieving by all primes up to , we sieve only by primes up to a bound . In practice, we choose so everything fits in CPU cache. We then use a base-2 pseudoprime test, followed by a prime test. For smaller , we use the pseudosquares prime test of Lukes, Patterson, and Williams [20], which is fast and deterministic, assuming a sufficient table of pseudosquares is available, and importantly it takes advantage of the trial division effect of the sieve of Eratosthenes. For larger , we can simply use the AKS prime test [1].

This change means we can get by with only space. Choosing larger or smaller through its implied constant makes a tradeoff between the cost of sieving and the cost of performing base-2 pseudoprime tests.

3.1. Our Second Algorithm

  1. Choose (this can be for a small positive constant ). We begin by finding the list of primes up to and dividing them into the two sets and . Small primes go into and the remainder go in . We want to be as large as possible with the constraint that . This implies that the largest prime in will be roughly .

  2. If , we will need to perform the pseudosquares prime test, so in preparation, find all pseudosquares (see [20]).

  3. Next, as before, we construct the wheel data structure so that it will generate all possible correct residues modulo .

  4. For each residue generated by the wheel, we construct a bit vector v[] of length . Each vector position v[], for , represents the value for the -tuple . We initialize v[], but clear it to if we find a prime where for some .

    for( )
    for(; ; )

    Once this sieving is complete, the only integers with v[] that remain, satisfy the property that all the have no prime divisors less than .

  5. For each such remaining (that is, v[]), we first do a base-2 strong pseudoprime test on . If it fails, we cross it off (set v[]). If it passes, we try and so forth, keeping v[] only if all values pass the pseudoprime test. We then perform a full prime test on the for all . If , we use the Lukes, Patterson, and Williams pseudosquares prime test [20] as done in [27]. For larger , we use the AKS prime test [1]. (This is for the purposes of the theorem; in practice, the pseudosquares prime test is faster, so we use that instead.) If all the pass the prime tests, the corresponding -tuple is written for output.

This version of the algorithm works best for . When , the prime tests become the runtime bottleneck, and so we recommend using so that the base-2 pseudoprime tests and the pseudosquares prime test are not needed, as the sieving will leave only primes.


We use the same example as above, finding prime quadruplets up to , which uses the pattern . We go a bit higher this time to illustrate the sieving. Recall our wheel uses the primes , and generates the three residues modulo .

We will use as our sieve bound, so . Like with the wheel primes, quadruplets that include sieve primes must be generated separately, so we output the quadruplet at this point.

For , we have our progression

For , we cross off integers that are modulo . This takes four passes: on the first pass we remove , which are ; on the second pass we remove , which are (for example ); the third removes , which are ; and the fourth removes , which are . Observe that for a given residue modulo , the numbers to cross off are exactly spaces apart.

For , we cross off integers that are modulo . We remove for , for , for , and for .

For , we cross off integers that are modulo . We remove for , for , for , and for .

For , we cross off integers that are modulo . We remove for , for , for , and for .

At this point we perform base-2 strong pseudoprime tests, followed by prime tests as needed. Here 851 and 3161 are not prime, and 1481 leads to the quadruplet .

This is then repeated with .

3.2. Complexity Analysis

Finding the primes up to takes time using space, well within our bounds. See [27] for a sublinear time algorithm to find all needed pseudosquares. In practice, all pseudosquares up to are known [28]. The cost in time and space to build the wheel is, up to a constant factor, the same. So we now focus on steps (4) and (5).

As shown above, the number of residues to check is . The time to sieve each interval of length using primes up to is at most proportional to

Here the multiplier is required because we cross off residues modulo all but finitely many primes . That said, this multiple of is absorbed into the implied constant that depends on the pattern .

By Mertens’s theorem, at this point an average of at most

vector locations remain to be prime tested. (Note that we cannot make any assumptions about the relative independence of the primality of the values for different , and so we cannot use a factor here.) A single base-2 strong pseudoprime test takes operations to perform, for a total cost proportional to

arithmetic operations to do the base-2 strong pseudoprime tests for each value of . This matches the sieving cost of from above. (Note that if we deliberately choose a larger value for , the increased sieving will decrease the number of pseudoprime tests needed. This tradeoff can be used to fine-tune the running time of the algorithm.)

Thus, the total cost for sieving and base-2 pseudoprime tests is

which we obtain by multiplying by the number of residues .

Next we need to count integers that pass the base-2 strong pseudoprime test. Such integers are either prime, or composite base-2 pseudoprimes. We switch to counting across all residues to obtain an overall bound.

Lemma 1 tells us that at most integers are prime that fit the pattern, so this is an upper bound on primes that pass the base-2 pseudoprime test.

Pomerance [23] showed that the number of composite base-2 pseudoprimes is bounded by

which is negligible. This plus the bound for primes above gives us the bound we desire for all integers that pass the base-2 pseudoprime test.

Next, to bound the cost of prime tests, we have two cases: , or .

For , we use the AKS prime test [1] (improved in [18]) which takes time . The cost of applying the AKS prime test to all the integers after they all pass a base-2 pseudoprime test is at most proportional to

which is for .

Note that when is large, in practice we might only do the base-2 pseudoprime tests, and then run full prime tests on the output afterwards, since the amount of output will be rather small.

For , Conjecture 1 implies that the pseudosquares prime test takes arithmetic operations to test integers for primality, given a table of pseudosquares . If has no prime divisors below , then pseudosquares up to suffice. See [20, 27].

So, under the assumption of Conjecture 1, the cost of applying the pseudosquares prime test to all the integers after they all pass a base-2 pseudoprime test is at most proportional to

and this is for .

The space used is dominated by the length of the sieve intervals and the space needed to store the primes in , which is bits.

This completes the proof of Theorems 2 and 3.

4. Computations

As mentioned previously, we implemented several versions of our second algorithm to see what we could compute. We looked for new computational records that were within reach of our university’s nice but aging hardware. Below we discuss some of the results of those computations. Some of the implementation details are specific to a particular computation. Here are four remarks about implementation details that these computations had in common.

  1. We wrote our programs in C++ using the GNU compiler under Linux. GMP was used for multiprecision arithmetic when necessary. Note that it is fairly easy to write the code such that GMP was needed only on occasion and for prime tests.

  2. We used MPI and ran our code on Butler University’s cluster Big Dawg. This machine has 16 compute nodes with 12 cores (2 CPUS) each at optimal capacity; our average utilization was around 150 of the 192 cores due to compute nodes going down from time to time. The CPU is the Intel Xeon CPU E5-2630 0 @ 2.30GHz with 15 MB cache, with 6 cores per CPU.

    To parallelize the algorithm, we striped on the residues . In other words, all processors stepped through all the residues, but only sieved every th residue for primes. This meant there was very little communication overhead except for when periodic checkpoints were done, about every 15-30 minutes.

  3. We usually chose our wheel size () and sieve intervals so that the size of each interval () was at most a few megabytes so that it would fit in the CPU cache. We used a vector<bool>, which packs bits.

  4. For larger values of , we observed that when sieving by smaller primes by each of the residues, we might find that almost all the bits of the current interval were cleared long before we reached the sieving limit , so we created a simple early-abort strategy that was able to save time.

    The very few remaining bits were tested with the base-2 strong pseudoprime test even though we had not sieved all the way to . We also, then, replaced the use of the pseudosquares prime test with strong pseudoprime tests [21] using results from [29] so that only a few bases were needed, due to the spotty trial-division information.

4.1. Twin Primes and Brun’s Constant

Let count the twin prime pairs with and be the sum of the reciprocals of their elements. Thomas Nicely computed these functions up to (See We verified his computations to 14 digits and extended the results to . A portion of our computational results are in the table below.

10304195697298 1.8304844246583
19831847025792 1.8318080634324
29096690339843 1.8325599218628
38196843833352 1.8330837014776
47177404870103 1.8334845790134
56064358236032 1.8338086822020
64874581322443 1.8340803303554
73619911145552 1.8343139034256
82309090712061 1.8345186031523
90948839353159 1.8347006694414

The last section of Klyve’s PhD Thesis [17] describes how to use this information to derive bounds for Brun’s constant.

We have four remarks on our algorithm implementation:

  1. As mentioned above, for small like , it is more efficient to set so that sieving also determines primality, thereby avoiding base-2 strong pseudoprime tests and primality tests.

  2. We computed using Kahan summation [16] with the long double data type in C++, which gave us 17 digits, 14 of which were accurate; Thomas Nicely has data with 53 digits of accuracy. The partial sums were accumulated in 10,000 buckets for each process, and then the buckets were in turn added up across processes using Kahan summation.

  3. Our computation took roughly 3 weeks of wall time, which included at least one restart from a checkpoint. Our verification of Nicely’s work to took 42 hours.

  4. We used a wheel with . Note that this is roughly . There were residues to sieve.

See sequence A007508, the number of twin prime pairs below .

4.2. Quadruple Primes

A related sum involves the reciprocals of the elements of the prime tuple . Let count these tuplets up to , and let be the sum of the reciprocals of their elements. Thomas Nicely computed these functions up to . We extended this computation and partial results are in the table below. The first two lines are Thomas Nicely’s own results, which we verified.

25379433651 0.8704776912340
46998268431 0.8704837109481
67439513530 0.8704870310432
87160212807 0.8704893020026
106365371168 0.8704910169467
125172360474 0.8704923889088
143655957845 0.8704935288452
161868188061 0.8704945017556
179847459283 0.8704953489172
197622677481 0.8704960981105

This computation took about 4 days, and we used a separate program rather than looking for pairs of twin primes in the first program. Even though is large enough to use prime tests, we found that sieving to was faster in practice.

We used a wheel with , which gave residues.

See sequence A050258, the number of prime quadruples with largest member .

4.3. Cunningham Chains

We have two new computational results for Cunningham chains.

  1. We found the smallest chain of length 15 of the first kind, and it begins with the prime

    The next four chains of this length of the first kind begin with

    This computation took roughly a month of wall time. Here we used wheel size , with residues to sieve. Note that is a rather badly behaved prime for larger Cunningham chains (only residues are excluded), so we left it out of the wheel.

    See sequence A005602, smallest prime beginning a Cunningham chain of length (of the first kind).

  2. In 2008 Jaroslaw Wroblewski found a Cunningham chain of length 17 of the first kind, starting with

    and we were able to show that this is in fact the smallest such chain of that length.

    This computation took roughly three months of wall time. We used , with residues to sieve. With roughly three times as many residues as the previous computation, it took roughly three times as long to complete.

5. Discussion and Future Work

In summary, we have described and analyzed two algorithms for finding primes in patterns, and then shown that the second of these algorithms is quite practical by performing a few computations.

We have some ideas for future work.

  1. In the Introduction, we mentioned that our algorithms could be used to find Charmichael numbers by finding prime triplets that satisfy the pattern , but we have not yet done that computation [6].

  2. Does it make sense to use Bernstein’s doubly-focused enumeration to attempt to further reduce the running time? See [5, 28, 30]

  3. A natural extension to our algorithms here is to allow the linear polynomials to potentially be higher degree, irreducible polynomials. See Schinzel’s Hypothesis H (See [26] and [7, §1.2.2]) and the Bateman-Horn conjecture [4].


We wish to thank Frank Levinson for his generous gift that funds the Butler cluster supercomputer Big Dawg, and the Holcomb Awards Committee for their financial support of this work.

Thanks to Thomàs Oliveira e Silva for several helpful comments on an earlier version of this paper.

We also wish to thank two anonymous referees for many detailed, helpful comments on earlier versions of this paper. In particular, one of the referees contributed the analysis of the implied constant in §2.3.

A preliminary version of this work was presented as a poster at the ANTS XIII conference in Madison, Wisconsin in July of 2018.


  • [1] Manindra Agrawal, Neeraj Kayal, and Nitin Saxena. PRIMES is in P. Ann. of Math. (2), 160(2):781–793, 2004.
  • [2] A. O. L. Atkin and D. J. Bernstein. Prime sieves using binary quadratic forms. Mathematics of Computation, 73:1023–1030, 2004.
  • [3] Eric Bach and Lorenz Huelsbergen. Statistical evidence for small generating sets. Math. Comp., 61(203):69–82, 1993.
  • [4] Paul T. Bateman and Roger A. Horn.

    A heuristic asymptotic formula concerning the distribution of prime numbers.

    Math. Comp., 16:363–367, 1962.
  • [5] Daniel J. Bernstein. Doubly focused enumeration of locally square polynomial values. In High primes and misdemeanours: lectures in honour of the 60th birthday of Hugh Cowie Williams, volume 41 of Fields Inst. Commun., pages 69–76. Amer. Math. Soc., Providence, RI, 2004.
  • [6] Jack Chernick. On Fermat’s simple theorem. Bull. Amer. Math. Soc., 45(4):269–274, 1939.
  • [7] R. Crandall and C. Pomerance. Prime Numbers, a Computational Perspective. Springer, 2001.
  • [8] L. E. Dickson. A new extension of Dirichlet’s theorem on prime numbers. Messenger of mathematics, 33:155––161, 1904.
  • [9] Tony Forbes. Prime clusters and Cunningham chains. Math. Comp., 68(228):1739–1747, 1999.
  • [10] William F. Galway. Dissecting a sieve to cut its need for space. In Algorithmic number theory (Leiden, 2000), volume 1838 of Lecture Notes in Comput. Sci., pages 297–312. Springer, Berlin, 2000.
  • [11] Daniel M. Gordon and Gene Rodemich. Dense admissible sets. In Algorithmic number theory (Portland, OR, 1998), volume 1423 of Lecture Notes in Comput. Sci., pages 216–225. Springer, Berlin, 1998.
  • [12] Richard K. Guy. Unsolved problems in number theory. Problem Books in Mathematics. Springer-Verlag, New York, third edition, 2004.
  • [13] H. Halberstam and H.-E. Richert. Sieve Methods. Academic Press, 1974.
  • [14] G. H. Hardy and J. E. Littlewood. Some problems of ‘partitio numerorum’; iii: On the expression of a number as a sum of primes. Acta Mathematica, 44(1):1–70, Dec 1923.
  • [15] G. H. Hardy and E. M. Wright. An Introduction to the Theory of Numbers. Oxford University Press, 5th edition, 1979.
  • [16] W. Kahan. Pracniques: Further remarks on reducing truncation errors. Commun. ACM, 8(1):40–, January 1965.
  • [17] Dominic Klyve. Explicit Bounds on Twin Primes and Brun’s Constant. PhD in mathematics, Dartmouth College, Hanover, NH USA, 2007.
  • [18] H. W. Lenstra, Jr. and Carl Pomerance. Primality testing with ”gaussian” periods. In M. Agrawal and A. Seth, editors, Proceedings of the 22nd Conference on Foundations of Software Technology and Theoretical Computer Science, FST TCS ’02, Berlin, Heidelberg, 2002. Springer-Verlag. LNCS 2556.
  • [19] Günter Löh. Long chains of nearly doubled primes. Math. Comp., 53(188):751–759, 1989.
  • [20] R. F. Lukes, C. D. Patterson, and H. C. Williams. Some results on pseudosquares. Math. Comp., 65(213):361–372, S25–S27, 1996.
  • [21] G. Miller. Riemann’s hypothesis and tests for primality. Journal of Computer and System Sciences, 13:300–317, 1976.
  • [22] T. Nicely. Enumeration to of the twin primes and Brun’s constant. Virginia J. Sci., 46:195–204, 1996.
  • [23] Carl Pomerance. On the distribution of pseudoprimes. Math. Comp., 37(156):587–593, 1981.
  • [24] Hans Riesel. Prime Numbers and Computer Methods for Factorization, volume 126 of Progress in Mathematics. Birkhäuser, 2nd edition, 1994.
  • [25] J. B. Rosser and L. Schoenfeld. Approximate formulas for some functions of prime numbers. Illinois Journal of Mathematics, 6:64–94, 1962.
  • [26] A. Schinzel and W. Sierpiński. Sur certaines hypothèses concernant les nombres premiers. Acta Arith., 4:185–208, 1958. Erratum 5 (1958), 259.
  • [27] Jonathan P. Sorenson. The pseudosquares prime sieve. In Florian Hess, Sebastian Pauli, and Michael Pohst, editors, Proceedings of the 7th International Symposium on Algorithmic Number Theory (ANTS-VII), pages 193–207, Berlin, Germany, July 2006. Springer. LNCS 4076, ISBN 3-540-36075-1.
  • [28] Jonathan P. Sorenson. Sieving for pseudosquares and pseudocubes in parallel using doubly-focused enumeration and wheel datastructures. In Guillaume Hanrot, Francois Morain, and Emmanuel Thomé, editors, Proceedings of the 9th International Symposium on Algorithmic Number Theory (ANTS-IX), pages 331–339, Nancy, France, July 2010. Springer. LNCS 6197, ISBN 978-3-642-14517-9.
  • [29] Jonathan P. Sorenson and Jonathan Webster. Strong pseudoprimes to twelve prime bases. Math. Comp., 86(304):985–1003, 2017.
  • [30] Kjell Wooding and H. C. Williams. Doubly-focused enumeration of pseudosquares and pseudocubes. In Proceedings of the 7th International Algorithmic Number Theory Symposium (ANTS VII), Berlin, Germany, 2006.
  • [31] Yitang Zhang. Bounded gaps between primes. Ann. of Math. (2), 179(3):1121–1174, 2014.