Primality test and primes enumeration using odd numbers indexation

Odd numbers can be indexed by the map k(n)=(n-3)/2, n belonging to 2N+3. We first propose a basic primality test using this index function that was first introduced in article (8). Input size of operations is reduced which improves computational time by a constant. We then apply similar techniques to Atkin prime-numbers sieve which uses modulus operations and finally to Pritchard wheel sieve, in both case yielding similar results.


Primality test and prime enumeration
An odd number is prime when it is not divisble by any prime lower than or equal to √ . This basic primality test requires too much computational time for large integers. Faster and more efficient deterministic and probabilistic primality tests have been designed for large numbers [1]. A deterministic polynomial primality test was proposed by M. Agrawal, N. Kayal and N. Saxena in 2002 [2].
Enumeration of primes up to a given limit can be done by using a primality test but prime number sieves are preferred from a performance point of view. A sieve is a type of fast algorithm to find all primes up to a given number. There exists many such algorithms, from the simple Erastosthenes' sieve (invented more than 2000 years ago), to the wheel sieves of Paul Pritchard ([3], [4], [5]) and the sieve of Atkin [6]. In [7], Gabriel Paillard, Felipe Franca and Christian Lavault present another version of the wheel sieve and give an overview of all the existing prime-numbers sieves.
In theory, indices are a way to represent odd numbers. By adapting results from [8], we show how odd number indices may be used in applied mathematics. In the last part, we apply [8] to Pritchard's wheel sieve, which leads to a wheel sieve. Using the linear diophantine equation resolution method first introduced in [9], we introduce an original way of "turning the wheel".

Notation
We will use the following notations:  [8] shows that is the union of two families of finite sequences with arithmetic difference. Actually proposition 2-5 says that any composite odd number ∈ can be written as a difference of two squares, and more precisely that there exists ∈ ℕ and ∈ ⟦0, ⟧ such that: 1 = { ( ) = ( + 1) + 2(2 + 3) ; ∈ ℕ, ∈ ℕ} 2 = { ( ) = ( + 2) + 2(2 + 3) ; ∈ ℕ, ∈ ℕ} Thus is the union of two families of infinite arithmetic sequences. The indices ( + 1) of first type reference points (or remarkable points, see [8]) are the initial terms of sequences ranging in 1 . Similarly, the indices ( + 2) of second type reference points are the initial terms of sequences ranging in 2 .

Basic primality test
In this section, we describe a basic primality test using the previous infinite sequences. Proposition 2-2: ∈ 1 is a prime number when: ( , ) 4 mod ≠ 0 ∈ 2 is a prime number when: Proof: This follows from the fact that ( , ) mod = mod and likewise for ( , ).

Remark 2-2:
In order to reduce computation of ( , ) and ( , ) for two consecutive prime numbers, we only decrement the value.
More precisely, if < ′ are two primes, we let ( , ′ ) = ′ − and we compute: These two expressions are independent of .

Primality test with indices
We adapt here the results of the previous section with indices.

First algorithms of prime enumeration
In this section, we present prime enumeration algorithms based on propostion 2-2 and 2-3. The first one manipulates numbers and the second one indices.

Primality test using numbers
This first algorithm named PrimeEnumeration consists in two functions: ➢ The main function which determines primes in up to and returns them in a list, along with its size. ➢ An auxiliary function which returns whether a number is prime, based on precomputed list of primes and values of Δ and Δ . It is called LocalTest. It is also in charge of updating the lists Δ and Δ if needed.
Three zero-based lists are used and built recursively in this algorithm: the list of primes itself , and the lists of values for Δ and Δ respective to (remember it is independent from ). Only numbers which are not multiples of 2 and 3 are tested. Thus we restrict to = 6 + 1 and = 6 + 5. The congruence of modulo 4 depends on the parity of , i.e. when is even, mod 4 = 1 and when is odd, mod 4 = 3.

Primality test using infinite sequences and indices
This second algorithm IndexPrimeEnumeration also consists in two functions, mirroring the previous algorithm: ➢ The main function which determines primes up to and returns them in a list along with its size. ➢ An auxiliary function which returns whether a number is prime based on precomputed list of primes and values of Δ ′ and Δ ′ . It is called LocalTest. Four zero-based lists are used and built recursively: the list of primes , the corresponding indices (indices of primes), and the lists Δ ′ and Δ ′ respective to .
Only numbers which are not multiple of 2 and 3 are tested, i.e. indices of the form = 3 − 1 and = 3 + 1.

Algorithm 2-4-2a Function IndexPrimeEnumeration( ):
is an odd integer such that ≥ 7. This function returns the list of primes up to and its size.

End If
← + 1 → We do not use but keep it for the sake of readability

End While
Return ({2,3} + , + 2) → Return the list of primes and the number of primes.

If
Do → initiate references that might be updated

End If
If > Do → update references because we always want ≤

End While
Return True → Test is positive

Perfomance of the algorithms
In this section, we present the performance of the previous two algorithms of prime enumeration. We first give a theoretical complexity, followed by empirical results. Time complexity is: Space complexity is: Proof: Any number 's primality is tested with primes in ⟦5, √ ⟧, in (1)  The space complexity is related to the lists we keep in memory, which are at most of size ( ).
This space complexity is ( √ ln( ) ). On the graph 2-5 below, we represent the computation time in seconds for both algorithms. Curve 1 corresponds to the algorithm PrimeEnumeration and curve 2 to IndexPrimeEnumeration. The correlation coefficient R of each curve is given on the graph. We observe that computation time of both algorithms is consistent with theoretical complexity, although exponent is a bit smaller than 1.5. Both algorithms PrimeEnumeration and IndexPrimeEnumeration have the same number of modulo operations. But the computation of the input of modulus operations is done with larger inputs for the former than for the latter, which allows to marginally save time for large values of .

The sieve of Atkin
The sieve of Atkin [6] is a modern and efficient algorithm for primes enumeration. We present two algorithms based on it, one using numbers and the other indices. Both are based on the version which has a complexity ( ) in time and space. Modified versions achieve up to ( ln ln( ) ) in time and (   1  2 + (1) ) in space.

Atkin algorithm
This algorithm is based on the following three results from [6].
Proposition 3-1 Let > 3 be a square-free integer. Then is prime if and only if one of the three following conditions is true: a. ∈ 1 + 4ℕ and there is an odd number of solutions to = 4 2 + 2 , ( , ) ∈ ℕ 2 , b.
We observe that the first congruence condition on can also be replaced by ∈ 1 + 12ℕ or ∈ 5 + 12ℕ. We also observe the following for an odd integer : • If = 4 2 + 2 , must be odd.
Remark 3-1 We can compute the remainder modulo 12 of 2 + 2 depending on remainders modulo 12 of and . This gives us the different cases to check in Atkin sieve. We present them in table 3-1, noting that there is no case for mod 12 = 0 and mod 12 = 6. We could run the sieve looping through 12x12 blocks of ( , ) according to this table, but for readability we do not implement this optimization in the algorithms below. We note however that this would save all the modulo operations.

Algorithm 3-1 SieveOfAtkin( ):
> 3 is an integer. This function returns the list of all prime numbers less than .

Atkin algorithm with indices
We can rewrite proposition 3-1 as: The relationships presented in the following remark are used in the next algorithm.

Algorithm 3-2 IndexSieveOfAtkin( ):
> 3 is an odd integer. This function returns the list of all prime numbers less than .

Performance of algorithms
In this section, we discuss theoretical complexity and present our results with the two algorithms implementing the sieve of Atkin.
The reference algorithm SieveOfAtkin has less operations index-based IndexSieveOfAtkin, which juggles between numbers and indices. But on the other hand SieveOfAtkin performs Euclidian divisions by 12, whereas IndexSieveOfAtkin does divisions by 6. This is due to the conversion of number into its index = ( − 3) 2 ⁄ . Furthermore, the latter only performs the sieve on odd numbers, which means effectively the memory space for the sieve is twice smaller.
On the graph 3-3 below, we plot the computation time in seconds for both algorithms. The curve 3 corresponds to SieveOfAtkin and the curve 4 to IndexSieveOfAtkin. We observe empirically that computation time of both algorithms looks slightly higher than linear, even though theoretically the number of operations appears to be linear in . Details of the Maple options used to get the regression are given in appendix 8.2.

Graph 3-3: computation time ( ) in seconds for both algorithms (Sieve of Atkin)
The second algorithm is faster for larger values of , roughly for > 10 9 . For such values the cost of encoding numbers to indices is offset by the gain on modulo operations and halving the size of the sieve. We note also that memory size is halved for the second algorithm.

Wheel sieve with indices
We first describe Pritchard's wheel sieve. Then we adapt it to indices and discuss a way to generate the integers of the turning wheel.

Description of Pritchard's wheel sieve
This description is based on [7] and [4]. The wheel sieve operates by generating a set of numbers that are coprime with the first prime numbers. The second of these is the next prime, multiples of which are then eliminated (by turning the wheel).
More precisely, let 0 = 2, 1 = 3 … the sequence of prime numbers and let: The following proposition describes a "turn of the wheel". Furthermore, induction formula for can also be used to recursively build the sequence of prime numbers:
Proof: The first element is 1, which is obviously not prime. For ≥ 1, ≥ 3 and from proposition 4-1-1 we can show (see corollary 4-2-2 later on) that has at least 2 elements. The second one must then be the smallest integer coprime with 0 … , and thus must be +1 .
The elements of are called pseudo-primes (at order ). Some of them are primes and others are not. However, we have a boundary condition to identify some of the primes: Proposition 4-1-3: All integers in and less than 2 are sure to be primes.
Proof: Any integer less than 2 is either prime or has a divisor among 0 … . The latter is impossible by definition of .
To enumerate primes up to , we thus have to keep turning the wheel as long as +1 2 < .
As Π grows exponentially (in particular it can be easily proven from Bertrand's postulate that Π > 2 from = 2), while we are only interested in pseudo-primes up to , we may replace in practice by = ∩ ⟦1, ⟧.
Thus, when we turn the wheel, we remove integers that are, for a given ∈ , and , integers, of the form: One way to do that is to remove all multiples of +1 . We will show however in section 4.2 that there is a relationship between the value of , the multiples of Π which are added to , and the composite numbers +1 which must be removed of the wheel +1 , so that the index to remove can be predicted from or conversely. We let ′ be the set of indices corresponding to , with 1 replaced by Π + 1 (which index is Π ′ − 1):

Index wheel sieve
In this section, we describe how we adapt the wheel sieve to work with indices of odd integers. The limit is supposed to be an odd integer of index .

Remark 4-2-1:
The first element of ′ is the index of the prime number +1 . ′ is included in Proof: Since we remapped 1 to Π + 1 in to define ′ , and because the indexing map is increasing, the first element of ′ is the index of prime +1 from proposition 4-1-2 (we note that it works even for = 0), and its last element is Π ′ − 1.

Proposition 4-2-1:
The index wheel sieve is the only sequence of sets verifying: Furthermore, indices in the wheel ′ up to correspond to all remaining prime numbers up to (on top of 0 … ) as soon as: If we let = 2 + 3, this corresponds to the definition of ( ′ , ) in [8]: ( ′ , ) = + (2 + 3) ′.
Proof: Because Π ′ and +1 are coprime, existence and unicity of the solution are well-known. In [9] we introduced the concept of normalizer of such a Diophantine equation, and have shown its additive and multiplicative property.
Furthermore, for all , by multiplicative property: This proposition gives us an effective way of building all couples ( , ) modulo +1 : start from ( 1 , 1) and add it to itself (modulo +1 ) up to +1 − 1 times (the last time we will get the couple (0,0 = 0 )).

Wheel sieve algorithms
As per sections 4.1 and 4.2, the wheel sieve algorithms will consist in two steps: (A) A first step where the wheel will always grow, as long as Π < , or: A second step where we will no longer grow the wheel, but will have to keep eliminating composite numbers, as long as 2 < , or: This is equivalent to saying that we replace +1 by +1 and similarly +1 ′ by +1 ′ . During step (B) we do not add new pseudo-primes, only remove those that we rule out as multiples of the next prime. Because Π grows exponentially, there will generally be more iterations in step (B) than in step (A).
Quick description of the steps of the index wheel sieve algorithm (see appendix for full algorithm): As for the previous algorithms, we note the list of primes and its number of elements. represents the list of indices of odd primes, and the list of indices of squared odd primes. At step , will contain all primes up to 2 , coming from the wheel ′ , and being filled with the corresponding indices.
Furthermore, if is another integer, the difference between the indices of 1 and 2 is:

= .
Proof: Note that 2 − 1 = 2 and thus: Similarly: This last remark is used in steps 2-b. and 3-b. to fill and to perform step 3-a.

Remark 4-3-2:
The index wheel sieve involves operations with reduced input size compared with the number version. This is clear from remark 4-3-1 where is exactly half of 2 2 − 1 2 , for instance.
Similarly Π ′ is half of Π so modulo operation input is also reduced.

Performance of algorithms
In this section, we present results from the previous algorithm of index wheel sieve, which we compare with a similar one on numbers (unspecified for to avoid a lengthy duplication). These results are similar to those obtained in the previous sections. As for the sieve of Atkin, we did not go for refinements that give a better time complexity, so theoretical complexity in terms of number of operations is ( ) for both algorithms.
On the graph 4-4 below, we plot the computation time in seconds for both algorithms, for up to 6.10 9 . The curve 5 corresponds to the the algorithm WheelSieveReference and the curve 6 corresponds to the the algorithm IndexWheelSieve. The correlation coefficient of each regression is given on the graph. Details of the Maple options used to get the regression are given in appendix 8.3. We notice that complexity of both algorithms again seems empirically slightly higher than linear.

Graph 4-4: computation time ( ) in seconds for both algorithms (Wheel sieve)
Complexity is reduced by using indices, due to reduction of input size in the modulo and the multiplication operations (see Remark 4-3-2) and despite a higher number of operations with the algorithm IndexWheelSieve. Moreover, the amount of memory space used with indices is halved, due to the fact that we avoid even numbers completely.

Conclusion
In theory, indices are a way to work with odd numbers only by not representing even numbers. Most mathematical relations must be reformulated for indices, which lead to a higher number of (conversion) operations, but in return the input size of other operations is reduced. In this article, we have shown how this indexing translates into optimized algorithms in applied mathematics. From a basic primality test implementation, to the sieve of Atkin and Pritchard's wheel sieve, indices speeded up these algorithms, not by changing their complexity but by reducing the time cost by a constant factor, and generally also made them more efficient from a memory point of view.

APPENDIX: ALGORITHM OF THE INDEX WHEEL SIEVE
This algorithm enumerates odd primes up to the limit . It is composed of a main function that is called IndexWheelSieve and the following auxilliary other functions: 7-2-DiophantineSolutions( ,Π ′ ) 7-3-WheelTurn( ′ , , , , Π ′ , ) 7-4-RemoveMultiples( , , ′ ) 7-5-GetNewPrimes( ′ , , , , , ) Some marginal optimizations can still be performed, for instance modulo operations inside a loop can be replaced by substractions, and memory can be managed better. For the sake of readability we leave these optimizations out of scope.