About
=====

This directory (src/primesieve) contains primesieve's sieve of
Eratosthenes implementation. Most files that start with a capital
letter contain a class of the same name. The header files of these
classes are stored in include/primesive. Below is a short explanation
of the most important classes and files.

C++ classes
-----------
* PrimeSieve
  PrimeSieve objects provide an easy API for prime sieving,
  PrimeSieve::sieve(start, stop) sieves the primes within the
  interval [start, stop]. The classes below are all used directly or
  indirectly for sieving.

* ParallelPrimeSieve (derived from PrimeSieve)
  ParallelPrimeSieve provides an easy API for multi-threaded prime
  sieving using OpenMP, it scales well even with 100 CPU cores! In
  ParallelPrimeSieve each OpenMP thread sieves primes using a thread
  private PrimeSieve object.

* SieveOfEratosthenes (abstract class)
  Implementation of the segmented sieve of Eratosthenes using a bit
  array with 30 numbers per byte, each byte of the sieve array holds
  the 8 offsets k = { 7, 11, 13, 17, 19, 23, 29, 31 }.
  Its main methods are addSievingPrime(uint_t) which must be called
  consecutively for all primes <= sqrt(n) in order to sieve the
  primes up to n and sieve(). SieveOfEratosthenes uses the
  EratSmall, EratMedium and EratBig classes to cross-off multiples.

* PrimeFinder (derived from SieveOfEratosthenes)
  Main SieveOfEratosthenes class: PrimeFinder is used to callback,
  print and count the primes and prime k-tuplets within the interval
  [start_, stop_] of the associated PrimeSieve object.

* PrimeGenerator (derived from SieveOfEratosthenes)
  Generates the primes up to sqrt(n) needed for sieving by the
  PrimeFinder class.

* PreSieve
  PreSieve objects are used to pre-sieve multiples of small primes
  e.g. <= 19 to speed up the sieve of Eratosthenes.

* WheelFactorization (abstract class)
  Wheel factorization is used to skip multiples of small primes e.g.
  <= 7 to speed up the sieve of Eratosthenes. The abstract
  WheelFactorization class is used to initialize sieving primes i.e.
  addSievingPrime() calculates the first multiple >= start of each
  sieving prime and the position within the SieveOfEratosthenes
  array of that multiple (multipleIndex). The unsetBit() method is
  used to cross-off a multiple (unset a bit) and to calculate the
  sieving prime's next multiple.

* EratSmall (derived from WheelFactorization)
  Segmented sieve of Eratosthenes algorithm with a hard-coded
  modulo 30 wheel that skips multiples of 2, 3 and 5. This algorithm
  is optimized for small sieving primes that have many multiples in
  each segment. EratSmall is a further optimized implementation of
  Achim Flammenkamp's algorithm.[9]

* EratMedium (derived from WheelFactorization)
  Segmented sieve of Eratosthenes algorithm with a fixed modulo 210
  wheel that skips multiples of 2, 3, 5 and 7. The wheel is
  implemented using a precomputed lookup table (wheel210 array from
  WheelFactorization.cpp). This algorithm is optimized for medium
  sieving primes with a few multiples per segment.

* EratBig (derived from WheelFactorization)
  Segmented sieve of Eratosthenes algorithm with Tomás Oliveira's
  improvement for big sieving primes [11] and a fixed modulo 210
  wheel that skips multiples of 2, 3, 5 and 7. The wheel is
  implemented using a precomputed lookup table (wheel210 array from
  WheelFactorization.cpp). EratBig is optimized for big sieving
  primes that have less than one multiple per segment.

* iterator
  The iterator class has been introduced in primesieve-5.0 and allows
  to easily iterate over primes. It provides next_prime() and
  previous_prime() methods.

Other files
-----------
* include/primesieve.hpp
  This header contains primesieve's new API first released in
  primesieve-5.0. It is mostly a wrapper around the methods of the
  PrimeSieve and ParallelPrimeSieve classes.

* primesieve-api.cpp
  This file contains the implementations of the functions declared
  in include/primesieve.hpp.

* include/primesieve/config.hpp
  Contains compile time constants that set the size of various
  arrays and limits within primesieve. You can set these constants
  according to your CPU type to get the best performance.

References
==========

[1] Richard C. Singleton, "An efficient prime number generator",
    Communications of the ACM 12, 563-564, 1969.
[2] R. P. Brent, "The first occurrence of large gaps between
    successive primes", Mathematics of Computation, 27:959-963,
    1973.
[3] C. Bays and R. Hudson, "The segmented sieve of Eratosthenes and
    primes in arithmetic progressions to 10^12", BIT 17:121 127,
    1977.
[4] Paul Pritchard, "Fast compact prime number sieves (among
    others)", Journal of Algorithms 4 (1983), 332-344.
[5] J. Sorenson, "An Introduction To Prime Number Sieves", Computer
    Science Technical Report Vol. 909, January 1990.
    http://research.cs.wisc.edu/techreports/1990/TR909.pdf
[6] J. Sorenson, "An analysis of two prime number sieves", Computer
    Science Technical Report Vol. 1028, June 1991.
    http://research.cs.wisc.edu/techreports/1991/TR1028.pdf
[7] J. Sorenson and I. Parberry, "Two Fast Parallel Prime Number
    Sieves", Information and Computation, Vol. 114, No. 1, 1994.
    http://larc.unt.edu/ian/pubs/sieve.pdf
[8] J. Sorenson, "Trading Time for Space in Prime Number Sieves",
    Lecture Notes in Computer Science, Vol. 1423 (1998), 179-194.
[9] Achim Flammenkamp, "The Art of Prime Sieving", 1998.
    http://wwwhomes.uni-bielefeld.de/achim/prime_sieve.html
[10] Jörg Richstein, "Segmentierung und Optimierung von Algorithmen
    zu Problemen aus der Zahlentheorie", Gießen, Univ., Diss., 1999.
[11] Tomás Oliveira e Silva, "Fast implementation of the segmented
    sieve of Eratosthenes", 2002.
    http://www.ieeta.pt/~tos/software/prime_sieve.html
[12] A. Járai and E. Vatai, "Cache optimized linear sieve", Acta
    Univ. Sapientiae, Informatica, 3, 2 (2011) 205-223.
    http://www.acta.sapientia.ro/acta-info/C3-2/info32-5.pdf
