https://wiki.haskell.org/api.php?action=feedcontributions&user=WillNess&feedformat=atomHaskellWiki - User contributions [en]2016-08-27T20:37:12ZUser contributionsMediaWiki 1.19.14+dfsg-1https://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-08-08T16:02:41Z<p>WillNess: /* One-liners */</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], []==[i | i<-[2..n-1], rem n i==0]]<br />
[n | n<-[2..], []==[j | i<-[2..n-1], j<-[i*i, i*i+i..n], j==n]]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
2 : fix (\xs-> 3 : [n | n <- [5,7..], <br />
foldr (\p r-> p*p>n || (rem n p>0 && r)) True xs])<br />
2:3 : fix (\xs-> 5 : [n | n <- scanl (+) 7 (cycle [4,2]), <br />
foldr (\p r-> p*p>n || (rem n p>0 && r)) True xs])<br />
2:3:5 : fix (\xs-> 7 : [n | n <- scanl (+) 11 (cycle [2,4,2,4,6,2,6,4]), <br />
foldr (\p r-> p*p>n || (rem n p>0 && r)) True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y<-xs, rem y p>0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p, p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\a i-> minus a [i*i, i*i+2*i..n]) (2:[3,5..n]) <br />
[3,5..(floor . sqrt . fromIntegral) n]<br />
primesTo = foldr (\n ps-> foldl (\a p-> minus a [p*p, p*p+p..n]) [2..n] ps)<br />
[] . takeWhile (> 1) . iterate (floor . sqrt . fromIntegral)<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
2 : fix (\xs-> 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in<br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..], xs)))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps }<br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps }<br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\a@(1:p:_) -> Just (p, a `minus` map (*p) a)) [1..] -- Euler's sieve<br />
unfoldr (\(p:xs) -> Just (p, xs `minus` map (*p) (p:xs))) [2..] <br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) )<br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-07-31T07:29:23Z<p>WillNess: /* One-liners */ tweak readability</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], []==[i | i<-[2..div n 2], rem n i==0]]<br />
[n | n<-[2..], []==[j | i<-[2..n-2], j<-[i*i,i*i+i..n], j==n]]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\a i-> minus a [i*i, i*i+2*i..n]) (2:[3,5..n]) <br />
[3,5..(floor . sqrt . fromIntegral) n]<br />
primesTo = foldr (\n ps-> foldl (\a p-> minus a [p*p, p*p+p..n]) [2..n] ps) <br />
[] . takeWhile (> 1) . iterate (floor . sqrt . fromIntegral)<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\a@(1:p:_) -> Just (p, a `minus` map (*p) a)) [1..] -- Euler's sieve<br />
unfoldr (\(p:xs) -> Just (p, xs `minus` map (*p) (p:xs))) [2..] <br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-07-29T18:12:37Z<p>WillNess: /* One-liners */</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], []==[i | i<-[2..div n 2], rem n i==0]]<br />
[n | n<-[2..], []==[j | i<-[2..n-2], j<-[i*i,i*i+i..n], j==n]]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\a i-> minus a [i*i, i*i+2*i..n]) (2:[3,5..n]) <br />
[3,5..(floor . sqrt . fromIntegral) n]<br />
primesTo = foldr (\n ps-> foldl (\a p-> minus a [p*p, p*p+p..n]) [2..n] ps) [] <br />
. takeWhile (> 1) . iterate (floor . sqrt . fromIntegral)<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\a@(1:p:_) -> Just (p, a `minus` map (*p) a)) [1..] -- Euler's sieve<br />
unfoldr (\(p:xs) -> Just (p, xs `minus` map (*p) (p:xs))) [2..] <br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-07-22T20:18:36Z<p>WillNess: /* One-liners */ simplify a definition</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n`div`2], rem n k==0] == []]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\a i-> minus a [i*i, i*i+2*i..n]) (2:[3,5..n]) <br />
[3,5..(floor . sqrt . fromIntegral) n]<br />
primesTo = foldr (\n ps-> foldl (\a p-> minus a [p*p, p*p+p..n]) [2..n] ps) [] <br />
. takeWhile (> 1) . iterate (floor . sqrt . fromIntegral)<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\a@(1:p:_) -> Just (p, a `minus` map (*p) a)) [1..] -- Euler's sieve<br />
unfoldr (\(p:xs) -> Just (p, xs `minus` map (*p) (p:xs))) [2..] <br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-07-01T12:27:53Z<p>WillNess: /* One-liners */ add Euler's sieve</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n`div`2], rem n k==0] == []]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\a i-> minus a [i*i, i*i+2*i..n]) (2:[3,5..n]) <br />
[3,5..(floor . sqrt . fromIntegral) n]<br />
primesTo = foldr (\n ps-> if n > 1 then foldl (\a p-> minus a [p*p, p*p+p..n])<br />
[2..n] ps else []) [] . iterate (floor . sqrt . fromIntegral) <br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\a@(1:p:_) -> Just (p, a `minus` map (*p) a)) [1..] -- Euler's sieve<br />
unfoldr (\(p:xs) -> Just (p, xs `minus` map (*p) (p:xs))) [2..] <br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-06-16T13:33:11Z<p>WillNess: /* One-liners */</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n`div`2], rem n k==0] == []]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\a i-> minus a [i*i, i*i+2*i..n]) (2:[3,5..n]) <br />
[3,5..(floor . sqrt . fromIntegral) n]<br />
primesTo = foldr (\n ps-> if n > 1 then foldl (\a p-> minus a [p*p, p*p+p..n])<br />
[2..n] ps else []) [] . iterate (floor . sqrt . fromIntegral) <br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-06-15T14:19:46Z<p>WillNess: /* One-liners */ tweak code</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n`div`2], rem n k==0] == []]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = foldr (\n r-> if n > 1 then foldl (\a b-> minus a [b*b, b*b+b..n]) <br />
[2..n] r else []) [] $ iterate (floor.sqrt.fromIntegral) n<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-06-05T07:11:08Z<p>WillNess: /* Definition */</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. <br />
<br />
To find out a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''p'' by counting up from it in increments of ''p'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+''n''+''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''p''&times;''p'', ''p''&times;''p''+''p'', ''p''&times;''p''+''p''+''p'', ...} ''':''' ''p'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small> <br />
<br />
In ''pseudocode'', this can be written as<br />
<br />
<haskell><br />
primes = [2..] \ [[p*p, p*p+p..] | p <- primes]<br />
</haskell><br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
Simplest, bounded, ''very'' inefficient formulation:<br />
<haskell><br />
primesTo m = sieve [2..m] {- (\\) is set-difference for unordered lists -}<br />
where <br />
sieve (x:xs) = x : sieve (xs Data.List.\\ [x,x+x..m])<br />
sieve [] = []<br />
</haskell><br />
<br />
The (unbounded) sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as enumeration of multiples of each prime, generated by counting up from prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
The ''"big union"'' <code>_U</code> function can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>; or it could use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
First of all, working with ''ordered'' increasing lists, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of the merge sort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also flatly ignore all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code could now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
-- joinL ((x:xs):t) = x : union xs (joinL t) <br />
joinT ((x:xs):t) = x : union xs (joinT (pairs t)) -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-05-27T23:28:11Z<p>WillNess: /* One-liners */ +1; c/e</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n`div`2], rem n k==0] == []]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
2 : fix ((3:) . concat -- counting by ones<br />
. unfoldr (\(x,u:us)-> Just ([x|u==0], (x+2,us))) <br />
. (,) 5 . ([0,0] ++) <br />
. foldi (\(x:xs) ys -> let n=div (head ys - x) 2 - 1 in<br />
x:take n xs ++ zipWith max ys (drop n xs)) []<br />
. map (\p-> (p*p :) . tail . cycle $ 1 : replicate (p-1) 0) )<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
{- concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..] -}<br />
<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-05-12T10:06:35Z<p>WillNess: /* One-liners */</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n`div`2], rem n k==0] == []]<br />
[n | n<-[2..], all ((> 0).rem n) [2..floor.sqrt.fromIntegral$n]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor.sqrt.fromIntegral$n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) -- ditto<br />
<$> (Just . splitAt 1) xs) $ [2..]<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-05-11T11:13:02Z<p>WillNess: /* One-liners */ +1</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
[n | n<-[2..], [() | k<-[2..n-2], rem n k==0] == []]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor . sqrt $ fromIntegral n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) -- ditto<br />
<$> (Just . splitAt 1) xs) $ [2..]<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-05-01T18:17:08Z<p>WillNess: /* Postponed */</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
Simplest, bounded, ''very'' inefficient formulation:<br />
<haskell><br />
primesTo m = sieve [2..m] {- (\\) is set-difference for unordered lists -}<br />
where <br />
sieve (x:xs) = x : sieve (xs Data.List.\\ [x,x+x..m])<br />
sieve [] = []<br />
</haskell><br />
<br />
The (unbounded) sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as enumeration of multiples of each prime, generated by counting up from prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
The ''"big union"'' <code>_U</code> function can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>; or it could use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
First of all, working with ''ordered'' increasing lists, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of the merge sort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also flatly ignore all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code could now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
-- joinL ((x:xs):t) = x : union xs (joinL t) <br />
joinT ((x:xs):t) = x : union xs (joinT (pairs t)) -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-03-16T14:19:57Z<p>WillNess: /* One-liners */</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor . sqrt $ fromIntegral n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
-- sieving by all odds<br />
2 : minus [3,5..] (foldi (\(x:xs)-> (x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) -- ditto<br />
<$> (Just . splitAt 1) xs) $ [2..]<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- Richard Bird's combined sieve<br />
fix $ (2:) . minus [3..] . foldr (\(x:xs)-> (x:) . union xs) [] <br />
. map (\p-> [p*p, p*p+p..])<br />
<br />
2 : _Y ( (3:) -- unbounded tree-like folding<br />
. minus [5,7..]<br />
. unionAll -- ~= foldi (\(x:xs) ys-> x:union xs ys) []<br />
. map (\p-> [p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-03-10T13:12:29Z<p>WillNess: /* One-liners */ add remark; indent</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
Produce an unbounded (mostly) list of primes.<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) [3,5..floor . sqrt $ fromIntegral n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r)) <br />
True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
. span (< head b) $ a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
unfoldr (\(p:xs) -> Just (p, minus xs [p, p+p..])) [2..] -- the basic sieve<br />
<br />
concat . unfoldr (\xs@(p:_) -> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..]<br />
fix $ (2:) . concat -- postponed<br />
. unfoldr (\(p:ps,xs) -> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(x:xs)->(x:).union xs) [] <br />
$ map (\x->[x*x, x*x+x..]) xs)<br />
2 : minus [3,5..] (foldi (\(x:xs)->(x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
2 : _Y ( (3:) -- unbounded Sieve of Eratosthenes<br />
. minus [5,7..]<br />
. foldi (\(x:xs) ys-> x:union xs ys) [] -- ~= unionAll<br />
. map (\p->[p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2016-03-10T12:37:31Z<p>WillNess: /* One-liners */ more point-free style, with fix</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
<br />
<haskell>[n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
nubBy (((>1).).gcd) [2..]<br />
[n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
2 : [n | n<-[3,5..], all ((> 0).rem n) <br />
[3,5..floor . sqrt $ fromIntegral n]]<br />
<br />
fix (\xs-> 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) xs])<br />
fix (\xs-> 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail xs])<br />
2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0<br />
&& r)) True xs])<br />
<br />
foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
nub . map head . scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] $ [2..]<br />
map head . iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) $ [2..]<br />
2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
[n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
$ span (< head b) a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
fix $ \xs-> 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail xs))<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
fix $ \xs-> let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail xs)<br />
<br />
unfoldr (\(p:xs)-> Just (p, minus xs [p, p+p..])) [2..]<br />
<br />
concat . unfoldr (\xs@(p:_)-> second (`minus` [p, p+p..]) <br />
<$> (Just . splitAt 1) xs) $ [2..]<br />
fix $ (2:) . concat <br />
. unfoldr (\(p:ps,xs)-> second ((ps,) . (`minus` [p*p, p*p+p..])) <br />
<$> (Just . span (< p*p)) xs) . (,[3..]) <br />
<br />
-- producing only unique composites:<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails xs)<br />
<br />
fix $ \xs-> 2 : minus [3..] (foldr (\(x:xs)->(x:).union xs) [] <br />
$ map (\x->[x*x, x*x+x..]) xs)<br />
2 : minus [3,5..] (foldi (\(x:xs)->(x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
2 : _Y ( (3:) -- unbounded Sieve of Eratosthenes<br />
. minus [5,7..]<br />
. foldi (\(x:xs) ys-> x:union xs ys) [] -- ~= unionAll<br />
. map (\p->[p*p, p*p+2*p..]) )<br />
<br />
[2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
[2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Foldl_as_foldr_alternativeFoldl as foldr alternative2016-01-26T11:53:23Z<p>WillNess: add skipping foldl (and foldr, for comparison)</p>
<hr />
<div>This page explains how <hask>foldl</hask> can be written using <hask>foldr</hask>. Yes, there is already [[Foldl as foldr|such a page]]! This one explains it differently.<br />
<br />
<br />
The usual definition of <hask>foldl</hask> looks like this:<br />
<br />
<br />
<haskell><br />
foldl :: (a -> x -> r) -> a -> [x] -> r<br />
foldl f a [] = a<br />
foldl f a (x : xs) = foldl f (f a x) xs<br />
</haskell><br />
<br />
<br />
Now the <hask>f</hask> never changes in the recursion. It turns out things will be simpler later if we pull it out:<br />
<br />
<br />
<haskell><br />
foldl :: (a -> x -> r) -> a -> [x] -> r<br />
foldl f a list = go a list<br />
where<br />
go acc [] = acc<br />
go acc (x : xs) = go (f acc x) xs<br />
</haskell><br />
<br />
<br />
-----<br />
<br />
<br />
For some reason (maybe we're crazy; maybe we want to do weird things with fusion; who knows?) we want to write this using <hask>foldr</hask>. Haskell programmers like curry, so it's natural to see <hask>go acc xs</hask> as <hask>(go acc) xs</hask>&mdash;that is, to see <hask>go a</hask> as a function that takes a list and returns the result of folding <hask>f</hask> into the list starting with an accumulator value of <hask>a</hask>. This perspective, however, is the ''wrong one'' for what we're trying to do here. So let's change the order of the arguments of the helper:<br />
<br />
<br />
<haskell><br />
foldl :: (a -> x -> r) -> a -> [x] -> r<br />
foldl f a list = go2 list a<br />
where<br />
go2 [] acc = acc<br />
go2 (x : xs) acc = go2 xs (f acc x)<br />
</haskell><br />
<br />
<br />
So now we see that <hask>go2 xs</hask> is a function that takes an accumulator and uses it as the initial value to fold <hask>f</hask> into <hask>xs</hask>. With this shift of perspective, we can rewrite <hask>go2</hask> just a little, shifting its second argument into an explicit lambda:<br />
<br />
<br />
<haskell><br />
foldl :: (a -> x -> r) -> a -> [x] -> r<br />
foldl f a list = go2 list a<br />
where<br />
go2 [] = \acc -> acc<br />
go2 (x : xs) = \acc -> go2 xs (f acc x)<br />
</haskell><br />
<br />
<br />
Believe it or not, we're almost done! How is that? Let's parenthesize a bit for emphasis:<br />
<br />
<br />
<haskell><br />
foldl f a list = go2 list a<br />
where<br />
go2 [] = (\acc -> acc) -- nil case<br />
go2 (x : xs) = \acc -> (go2 xs) (f acc x) -- construct x (go2 xs)<br />
</haskell><br />
<br />
<br />
This isn't an academic paper, so we won't mention Graham Hutton's [https://www.cs.nott.ac.uk/~gmh/fold.pdf "Tutorial on the Universality and Expressiveness of Fold"], but <hask>go2</hask> fits the <hask>foldr</hask> pattern, constructing its result in non-nil case from the list's head element (<hask>x</hask>) and the recursive result for its tail (<hask>go2 xs</hask>):<br />
<br />
<br />
<haskell><br />
go2 list = foldr construct (\acc -> acc) list<br />
where<br />
construct x r = \acc -> r (f acc x) <br />
</haskell><br />
<br />
<br />
Substituting this in,<br />
<br />
<br />
<haskell><br />
foldl f a list = (foldr construct (\acc -> acc) list) a<br />
where<br />
construct x r = \acc -> r (f acc x)<br />
</haskell><br />
<br />
<br />
And that's all she wrote! One way to look at this final expression is that <hask>construct</hask> takes an element <hask>x</hask> of the list, a function <hask>r</hask> produced by folding over the rest of the list, and the value of an accumulator, <hask>acc</hask>, "from the left". It applies <hask>f</hask> to the accumulator and the list element, and passes the result forward to the function it got "on the right".<br />
<br />
<br />
Because <hask>r</hask> is the same function as constructed by the <hask>construct</hask> here, calling this e.g. for a list <hask>[x,y,...,z]</hask> scans through the whole list as-if evaluating a nested lambda applied to the initial value of the accumulator, <br />
<br />
<br />
<haskell><br />
(\acc-> <br />
(\acc-> <br />
(... (\acc-> (\acc -> acc)<br />
(f acc z)) ...)<br />
(f acc y))<br />
(f acc x)) a<br />
</haskell><br />
<br />
which creates the chain of evaluations as in <br />
<br />
<haskell><br />
(\acc -> acc) (f (... (f (f a x) y) ...) z)<br />
</haskell><br />
<br />
<br />
which is just what the normal <hask>foldl</hask> would do.<br />
<br />
<br />
----<br />
<br />
<br />
The <hask>construct</hask> function could even be made more clever, and inspect the current element in order to decide whether to ''process'' the list ''further'' or not. Thus, such a variant of <hask>foldl</hask> will be able to stop early, and thus process even infinite lists:<br />
<br />
<br />
<haskell><br />
foldlWhile t f a list = foldr cons (\acc -> acc) list a<br />
where<br />
cons x r = \acc -> if t x then r (f acc x) else acc<br />
</haskell><br />
<br />
<br />
And if we want our <hask>foldl</hask> to decide whether to process or ''skip'' the current element, then it's<br />
<br />
<br />
<haskell><br />
foldlIf t f a list = foldr cons (\acc -> acc) list a<br />
where<br />
cons x r = \acc -> if t x then r (f acc x) else r acc<br />
</haskell><br />
<br />
<br />
(Just for comparison, skipping <hask>foldr</hask> is of course, trivial:)<br />
<br />
<br />
<haskell><br />
foldrIf t f a list = foldr cons a list<br />
where<br />
cons x r | t x = f x r <br />
| otherwise = r<br />
</haskell></div>WillNesshttps://wiki.haskell.org/CurryingCurrying2016-01-12T11:07:49Z<p>WillNess: c/e; note associativity of arrows in types and of application</p>
<hr />
<div>[[Category:Glossary]]<br />
Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed.<br />
<br />
<haskell><br />
f :: a -> b -> c<br />
</haskell><br />
is the '''curried''' form of<br />
<haskell><br />
g :: (a, b) -> c<br />
</haskell><br />
You can convert these two types in either directions with the Prelude functions <hask>curry</hask> and <hask>uncurry</hask>.<br />
<haskell><br />
f = curry g<br />
g = uncurry f<br />
</haskell><br />
Both forms are equally expressive.<br />
It holds<br />
<haskell><br />
f x y = g (x,y) ,<br />
</haskell><br />
however the curried form is usually more convenient because it allows [[partial application]].<br />
<br />
In Haskell, ''all'' functions are considered curried: That is, ''all functions in Haskell take just one argument.''<br />
This is mostly hidden in notation, and so may not be apparent to a new Haskeller. It can be said that arrows in the types notation associate ''to the right'', so that <hask>f :: a -> b -> c</hask> is really <hask>f :: a -> (b -> c)</hask>. Functional application though, associates ''to the left'': <hask>f x y</hask> is really <hask>(f x) y</hask>. <br><br><br />
<br />
Let's take the function <haskell>div :: Int -> Int -> Int</haskell> which performs integer division. The expression <hask>div 11 2</hask> unsurprisingly evaluates to <hask>5</hask>. <br />
<br />
But there's more that's going on than immediately meets the untrained eye. It's a two-part process. First, <haskell>div 11</haskell> is evaluated and ''returns a function'' of type <haskell>Int -> Int</haskell> Then that resulting function is applied to the value <hask>2</hask>, and yields <hask>5</hask>.<br />
<br />
You'll notice that the notation for types reflects this: you can read <haskell>Int -> Int -> Int</haskell> incorrectly as "takes two <hask>Int</hask>s and returns an <hask>Int</hask>", but what it's ''really'' saying is "takes an <hask>Int</hask> and returns something of the type <hask>Int -> Int</hask>" -- that is, it returns a function that takes an <hask>Int</hask> and returns an <hask>Int</hask>. (One can write the type as <hask>Int x Int -> Int</hask> if you really mean the former -- but since all functions in Haskell are curried, that's not legal Haskell. Alternatively, using tuples, you can write <hask>(Int, Int) -> Int</hask>, but keep in mind that the tuple constructor <hask>(,)</hask> itself can be curried.)<br />
<br />
Much of the time, currying can be ignored by the new programmer. The major advantage of considering all functions as curried is theoretical: formal proofs are easier when all functions are treated uniformly (one argument in, one result out). Having said that, there ''are'' Haskell idioms and techniques for which you need to understand currying. <br />
<br />
See<br />
* [[partial application]]<br />
* [[Section of an infix operator]]<br />
* Sometimes it's valuable to think about functions abstractly without specifically giving all their arguments: this is the [[Pointfree]] style.<br />
* Sometimes half the work of the function can be done looking only at the first argument (but there really ''is'' only one argument, remember?): see [[functional dispatch]].<br />
* Conversion between curried and uncurried style allows [[Composing functions with multiple values|composition of functions with multiple values]]<br />
<br />
== Exercises ==<br />
<br />
* Simplify <hask>curry id</hask> <!-- (,) --><br />
* Simplify <hask>uncurry const</hask> <!-- fst --><br />
* Express <hask>snd</hask> using <hask>curry</hask> or <hask>uncurry</hask> and other basic Prelude functions and without lambdas <!-- uncurry (flip const) --><br />
* Write the function <hask>\(x,y) -> (y,x)</hask> without lambda and with only Prelude functions <!-- uncurry (flip (curry id)) --></div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-01-05T16:12:18Z<p>WillNess: /* Sieve of Eratosthenes */ c/e</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
Simplest, bounded, ''very'' inefficient formulation:<br />
<haskell><br />
primesTo m = sieve [2..m] {- (\\) is set-difference for unordered lists -}<br />
where <br />
sieve (x:xs) = x : sieve (xs Data.List.\\ [x,x+x..m])<br />
sieve [] = []<br />
</haskell><br />
<br />
The (unbounded) sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as enumeration of multiples of each prime, generated by counting up from prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
The ''"big union"'' <code>_U</code> function can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>; or it could use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
First of all, working with ''ordered'' increasing lists, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of the merge sort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also flatly ignore all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
-- joinL ((x:xs):t) = x : union xs (joinL t) <br />
joinT ((x:xs):t) = x : union xs (joinT (pairs t)) -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-01-05T15:52:11Z<p>WillNess: /* Sieve of Eratosthenes */ typo</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
Simplest, bounded formulation. *Very* inefficient:<br />
<haskell><br />
primesTo m = sieve [2..m] {- (\\) is set-difference for unordered lists -}<br />
where <br />
sieve (x:xs) = x : sieve (xs Data.List.\\ [x,x+x..m])<br />
sieve [] = []<br />
</haskell><br />
<br />
The (unbounded) sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
-- joinL ((x:xs):t) = x : union xs (joinL t) <br />
joinT ((x:xs):t) = x : union xs (joinT (pairs t)) -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-01-05T15:51:52Z<p>WillNess: /* Sieve of Eratosthenes */ add simplest variant</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
Simplest, bounded formulation. *Very* inefficient.<br />
<haskell><br />
primesTo m = sieve [2..m] {- (\\) is set-difference for unordered lists -}<br />
where <br />
sieve (x:xs) = x : sieve (xs Data.List.\\ [x,x+x..m])<br />
sieve [] = []<br />
</haskell><br />
<br />
The (unbounded) sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
-- joinL ((x:xs):t) = x : union xs (joinL t) <br />
joinT ((x:xs):t) = x : union xs (joinT (pairs t)) -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-01-02T12:13:38Z<p>WillNess: /* Tree merging */ tweak code for uniformity and comparison</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
-- joinL ((x:xs):t) = x : union xs (joinL t) <br />
joinT ((x:xs):t) = x : union xs (joinT (pairs t)) -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-01-02T12:09:23Z<p>WillNess: /* Segmented */ c/e comments</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] -- chain of subtractions<br />
[[y+s, y+2*s..q] | (s,y) <- fs] -- OR,<br />
-- [x,x+2..q-2] `minus` foldl union [] -- subtraction of merged<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs] -- lists<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2016-01-02T11:58:24Z<p>WillNess: /* Sieve of Eratosthenes */ tweak a spec</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat <br />
. takeWhile (not.null) . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
-- minus [x,x+2..q-2] (foldl union []<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbers_miscellaneousPrime numbers miscellaneous2015-12-01T13:27:47Z<p>WillNess: /* One-liners */ tweak a def -- simpler and faster</p>
<hr />
<div>For a context to this, please see [[Prime numbers#Implicit_Heap | Prime numbers]].<br />
<br />
== Implicit Heap ==<br />
<br />
The following is an original implicit heap implementation for the sieve of<br />
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The [[Prime_numbers#Tree merging with Wheel]] section simplifies it, removing the <code>People a</code> structure altogether, and improves upon it by using a folding tree structure better adjusted for primes processing, and a [[Prime_numbers#Euler.27s_Sieve | wheel]] optimization.<br />
<br />
See also the message threads [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/25270/focus=25312 Re: "no-coding" functional data structures via lazyness] for more about how merging ordered lists amounts to creating an implicit heap and [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/26426/focus=26493 Re: Code and Perf. Data for Prime Finders] for an explanation of the <code>People a</code> structure that makes it work.<br />
<br />
<haskell><br />
data People a = VIP a (People a) | Crowd [a]<br />
<br />
mergeP :: Ord a => People a -> People a -> People a<br />
mergeP (VIP x xt) ys = VIP x $ mergeP xt ys<br />
mergeP (Crowd xs) (Crowd ys) = Crowd $ merge xs ys<br />
mergeP xs@(Crowd (x:xt)) ys@(VIP y yt) = case compare x y of<br />
LT -> VIP x $ mergeP (Crowd xt) ys<br />
EQ -> VIP x $ mergeP (Crowd xt) yt<br />
GT -> VIP y $ mergeP xs yt<br />
<br />
merge :: Ord a => [a] -> [a] -> [a]<br />
merge xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : merge xt ys<br />
EQ -> x : merge xt yt<br />
GT -> y : merge xs yt<br />
<br />
diff xs@(x:xt) ys@(y:yt) = case compare x y of<br />
LT -> x : diff xt ys<br />
EQ -> diff xt yt<br />
GT -> diff xs yt<br />
<br />
foldTree :: (a -> a -> a) -> [a] -> a<br />
foldTree f ~(x:xs) = x `f` foldTree f (pairs xs)<br />
where pairs ~(x: ~(y:ys)) = f x y : pairs ys<br />
<br />
primes, nonprimes :: [Integer]<br />
primes = 2:3:diff [5,7..] nonprimes<br />
nonprimes = serve . foldTree mergeP . map multiples $ tail primes<br />
where<br />
multiples p = vip [p*p,p*p+2*p..]<br />
<br />
vip (x:xs) = VIP x $ Crowd xs<br />
serve (VIP x xs) = x:serve xs<br />
serve (Crowd xs) = xs<br />
</haskell><br />
<br />
<code>nonprimes</code> effectively implements a heap, exploiting lazy evaluation.<br />
<br />
== Prime Wheels ==<br />
<br />
The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form <math>6k+1</math> or <math>6k+5</math>. Thus, we only need to test these numbers:<br />
<br />
<haskell><br />
primes :: [Integer]<br />
primes = 2:3:prs<br />
where<br />
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]<br />
prs = p : filter isPrime candidates<br />
isPrime n = all (not . divides n)<br />
$ takeWhile (\p -> p*p <= n) prs<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
<br />
Here, <hask>prs</hask> is the list of primes greater than 3 and <hask>isPrime</hask> does not test for divisibility by 2 or 3 because the <hask>candidates</hask> by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.<br />
<br />
Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a '''prime wheel'''. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.<br />
<br />
A wheel can be represented by its circumference and the spiked positions.<br />
<haskell><br />
data Wheel = Wheel Integer [Integer]<br />
</haskell><br />
We prick out numbers by rolling the wheel.<br />
<haskell><br />
roll (Wheel n rs) = [n*k+r | k <- [0..], r <- rs]<br />
</haskell><br />
The smallest wheel is the unit wheel with one spike, it will prick out every number.<br />
<haskell><br />
w0 = Wheel 1 [1]<br />
</haskell><br />
We can create a larger wheel by rolling a smaller wheel of circumference <hask>n</hask> along a rim of circumference <hask>p*n</hask> while excluding spike positions at multiples of <hask>p</hask>.<br />
<br />
<haskell><br />
nextSize (Wheel n rs) p =<br />
Wheel (p*n) [r2 | k <- [0..(p-1)], r <- rs,<br />
let r2 = n*k+r, r2 `mod` p /= 0]<br />
</haskell><br />
<br />
Combining both, we can make wheels that prick out numbers that avoid a given list <hask>ds</hask> of divisors.<br />
<haskell><br />
mkWheel ds = foldl nextSize w0 ds<br />
</haskell><br />
<br />
Now, we can generate prime numbers with a wheel that for instance avoids all multiples of 2, 3, 5 and 7.<br />
<haskell><br />
primes :: [Integer]<br />
primes = small ++ large<br />
where<br />
1:p:candidates = roll $ mkWheel small<br />
small = [2,3,5,7]<br />
large = p : filter isPrime candidates<br />
isPrime n = all (not . divides n) <br />
$ takeWhile (\p -> p*p <= n) large<br />
divides n p = n `mod` p == 0<br />
</haskell><br />
It's a pretty big wheel with a circumference of 210 and allows us to calculate the first 10000 primes in convenient time.<br />
<br />
A fixed size wheel is fine, but adapting the wheel size while generating prime numbers quickly becomes impractical, because the circumference grows very fast, as primorial, but the returns quickly diminish, the improvement being just <code>(p-1)/p</code>. See [[Prime_numbers#Euler.27s_Sieve | Euler's Sieve]], or the [[Research papers/Functional pearls|functional pearl]] titled [http://citeseer.ist.psu.edu/runciman97lazy.html Lazy wheel sieves and spirals of primes] for more.<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<haskell><br />
<br />
module Sieve where<br />
import qualified Data.IntSet as I<br />
<br />
-- findNext - finds the next member of an IntSet.<br />
findNext c is | I.member c is = c<br />
| c > I.findMax is = error "Ooops. No next number in set."<br />
| otherwise = findNext (c+1) is<br />
<br />
-- mark - delete all multiples of n from n*n to the end of the set<br />
mark n is = is I.\\ (I.fromAscList (takeWhile (<=end) (map (n*) [n..])))<br />
where<br />
end = I.findMax is<br />
<br />
-- primes - gives all primes up to n <br />
primes n = worker 2 (I.fromAscList [2..n])<br />
where<br />
worker x is <br />
| (x*x) > n = is<br />
| otherwise = worker (findNext (x+1) is) (mark x is)<br />
</haskell><br />
<br />
''(doesn't look like it runs very efficiently)''.<br />
<br />
<br />
<br />
== One-liners ==<br />
<br />
<haskell>primes = [n | n<-[2..], product [1..n-1] `rem` n == n-1] -- Wilson's theorem<br />
<br />
primes = nubBy (((>1).).gcd) [2..]<br />
primes = [n | n<-[2..], all ((> 0).rem n) [2..n-1]]<br />
primes = 2 : [n | n<-[3,5..], all ((> 0).rem n) <br />
[3,5..floor . sqrt $ fromIntegral n]]<br />
<br />
primes = 2 : [n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) primes]<br />
primes = 2 : 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0 && r))<br />
True $ tail primes]<br />
primes = 2 : fix (\xs-> 3 : [n | n<-[5,7..], foldr (\p r-> p*p>n || (rem n p>0<br />
&& r)) True xs])<br />
<br />
primes = foldr (\x xs-> x : filter ((> 0).(`rem`x)) xs) [] [2..]<br />
primes = nub $ map head $ scanl (\xs x-> filter ((> 0).(`rem`x)) xs) [2..] [2..]<br />
primes = map head $ iterate (\(x:xs)-> filter ((> 0).(`rem`x)) xs) [2..]<br />
primes = 2 : unfoldr (\(x:xs)-> Just(x, filter ((> 0).(`rem`x)) xs)) [3,5..]<br />
<br />
primes = fix $ concatMap (fst.snd)<br />
. iterate (\(p:t,(h,xs)) -> (t,span (< head t^2) [y | y <- xs, rem y p /= 0]))<br />
. (, ([2,3],[4..])) -- (minus xs [p*p,p*p+p..])<br />
<br />
primes = [n | n<-[2..], not $ elem n [j*k | j<-[2..n-1], k<-[2..n-1]]]<br />
primes = [n | n<-[2..], not $ elem n [j*k | j<-[2..n`div`2], k<-[2..n`div`j]]]<br />
<br />
primes = zipWith (flip (!!)) [0..] . scanl1 minus -- APL-style<br />
. scanl1 (zipWith (+)) $ repeat [2..] <br />
primes = tail . concat . unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))<br />
$ span (< head b) a) <br />
. scanl1 (zipWith (+) . tail) $ tails [1..]<br />
<br />
primesTo n = foldl (\r x-> r `minus` [x*x, x*x+2*x..]) (2:[3,5..n]) <br />
[3,5..floor . sqrt $ fromIntegral n]<br />
primesTo n = 2 : foldr (\r z-> if (head r^2) <= n then head r : z else r) [] <br />
(iterate (\(p:t)-> minus t [p*p, p*p+2*p..]) [3,5..n])<br />
<br />
primes = 2 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, (filter ((> 0).(`rem`p)) t, ps))) ([3,5..],[3,5..]))<br />
primes = 2 : 3 : concat (unfoldr (\(xs,p:ps)-> let (h,t)=span (< p*p) xs in <br />
Just (h, ((`minus` [p*p, p*p+2*p..]) t, ps))) ([5,7..],<br />
tail primes))<br />
primes = 2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), [x | x <- [x, x+2 .. p*p-2],<br />
all ((/= 0).rem x) fs])) ((inits ps, 5, ps), [3]) ) <br />
<br />
primes = 2 : _Y (\ps-> concatMap snd $ iterate (\((fs:ft, x, p:t),_) -> <br />
((ft,p*p+2,t), minus [x, x+2 .. p*p-2] <br />
$ foldi union [] [[o, o+2*i .. p*p-2] | i <- fs, <br />
let o=x+mod(i-x)(2*i)])) ((inits ps, 5, ps), [3]) ) <br />
<br />
primes = let { sieve (x:xs) = x : sieve [n | n <- xs, rem n x > 0] } <br />
in sieve [2..] <br />
primes = let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (filter ((> 0).(`rem`p)) t) ps } <br />
in 2 : 3 : sieve [5,7..] (tail primes)<br />
primes = let { sieve xs (p:ps) = let (h,t)=span (< p*p) xs in <br />
h ++ sieve (t `minus` [p*p, p*p+2*p..]) ps } <br />
in 2 : 3 : sieve [5,7..] (tail primes)<br />
<br />
-- producing only unique composites:<br />
primes = 2 : minus [3..] (foldr (\(p:ps) r-> fix $ ((p*p) :) .<br />
merge r . map (p*) . merge ps) [] $ tails primes)<br />
<br />
primes = 2 : minus [3..] (foldr (\(x:xs)->(x:).union xs) [] <br />
$ map (\x->[x*x, x*x+x..]) primes)<br />
primes = 2 : minus [3,5..] (foldi (\(x:xs)->(x:).union xs) [] <br />
$ map (\x->[x*x, x*x+2*x..]) [3,5..])<br />
<br />
primes = 2 : _Y ( (3:) -- unbounded Sieve of Eratosthenes<br />
. minus [5,7..]<br />
. foldi (\(x:xs) ys-> x:union xs ys) [] -- ~= unionAll<br />
. map (\p->[p*p, p*p+2*p..]) )<br />
<br />
primes = [2,3,5,7] ++ _Y ( (11:) -- using a wheel;<br />
. minus (scanl (+) 13 $ tail wh11) -- 1.4x faster than <br />
. unionAll -- the next one<br />
. map (\p-> map (p*) . dropWhile (< p) $ <br />
scanl (+) (p - rem (p-11) 210) wh11) )<br />
primes = [2,3,5,7] ++ _Y ( (11:) <br />
. minus (scanl (+) 13 $ tail wh11)<br />
. unionAll<br />
. map (\(w,p)-> scanl (\c d-> c + p*d) (p*p) w)<br />
. isectBy (compare . snd)<br />
(tails wh11 `zip` scanl (+) 11 wh11) ) <br />
_Y g = g (_Y g)<br />
wh11 = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: <br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wh11<br />
</haskell><br />
<br />
<code>foldi</code> is an infinitely right-deepening tree folding function found [[Fold#Tree-like_folds|here]]. <code>minus</code> and <code>union</code> of course are on the main page [[Prime_numbers#Initial_definition|here]] (and <code>merge</code> a simpler, duplicates-ignoring variant of <code>union</code>).<br />
<br />
The few last definitions use functions from the [http://hackage.haskell.org/package/data-ordlist <code>data-ordlist</code>] package, and the 2-3-5-7 wheel <code>wh11</code>; they might be leaking space unless <code>minus</code> is fused with its input (into [[Prime_numbers#Tree merging |<code>gaps</code>]]/[[Prime_numbers#Tree merging with Wheel|<code>gapsW</code>]] from the main page).<br />
<br />
[[Category:Code]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2015-11-28T22:59:18Z<p>WillNess: /* Optimal trial division */ tweak comment</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
-- minus [x,x+2..q-2] (foldl union []<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
-- = 2 : filter (`noDivs`[3,5..]) [3,5..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Testing_primalityTesting primality2015-11-23T02:53:47Z<p>WillNess: /* Primality Test and Integer Factorization */</p>
<hr />
<div>= Testing Primality =<br />
<br />
(for a context to this see [[Prime_numbers | Prime numbers]]).<br />
<br />
== Primality Test and Integer Factorization ==<br />
<br />
Simplest primality test and integer factorization is by trial division:<br />
<haskell><br />
import Data.List (unfoldr)<br />
import Data.Maybe (listToMaybe)<br />
<br />
factors :: Integer -> [Integer]<br />
factors n <br />
= unfoldr (\n -> listToMaybe [(x, div n x) | x <- [2..n], mod n x==0]) n<br />
= unfoldr (\(d,n) -> listToMaybe [(x, (x, div n x)) | x <- [d..n], mod n x==0]) (2,n)<br />
= unfoldr (\(d,n) -> listToMaybe [(x, (x, div n x)) | x <- takeWhile ((<=n).(^2)) <br />
[d..] ++ [n|n>1], mod n x==0]) (2,n)<br />
isPrime n = n > 1 && head (factors n) == n<br />
</haskell><br />
<br />
The factors produced by this code are all prime by construction, because we enumerate possible divisors in ascending order while dividing each found factor out of the number being tested.<br />
<br />
Of course there's no need to try any even numbers above 2. Given an infinite list of primes we can avoid ''any'' composites, not just evens:<br />
<haskell><br />
pfactors prs n = unfoldr (\(ds,n) -> listToMaybe <br />
[(x, (dropWhile (< x) ds, div n x)) | x <- takeWhile ((<=n).(^2)) ds ++<br />
[n|n>1], mod n x==0]) (prs,n)<br />
primes :: [Integer]<br />
primes = 2 : 3 : [x | x <- [5,7..], head (pfactors (tail primes) x) == x]<br />
</haskell><br />
<br />
Re-writing the above as a recursive code, we get:<br />
<br />
<haskell><br />
isPrime n = n > 1 &&<br />
foldr (\p r -> p*p > n || ((n `rem` p) /= 0 && r))<br />
True primes<br />
<br />
primeFactors n | n > 1 = go n primes -- or go n (2:[3,5..])<br />
where -- for one-off invocation<br />
go n ps@(p:t)<br />
| p*p > n = [n]<br />
| r == 0 = p : go q ps<br />
| otherwise = go n t<br />
where<br />
(q,r) = quotRem n p<br />
</haskell><br />
<br />
When trying to factorize only one number or two, it might be faster to just use <code>(2:[3,5..])</code> as a source of possible divisors instead of calculating the prime numbers first, depending on the speed of your primes generator. For more than a few factorizations, when no other primes source is available, just use<br />
<haskell><br />
primes = 2 : filter isPrime [3,5..]<br />
</haskell><br />
<br />
More at [[Prime numbers#Optimal trial division]].<br />
<br />
== Miller-Rabin Primality Test ==<br />
<haskell><br />
-- (eq. to) find2km (2^k * n) = (k,n)<br />
find2km :: Integral a => a -> (a,a)<br />
find2km n = f 0 n<br />
where <br />
f k m<br />
| r == 1 = (k,m)<br />
| otherwise = f (k+1) q<br />
where (q,r) = quotRem m 2 <br />
<br />
-- n is the number to test; a is the (presumably randomly chosen) witness<br />
millerRabinPrimality :: Integer -> Integer -> Bool<br />
millerRabinPrimality n a<br />
| a <= 1 || a >= n-1 = <br />
error $ "millerRabinPrimality: a out of range (" <br />
++ show a ++ " for "++ show n ++ ")" <br />
| n < 2 = False<br />
| even n = False<br />
| b0 == 1 || b0 == n' = True<br />
| otherwise = iter (tail b)<br />
where<br />
n' = n-1<br />
(k,m) = find2km n'<br />
b0 = powMod n a m<br />
b = take (fromIntegral k) $ iterate (squareMod n) b0<br />
iter [] = False<br />
iter (x:xs)<br />
| x == 1 = False<br />
| x == n' = True<br />
| otherwise = iter xs<br />
<br />
-- (eq. to) pow' (*) (^2) n k = n^k<br />
pow' :: (Num a, Integral b) => (a->a->a) -> (a->a) -> a -> b -> a<br />
pow' _ _ _ 0 = 1<br />
pow' mul sq x' n' = f x' n' 1<br />
where <br />
f x n y<br />
| n == 1 = x `mul` y<br />
| r == 0 = f x2 q y<br />
| otherwise = f x2 q (x `mul` y)<br />
where<br />
(q,r) = quotRem n 2<br />
x2 = sq x<br />
<br />
mulMod :: Integral a => a -> a -> a -> a<br />
mulMod a b c = (b * c) `mod` a<br />
squareMod :: Integral a => a -> a -> a<br />
squareMod a b = (b * b) `rem` a<br />
<br />
-- (eq. to) powMod m n k = n^k `mod` m<br />
powMod :: Integral a => a -> a -> a -> a<br />
powMod m = pow' (mulMod m) (squareMod m)<br />
</haskell><br />
<br />
Example:<br />
<br />
<haskell>-- check if '1212121' is prime with several witnesses<br />
> map (millerRabinPrimality 1212121) [5432,1265,87532,8765,26]<br />
[True,True,True,True,True]<br />
</haskell><br />
<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2015-11-11T19:15:52Z<p>WillNess: /* Optimal trial division */ simplify: pointfree -> pointful</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
-- minus [x,x+2..q-2] (foldl union []<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f > 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2015-11-11T19:10:37Z<p>WillNess: /* Turner's sieve - Trial division */ it says "revised 1983 for Z expressions", so, use 1983.</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
-- minus [x,x+2..q-2] (foldl union []<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's ''(SASL Language Manual, 1983)'' formulation replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p > 0]<br />
-- map head<br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..]<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p > 0]<br />
-- (\(a,b:_) -> map head a ++ b) . span ((< m).(^2).head) <br />
-- $ iterate (\(p:xs) -> [x | x <- xs, rem x p > 0]) [2..m]<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x <- t, rem x p > 0]<br />
-- fix $ concatMap (fst . fst)<br />
-- . iterate (\((_,xs), p:ps) -> let (h,t) = span (< p*p) xs in<br />
-- ((h, [x | x <- t, rem x p > 0]), ps)) <br />
-- . (,) ([2],[3..]) <br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile ((<=i).(^2)) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f /= 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2015-11-02T00:49:29Z<p>WillNess: </p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
-- minus [x,x+2..q-2] (foldl union []<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's original 1975 formulation ''(SASL Language Manual, 1975)'' replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]<br />
-- map fst . tail <br />
-- $ iterate (\(_,p:xs)->(p, [x | x <- xs, rem x p /= 0])) (1,[2..])<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p /= 0]<br />
-- (\(a,(p,xs):_)-> map fst a ++ p:xs) . span ((< m).(^2).fst) . tail<br />
-- $ iterate (\(_,p:xs)->(p, [x | x <- xs, rem x p /= 0])) (1,[2..m])<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x<-t, rem x p /= 0]<br />
-- fix $ concat . map fst . <br />
-- iterate (\(_,(xs,p:ps))->let (h,t)=span (< p*p) xs in<br />
-- (h, ([x | x <- t, rem x p /= 0], ps))) . ((,) [2]) . ((,) [3..])<br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile ((<=i).(^2)) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f /= 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..]<br />
where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2015-11-02T00:42:15Z<p>WillNess: /* Sieve of Eratosthenes */ c/e</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus`, `union` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
''<code>_U</code>'' can be defined as the folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into the segments between successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] -- bounded, up to m<br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p, p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] <br />
where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
-- minus [x,x+2..q-2] (foldl union []<br />
-- [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t<br />
where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs<br />
where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's original 1975 formulation ''(SASL Language Manual, 1975)'' replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]<br />
-- map fst . tail <br />
-- $ iterate (\(_,p:xs)->(p, [x | x <- xs, rem x p /= 0])) (1,[2..])<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p /= 0]<br />
-- (\(a,(p,xs):_)-> map fst a ++ p:xs) . span ((< m).(^2).fst) . tail<br />
-- $ iterate (\(_,p:xs)->(p, [x | x <- xs, rem x p /= 0])) (1,[2..m])<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x<-t, rem x p /= 0]<br />
-- fix $ concat . map fst . <br />
-- iterate (\(_,(xs,p:ps))->let (h,t)=span (< p*p) xs in<br />
-- (h, ([x | x <- t, rem x p /= 0], ps))) . ((,) [2]) . ((,) [3..])<br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code>filterBy ds n = [n | noDivs n ds]</code> (see <code>noDivs</code> definition below) &thinsp;&ndash;&thinsp; but unlike the original code, each filter being created at its proper moment, not sooner than the prime's square is seen.<br />
<br />
=== Optimal trial division ===<br />
<br />
The above is equivalent to the traditional formulation of trial division,<br />
<haskell><br />
ps = 2 : [i | i <- [3..], <br />
and [rem i p > 0 | p <- takeWhile ((<=i).(^2)) ps]]<br />
</haskell><br />
or,<br />
<haskell><br />
noDivs n fs = foldr (\f r -> f*f > n || (rem n f /= 0 && r)) True fs<br />
-- primes = filter (`noDivs`[2..]) [2..]<br />
primesTD = 2 : 3 : filter (`noDivs` tail primesTD) [5,7..]<br />
isPrime n = n > 1 && noDivs n primesTD<br />
</haskell><br />
except that this code is rechecking for each candidate number which primes to use, whereas for every candidate number in each segment between the successive squares of primes these will just be the same prefix of the primes list being built.<br />
<br />
Trial division is used as a simple [[Testing primality#Primality Test and Integer Factorization|primality test and prime factorization algorithm]].<br />
<br />
=== Segmented Generate and Test ===<br />
Next we turn [[#Postponed Filters |the list of filters]] into one filter by an ''explicit'' list, each one in a progression of prefixes of the primes list. This seems to eliminate most recalculations, explicitly filtering composites out from batches of odds between the consecutive squares of primes. <br />
<haskell><br />
import Data.List<br />
<br />
primesST = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes (inits oddprimes) -- [],[3],[3,5],...<br />
sieve x q ~(_:t) (fs:ft) =<br />
filter ((`all` fs) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head t^2) t ft<br />
</haskell><br />
<br />
<br />
==== Generate and Test Above Limit ====<br />
<br />
The following will start the segmented Turner sieve at the right place, using any primes list it's supplied with (e.g. [[#Tree_merging_with_Wheel | TMWE]] etc.) or itself, as shown, demand computing it just up to the square root of any prime it'll produce:<br />
<br />
<haskell><br />
primesFromST m | m > 2 =<br />
sieve (m`div`2*2+1) (head ps^2) (tail ps) (inits ps)<br />
where <br />
(h,ps) = span (<= (floor.sqrt $ fromIntegral m+1)) oddprimes<br />
sieve x q ps (fs:ft) =<br />
filter ((`all` (h ++ fs)) . ((/=0).) . rem) [x,x+2..q-2]<br />
++ sieve (q+2) (head ps^2) (tail ps) ft<br />
oddprimes = 3 : primesFromST 5 -- odd primes<br />
</haskell><br />
<br />
This is usually faster than testing candidate numbers for divisibility [[#Optimal trial division|one by one]] which has to re-fetch anew the needed prime factors to test by, for each candidate. Faster is the [[99_questions/Solutions/39#Solution_4.|offset sieve of Eratosthenes on odds]], and yet faster the one [[#Above_Limit_-_Offset_Sieve|w/ wheel optimization]], on this page.<br />
<br />
=== Conclusions ===<br />
All these variants being variations of trial division, finding out primes by direct divisibility testing of every candidate number by sequential primes below its square root (instead of just by ''its factors'', which is what ''direct generation of multiples'' is doing, essentially), are thus principally of worse complexity than that of Sieve of Eratosthenes.<br />
<br />
The initial code is just a one-liner that ought to have been regarded as ''executable specification'' in the first place. It can easily be improved quite significantly with a simple use of bounded, guarded formulation to limit the number of filters it creates, or by postponement of filter creation.<br />
<br />
== Euler's Sieve ==<br />
=== Unbounded Euler's sieve ===<br />
With each found prime Euler's sieve removes all its multiples ''in advance'' so that at each step the list to process is guaranteed to have ''no multiples'' of any of the preceding primes in it (consists only of numbers ''coprime'' with all the preceding primes) and thus starts with the next prime:<br />
<br />
<haskell><br />
primesEU = 2 : eulers [3,5..] where<br />
eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs))<br />
-- eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+2*p..])<br />
</haskell><br />
<br />
This code is extremely inefficient, running above <math>O({n^{2}})</math> empirical complexity (and worsening rapidly), and should be regarded a ''specification'' only. Its memory usage is very high, with empirical space complexity just below <math>O({n^{2}})</math>, in ''n'' primes produced.<br />
<br />
In the stream-based sieve of Eratosthenes we are able to ''skip'' along the input stream <code>xs</code> directly to the prime's square, consuming the whole prefix at once, thus achieving the results equivalent to the postponement technique, because the generation of the prime's multiples is independent of the rest of the stream. <br />
<br />
But here in the Euler's sieve it ''is'' dependent on all <code>xs</code> and we're unable ''in principle'' to skip along it to the prime's square - because all <code>xs</code> are needed for each prime's multiples generation. Thus efficient unbounded stream-based implementation seems to be impossible in principle, under the simple scheme of producing the multiples by multiplication.<br />
<br />
=== Wheeled list representation ===<br />
<br />
The situation can be somewhat improved using a different list representation, for generating lists not from a last element and an increment, but rather a last span and an increment, which entails a set of helpful equivalences:<br />
<haskell><br />
{- fromElt (x,i) = x : fromElt (x + i,i)<br />
=== iterate (+ i) x<br />
[n..] === fromElt (n,1) <br />
=== fromSpan ([n],1) <br />
[n,n+2..] === fromElt (n,2) <br />
=== fromSpan ([n,n+2],4) -}<br />
<br />
fromSpan (xs,i) = xs ++ fromSpan (map (+ i) xs,i)<br />
<br />
{- === concat $ iterate (map (+ i)) xs<br />
fromSpan (p:xt,i) === p : fromSpan (xt ++ [p + i], i) <br />
fromSpan (xs,i) `minus` fromSpan (ys,i) <br />
=== fromSpan (xs `minus` ys, i) <br />
map (p*) (fromSpan (xs,i)) <br />
=== fromSpan (map (p*) xs, p*i)<br />
fromSpan (xs,i) === forall (p > 0).<br />
fromSpan (concat $ take p $ iterate (map (+ i)) xs, p*i) -}<br />
<br />
spanSpecs = iterate eulerStep ([2],1)<br />
eulerStep (xs@(p:_), i) = <br />
( (tail . concat . take p . iterate (map (+ i))) xs<br />
`minus` map (p*) xs, p*i )<br />
<br />
{- > mapM_ print $ take 4 spanSpecs <br />
([2],1)<br />
([3],2)<br />
([5,7],6)<br />
([7,11,13,17,19,23,29,31],30) -}<br />
</haskell><br />
<br />
Generating a list from a span specification is like rolling a ''[[#Prime_Wheels|wheel]]'' as its pattern gets repeated over and over again. For each span specification <code>w@((p:_),_)</code> produced by <code>eulerStep</code>, the numbers in <code>(fromSpan w)</code> up to <math>{p^2}</math> are all primes too, so that<br />
<br />
<haskell><br />
eulerPrimesTo m = if m > 1 then go ([2],1) else []<br />
where<br />
go w@((p:_), _) <br />
| m < p*p = takeWhile (<= m) (fromSpan w)<br />
| True = p : go (eulerStep w)<br />
</haskell><br />
<br />
This runs at about <math>O(n^{1.5..1.8})</math> complexity, for <code>n</code> primes produced, and also suffers from a severe space leak problem (IOW its memory usage is also very high).<br />
<br />
== Using Immutable Arrays ==<br />
<br />
=== Generating Segments of Primes ===<br />
<br />
The sieve of Eratosthenes' [[#Segmented|removal of multiples on each segment of odds]] can be done by actually marking them in an array, instead of manipulating ordered lists, and can be further sped up more than twice by working with odds only:<br />
<br />
<haskell><br />
import Data.Array.Unboxed<br />
<br />
primesSA :: [Int]<br />
primesSA = 2 : oddprimes ()<br />
where <br />
oddprimes () = 3 : sieve (oddprimes ()) 3 []<br />
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a] <br />
++ sieve ps (p*p) ((p,0) : <br />
[(s, rem (y-q) s) | (s,y) <- fs])<br />
where<br />
q = (p*p-x)`div`2<br />
a :: UArray Int Bool<br />
a = accumArray (\ b c -> False) True (1,q-1)<br />
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]] <br />
</haskell><br />
<br />
Runs significantly faster than [[#Tree merging with Wheel|TMWE]] and with better empirical complexity, of about <math>O(n^{1.10..1.05})</math> in producing first few millions of primes, with constant memory footprint.<br />
<br />
=== Calculating Primes Upto a Given Value ===<br />
<br />
Equivalent to [[#Accumulating Array|Accumulating Array]] above, running somewhat faster (compiled by GHC with optimizations turned on):<br />
<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToNA n = 2: [i | i <- [3,5..n], ar ! i]<br />
where<br />
ar = f 5 $ accumArray (\ a b -> False) True (3,n) <br />
[(i,()) | i <- [9,15..n]]<br />
f p a | q > n = a<br />
| True = if null x then a2 else f (head x) a2<br />
where q = p*p<br />
a2 :: UArray Int Bool<br />
a2 = a // [(i,False) | i <- [q, q+2*p..n]]<br />
x = [i | i <- [p+2,p+4..n], a2 ! i]<br />
</haskell><br />
<br />
=== Calculating Primes in a Given Range ===<br />
<br />
<haskell><br />
primesFromToA a b = (if a<3 then [2] else []) <br />
++ [i | i <- [o,o+2..b], ar ! i]<br />
where <br />
o = max (if even a then a+1 else a) 3 -- first odd in the segment<br />
r = floor . sqrt $ fromIntegral b + 1<br />
ar = accumArray (\_ _ -> False) True (o,b) -- initially all True,<br />
[(i,()) | p <- [3,5..r]<br />
, let q = p*p -- flip every multiple of an odd <br />
s = 2*p -- to False<br />
(n,x) = quotRem (o - q) s <br />
q2 = if o <= q then q<br />
else q + (n + signum x)*s<br />
, i <- [q2,q2+s..b] ]<br />
</haskell><br />
<br />
Although sieving by odds instead of by primes, the array generation is so fast that it is very much feasible and even preferable for quick generation of some short spans of relatively big primes.<br />
<br />
== Using Mutable Arrays ==<br />
<br />
Using mutable arrays is the fastest but not the most memory efficient way to calculate prime numbers in Haskell.<br />
<br />
=== Using ST Array ===<br />
<br />
This method implements the Sieve of Eratosthenes, similar to how you might do it<br />
in C, modified to work on odds only. It is fast, but about linear in memory consumption, allocating one (though apparently packed) sieve array for the whole sequence to process.<br />
<br />
<haskell><br />
import Control.Monad<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Unboxed<br />
<br />
sieveUA :: Int -> UArray Int Bool<br />
sieveUA top = runSTUArray $ do<br />
let m = (top-1) `div` 2<br />
r = floor . sqrt $ fromIntegral top + 1<br />
sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)<br />
forM_ [1..r `div` 2] $ \i -> do<br />
isPrime <- readArray sieve i<br />
when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)<br />
forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do<br />
writeArray sieve j False<br />
return sieve<br />
<br />
primesToUA :: Int -> [Int]<br />
primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]<br />
</haskell><br />
<br />
Its [http://ideone.com/KwZNc empirical time complexity] is improving with ''n'' (number of primes produced) from above <math>O(n^{1.20})</math> towards <math>O(n^{1.16})</math>. The reference [http://ideone.com/FaPOB C++ vector-based implementation] exhibits this improvement in empirical time complexity too, from <math>O(n^{1.5})</math> gradually towards <math>O(n^{1.12})</math>, where tested ''(which might be interpreted as evidence towards the expected [http://en.wikipedia.org/wiki/Computation_time#Linearithmic.2Fquasilinear_time quasilinearithmic] <math>O(n \log(n)\log(\log n))</math> time complexity)''.<br />
<br />
=== Bitwise prime sieve with Template Haskell ===<br />
<br />
Count the number of prime below a given 'n'. Shows fast bitwise arrays,<br />
and an example of [[Template Haskell]] to defeat your enemies.<br />
<br />
<haskell><br />
{-# OPTIONS -O2 -optc-O -XBangPatterns #-}<br />
module Primes (nthPrime) where<br />
<br />
import Control.Monad.ST<br />
import Data.Array.ST<br />
import Data.Array.Base<br />
import System<br />
import Control.Monad<br />
import Data.Bits<br />
<br />
nthPrime :: Int -> Int<br />
nthPrime n = runST (sieve n)<br />
<br />
sieve n = do<br />
a <- newArray (3,n) True :: ST s (STUArray s Int Bool)<br />
let cutoff = truncate (sqrt $ fromIntegral n) + 1<br />
go a n cutoff 3 1<br />
<br />
go !a !m cutoff !n !c<br />
| n >= m = return c<br />
| otherwise = do<br />
e <- unsafeRead a n<br />
if e then<br />
if n < cutoff then<br />
let loop !j<br />
| j < m = do<br />
x <- unsafeRead a j<br />
when x $ unsafeWrite a j False<br />
loop (j+n)<br />
| otherwise = go a m cutoff (n+2) (c+1)<br />
in loop ( if n < 46340 then n * n else n `shiftL` 1)<br />
else go a m cutoff (n+2) (c+1)<br />
else go a m cutoff (n+2) c<br />
</haskell><br />
<br />
And place in a module:<br />
<br />
<haskell><br />
{-# OPTIONS -fth #-}<br />
import Primes<br />
<br />
main = print $( let x = nthPrime 10000000 in [| x |] )<br />
</haskell><br />
<br />
Run as:<br />
<br />
<haskell><br />
$ ghc --make -o primes Main.hs<br />
$ time ./primes<br />
664579<br />
./primes 0.00s user 0.01s system 228% cpu 0.003 total<br />
</haskell><br />
<br />
== Implicit Heap ==<br />
<br />
See [[Prime_numbers_miscellaneous#Implicit_Heap | Implicit Heap]].<br />
<br />
== Prime Wheels ==<br />
<br />
See [[Prime_numbers_miscellaneous#Prime_Wheels | Prime Wheels]].<br />
<br />
== Using IntSet for a traditional sieve ==<br />
<br />
See [[Prime_numbers_miscellaneous#Using_IntSet_for_a_traditional_sieve | Using IntSet for a traditional sieve]].<br />
<br />
== Testing Primality, and Integer Factorization ==<br />
<br />
See [[Testing_primality | Testing primality]]:<br />
<br />
* [[Testing_primality#Primality_Test_and_Integer_Factorization | Primality Test and Integer Factorization ]]<br />
* [[Testing_primality#Miller-Rabin_Primality_Test | Miller-Rabin Primality Test]]<br />
<br />
== One-liners ==<br />
See [[Prime_numbers_miscellaneous#One-liners | primes one-liners]].<br />
<br />
== External links ==<br />
* http://www.cs.hmc.edu/~oneill/code/haskell-primes.zip<br />
: A collection of prime generators; the file "ONeillPrimes.hs" contains one of the fastest pure-Haskell prime generators; code by Melissa O'Neill. <br />
: WARNING: Don't use the priority queue from ''older versions'' of that file for your projects: it's broken and works for primes only by a lucky chance. The ''revised'' version of the file fixes the bug, as pointed out by Eugene Kirpichov on February 24, 2009 on the [http://www.mail-archive.com/haskell-cafe@haskell.org/msg54618.html haskell-cafe] mailing list, and fixed by Bertram Felgenhauer.<br />
<br />
* [http://ideone.com/willness/primes test entries] for (some of) the above code variants.<br />
<br />
* Speed/memory [http://ideone.com/p0e81 comparison table] for sieve of Eratosthenes variants.<br />
<br />
* [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth Empirical orders of growth] on Wikipedia.<br />
<br />
[[Category:Code]]<br />
[[Category:Mathematics]]</div>WillNesshttps://wiki.haskell.org/Prime_numbersPrime numbers2015-09-24T10:36:31Z<p>WillNess: /* External links */ +1</p>
<hr />
<div>In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1).<br />
<br />
== Prime Number Resources ==<br />
<br />
* At Wikipedia:<br />
**[http://en.wikipedia.org/wiki/Prime_numbers Prime Numbers]<br />
**[http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes]<br />
<br />
* HackageDB packages:<br />
** [http://hackage.haskell.org/package/arithmoi arithmoi]: Various basic number theoretic functions; efficient array-based sieves, Montgomery curve factorization ...<br />
** [http://hackage.haskell.org/package/Numbers Numbers]: An assortment of number theoretic functions.<br />
** [http://hackage.haskell.org/package/NumberSieves NumberSieves]: Number Theoretic Sieves: primes, factorization, and Euler's Totient.<br />
** [http://hackage.haskell.org/package/primes primes]: Efficient, purely functional generation of prime numbers.<br />
<br />
* Papers:<br />
** O'Neill, Melissa E., [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf "The Genuine Sieve of Eratosthenes"], Journal of Functional Programming, Published online by Cambridge University Press 9 October 2008 doi:10.1017/S0956796808007004.<br />
<br />
== Definition ==<br />
<br />
In mathematics, ''amongst the natural numbers greater than 1'', a ''prime number'' (or a ''prime'') is such that has no divisors other than itself (and 1). The smallest prime is thus 2. Non-prime numbers are known as ''composite'', i.e. those representable as product of two natural numbers greater than 1. The set of prime numbers is thus<br />
<br />
: &nbsp;&nbsp; '''P''' &nbsp;= {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) ((''m'' | ''n'') &rArr; m = n)}<br />
<br />
:: = {''n'' &isin; '''N'''<sub>2</sub> ''':''' (&forall; ''m'' &isin; '''N'''<sub>2</sub>) (''m''&times;''m'' &le; ''n'' &rArr; &not;(''m'' | ''n''))}<br />
<br />
:: = '''N'''<sub>2</sub> \ {''n''&times;''m'' ''':''' ''n'',''m'' &isin; '''N'''<sub>2</sub>} <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''m'' ''':''' ''m'' &isin; '''N'''<sub>n</sub>} ''':''' ''n'' &isin; '''N'''<sub>2</sub> }<br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''N'''<sub>2</sub> } <br />
<br />
:: = '''N'''<sub>2</sub> \ '''&#8899;''' { {''n''&times;''n'', ''n''&times;''n''+''n'', ''n''&times;''n''+2&times;''n'', ...} ''':''' ''n'' &isin; '''P''' } <br />
:::: &nbsp; where &nbsp; &nbsp; '''N'''<sub>k</sub> = {''n'' &isin; '''N''' ''':''' ''n'' &ge; k}<br />
<br />
Thus starting with 2, for each newly found prime we can ''eliminate'' from the rest of the numbers ''all the multiples'' of this prime, giving us the next available number as next prime. This is known as ''sieving'' the natural numbers, so that in the end all the composites are eliminated and what we are left with are just primes. <small>(This is what the last formula is describing, though seemingly [http://en.wikipedia.org/wiki/Impredicativity impredicative], because it is self-referential. But because '''N'''<sub>2</sub> is well-ordered (with the order being preserved under addition), the formula is well-defined.)</small><br />
<br />
To eliminate a prime's multiples we can either '''a.''' test each new candidate number for divisibility by that prime, giving rise to a kind of ''trial division'' algorithm; or '''b.''' we can directly generate the multiples of a prime ''<code>p</code>'' by counting up from it in increments of ''<code>p</code>'', resulting in a variant of the ''sieve of Eratosthenes''. <br />
<br />
Having a direct-access mutable arrays indeed enables easy marking off of these multiples on pre-allocated array as it is usually done in imperative languages; but to get an [[#Tree merging with Wheel|efficient ''list''-based code]] we have to be smart about combining those streams of multiples of each prime - which gives us also the memory efficiency in generating the results incrementally, one by one.<br />
<br />
== Sieve of Eratosthenes ==<br />
<br />
The sieve of Eratosthenes calculates primes as ''integers above 1 that are not multiples of primes'', i.e. ''not composite'' &mdash; whereas composites are found as a union of sequences of multiples of each prime, generated by counting up from the prime's square in constant increments equal to that prime (or twice that much, for odd primes): <br />
<br />
<haskell><br />
primes = 2 : 3 : ([5,7..] `minus` _U [[p*p, p*p+2*p..] | p <- tail primes])<br />
<br />
{- Using `under n = takeWhile (<= n)`, with ordered increasing lists,<br />
`minus` and `_U` satisfy, for any `n`:<br />
under n (minus a b) == under n a \\ under n b<br />
under n (union a b) == nub . sort $ under n a ++ under n b<br />
under n . _U == nub . sort . concat . map (under n) -}<br />
</haskell><br />
<br />
The definition is primed with 2 and 3 as initial primes, to avoid the vicious circle.<br />
<br />
<code>_U</code> can be defined as a folding of <code>(\(x:xs) -> (x:) . union xs)</code>, or it can use a <code>Bool</code> array as a sorting and duplicates-removing device. The processing naturally divides up into segments between the successive squares of primes.<br />
<br />
Stepwise development follows (the fully developed version is [[#Tree merging with Wheel|here]]). <br />
<br />
=== Initial definition ===<br />
<br />
To start with, the sieve of Eratosthenes can be genuinely represented by <br />
<haskell><br />
-- genuine yet wasteful sieve of Eratosthenes<br />
-- primes = eratos [2.. ] -- unbounded<br />
primesTo m = eratos [2..m] where -- bounded, up to m<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p,p+p..])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [1..])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (p:xs)) <br />
-- turner (p:xs) = p : turner [x | x <- xs, rem x p /= 0] <br />
</haskell><br />
<br />
This should be regarded more like a ''specification'', not a code. It runs at [https://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth] worse than quadratic in number of primes produced. But it has the core defining features of the classical formulation of S. of E. as '''''a.''''' being bounded, i.e. having a top limit value, and '''''b.''''' finding out the multiples of a prime directly, by counting up from it in constant increments, equal to that prime.<br />
<br />
The canonical list-difference <code>minus</code> and duplicates-removing <code>union</code> functions dealing with ordered increasing lists (cf. [http://hackage.haskell.org/packages/archive/data-ordlist/latest/doc/html/Data-List-Ordered.html Data.List.Ordered package]) are:<br />
<haskell><br />
-- ordered lists, difference and union<br />
minus (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : minus xs (y:ys)<br />
EQ -> minus xs ys <br />
GT -> minus (x:xs) ys<br />
minus xs _ = xs<br />
union (x:xs) (y:ys) = case (compare x y) of <br />
LT -> x : union xs (y:ys)<br />
EQ -> x : union xs ys <br />
GT -> y : union (x:xs) ys<br />
union xs [] = xs<br />
union [] ys = ys<br />
</haskell><br />
<br />
The name ''merge'' ought to be reserved for duplicates-preserving merging operation of mergesort.<br />
<br />
=== Analysis ===<br />
<br />
So for each newly found prime ''p'' the sieve discards its multiples, enumerating them by counting up in steps of ''p''. There are thus <math>O(m/p)</math> multiples generated and eliminated for each prime, and <math>O(m \log \log(m))</math> multiples in total, with duplicates, by virtues of [http://en.wikipedia.org/wiki/Prime_harmonic_series prime harmonic series].<br />
<br />
If each multiple is dealt with in <math>O(1)</math> time, this will translate into <math>O(m \log \log(m))</math> RAM machine operations (since we consider addition as an atomic operation). Indeed mutable random-access arrays allow for that. But lists in Haskell are sequential-access, and complexity of <code>minus(a,b)</code> for lists is <math>\textstyle O(|a \cup b|)</math> instead of <math>\textstyle O(|b|)</math> of the direct access destructive array update. The lower the complexity of each ''minus'' step, the better the overall complexity.<br />
<br />
So on ''k''-th step the argument list <code>(p:xs)</code> that the <code>eratos</code> function gets, starts with the ''(k+1)''-th prime, and consists of all the numbers &le; ''m'' coprime with all the primes &le; ''p''. According to the M. O'Neill's article (p.10) there are <math>\textstyle\Phi(m,p) \in \Theta(m/\log p)</math> such numbers. <br />
<br />
It looks like <math>\textstyle\sum_{i=1}^{n}{1/log(p_i)} = O(n/\log n)</math> for our intents and purposes. Since the number of primes below ''m'' is <math>n = \pi(m) = O(m/\log(m))</math> by the prime number theorem (where <math>\pi(m)</math> is a prime counting function), there will be ''n'' multiples-removing steps in the algorithm; it means total complexity of at least <math>O(m n/\log(n)) = O(m^2/(\log(m))^2)</math>, or <math>O(n^2)</math> in ''n'' primes produced - much much worse than the optimal <math>O(n \log(n) \log\log(n))</math>.<br />
<br />
=== From Squares ===<br />
<br />
But we can start each elimination step at a prime's square, as its smaller multiples will have been already produced and discarded on previous steps, as multiples of smaller primes. This means we can stop early now, when the prime's square reaches the top value ''m'', and thus cut the total number of steps to around <math>\textstyle n = \pi(m^{0.5}) = \Theta(2m^{0.5}/\log m)</math>. This does not in fact change the complexity of random-access code, but for lists it makes it <math>O(m^{1.5}/(\log m)^2)</math>, or <math>O(n^{1.5}/(\log n)^{0.5})</math> in ''n'' primes produced, a dramatic speedup: <br />
<haskell><br />
primesToQ m = eratos [2..m] where<br />
eratos [] = []<br />
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])<br />
-- eratos (p:xs) = p : eratos (xs `minus` map (p*) [p..div m p])<br />
-- eulers (p:xs) = p : eulers (xs `minus` map (p*) (under (div m p) (p:xs)))<br />
-- turner (p:xs) = p : turner [x | x<-xs, x<p*p || rem x p /= 0] <br />
</haskell><br />
<br />
Its empirical complexity is around <math>O(n^{1.45})</math>. This simple optimization works here because this formulation is bounded (by an upper limit). To start late on a bounded sequence is to stop early (starting past end makes an empty sequence &ndash; ''see warning below''<sup><sub> 1</sub></sup>), thus preventing the creation of all the superfluous multiples streams which start above the upper bound anyway <small>(note that Turner's sieve is unaffected by this)</small>. This is acceptably slow now, striking a good balance between clarity, succinctness and efficiency.<br />
<br />
<sup><sub>1</sub></sup><small>''Warning'': this is predicated on a subtle point of <code>minus xs [] = xs</code> definition being used, as it indeed should be. If the definition <code>minus (x:xs) [] = x:minus xs []</code> is used, the problem is back and the complexity is bad again.</small><br />
<br />
=== Guarded ===<br />
This ought to be ''explicated'' (improving on clarity, though not on time complexity) as in the following, for which it is indeed a minor optimization whether to start from ''p'' or ''p*p'' - because it explicitly ''stops as soon as possible'':<br />
<haskell><br />
primesToG m = 2 : sieve [3,5..m] where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| otherwise = p : sieve (xs `minus` [p*p, p*p+2*p..])<br />
-- p : sieve (xs `minus` map (p*) [p,p+2..])<br />
-- p : eulers (xs `minus` map (p*) (p:xs)) <br />
</haskell><br />
(here we also dismiss all evens above 2 a priori.) It is now clear that it ''can't'' be made unbounded just by abolishing the upper bound ''m'', because the guard can not be simply omitted without changing the complexity back for the worst.<br />
<br />
=== Accumulating Array ===<br />
<br />
So while <code>minus(a,b)</code> takes <math>O(|b|)</math> operations for random-access imperative arrays and about <math>O(|a|)</math> operations here for ordered increasing lists of numbers, using Haskell's immutable array for ''a'' one ''could'' expect the array update time to be nevertheless closer to <math>O(|b|)</math> if destructive update were used implicitly by compiler for an array being passed along as an accumulating parameter:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 #-}<br />
import Data.Array.Unboxed<br />
<br />
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]]<br />
:: UArray Int Bool)<br />
where<br />
sieve p a <br />
| p*p > m = 2 : [i | (i,True) <- assocs a]<br />
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]<br />
| otherwise = sieve (p+2) a<br />
</haskell><br />
<br />
Indeed for unboxed arrays, with the type signature added explicitly <small>(suggested by Daniel Fischer)</small>, the above code runs pretty fast, with empirical complexity of about ''<math>O(n^{1.15..1.45})</math>'' in ''n'' primes produced (for producing from few hundred thousands to few millions primes, memory usage also slowly growing). But it relies on specific compiler optimizations, and indeed if we remove the explicit type signature, the code above turns ''very'' slow.<br />
<br />
How can we write code that we'd be certain about? One way is to use explicitly mutable monadic arrays ([[#Using Mutable Arrays|''see below'']]), but we can also think about it a little bit more on the functional side of things still.<br />
<br />
=== Postponed ===<br />
Going back to ''guarded'' Eratosthenes, first we notice that though it works with minimal number of prime multiples streams, it still starts working with each prematurely. Fixing this with explicit synchronization won't change complexity but will speed it up some more:<br />
<haskell><br />
primesPE1 = 2 : sieve [3..] primesPE1 <br />
where <br />
sieve xs (p:ps) | q <- p*p , (h,t) <- span (< q) xs =<br />
h ++ sieve (t `minus` [q, q+p..]) ps<br />
-- h ++ turner [x|x<-t, rem x p /= 0] ps<br />
</haskell><br />
<!-- primesPE1 = 2 : sieve [3,5..] 9 (tail primesPE1)<br />
where <br />
sieve xs q ~(p:t) | (h,ys) <- span (< q) xs =<br />
h ++ sieve (ys `minus` [q, q+2*p..]) (head t^2) t<br />
-- h ++ turner [x | x <- ys, rem x p /= 0] ...<br />
--><br />
Inlining and fusing <code>span</code> and <code>(++)</code> we get:<br />
<haskell><br />
primesPE = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| otherwise = sieve (xs `minus` [q, q+2*p..]) (head t^2) t<br />
</haskell><br />
Since the removal of a prime's multiples here starts at the right moment, and not just from the right place, the code can now finally be made unbounded. Because no multiples-removal process is started ''prematurely'', there are no ''extraneous'' multiples streams, which were the reason for the original formulation's extreme inefficiency.<br />
<br />
=== Segmented ===<br />
With work done segment-wise between the successive squares of primes it becomes <br />
<br />
<haskell><br />
primesSE = 2 : oddprimes<br />
where<br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
foldr (flip minus) [x,x+2..q-2] <br />
[[y+s, y+2*s..q] | (s,y) <- fs]<br />
++ sieve (q+2) (head t^2) t<br />
((2*p,q):[(s,q-rem (q-y) s) | (s,y) <- fs])<br />
</haskell> <br />
<br />
This "marks" the odd composites in a given range by generating them - just as a person performing the original sieve of Eratosthenes would do, counting ''one by one'' the multiples of the relevant primes. These composites are independently generated so some will be generated multiple times. <br />
<br />
The advantage to working in spans explicitly is that this code is easily amendable to using arrays for the composites marking and removal on each ''finite'' span; and memory usage can be kept in check by using fixed sized segments.<br />
<br />
====Segmented Tree-merging====<br />
Rearranging the chain of subtractions into a subtraction of merged streams ''([[#Linear merging|see below]])'' and using [[#Tree merging|tree-like folding]] structure, further [http://ideone.com/pfREP speeds up the code] and ''significantly'' improves its asymptotic time behavior (down to about <math>O(n^{1.28} empirically)</math>, space is leaking though):<br />
<br />
<haskell><br />
primesSTE = 2 : oddprimes<br />
where <br />
oddprimes = sieve 3 9 oddprimes []<br />
sieve x q ~(p:t) fs = <br />
([x,x+2..q-2] `minus` joinST [[y+s, y+2*s..q] | (s,y) <- fs])<br />
++ sieve (q+2) (head t^2) t<br />
((++ [(2*p,q)]) [(s,q-rem (q-y) s) | (s,y) <- fs])<br />
<br />
joinST (xs:t) = (union xs . joinST . pairs) t where<br />
pairs (xs:ys:t) = union xs ys : pairs t<br />
pairs t = t<br />
joinST [] = []<br />
</haskell><br />
<br />
====Segmented merging via an array====<br />
<br />
The removal of composites is easy with arrays. Starting points can be calculated directly:<br />
<br />
<haskell><br />
import Data.List (inits)<br />
import Data.Array.Unboxed<br />
<br />
primesSAE = 2 : sieve 3 4 (tail primesSAE) (inits primesSAE)<br />
where<br />
sieve x q ps (fs:ft) = [i | (i,True) <- assocs (<br />
accumArray (\ _ _ -> False)<br />
True (x,q-1)<br />
[(i,()) | p <- fs, let c = p * div (x+p-1) p,<br />
i <- [c, c+p..q-1]] :: UArray Int Bool )]<br />
++ sieve q (head ps^2) (tail ps) ft<br />
</haskell><br />
<br />
=== Linear merging ===<br />
But segmentation doesn't add anything substantially, and each multiples stream starts at its prime's square anyway. What does the [[#Postponed|Postponed]] code do, operationally? With each prime's square passed by, there emerges a nested linear ''left-deepening'' structure, '''''(...((xs-a)-b)-...)''''', where '''''xs''''' is the original odds-producing ''[3,5..]'' list, so that each odd it produces must go through more and more <code>minus</code> nodes on its way up - and those odd numbers that eventually emerge on top are prime. Thinking a bit about it, wouldn't another, ''right-deepening'' structure, '''''(xs-(a+(b+...)))''''', be better? This idea is due to Richard Bird, seen in his code presented in M. O'Neill's article, equivalent to:<br />
<haskell><br />
primesB = 2 : minus [3..] (foldr (\p r-> p*p : union [p*p+p, p*p+2*p..] r) <br />
[] primesB)<br />
</haskell><br />
or,<br />
<br />
<haskell><br />
primesLME1 = 2 : prs where<br />
prs = 3 : minus [5,7..] (joinL [[p*p, p*p+2*p..] | p <- prs])<br />
<br />
joinL ((x:xs):t) = x : union xs (joinL t)<br />
</haskell><br />
<br />
Here, ''xs'' stays near the top, and ''more frequently'' odds-producing streams of multiples of smaller primes are ''above'' those of the bigger primes, that produce ''less frequently'' their multiples which have to pass through ''more'' <code>union</code> nodes on their way up. Plus, no explicit synchronization is necessary anymore because the produced multiples of a prime start at its square anyway - just some care has to be taken to avoid a runaway access to the indefinitely-defined structure, defining <code>joinL</code> (or <code>foldr</code>'s combining function) to produce part of its result ''before'' accessing the rest of its input (making it ''productive'').<br />
<br />
Melissa O'Neill [http://hackage.haskell.org/packages/archive/NumberSieves/0.0/doc/html/src/NumberTheory-Sieve-ONeill.html introduced double primes feed] to prevent unneeded memoization (a memory leak). We can even do multistage. Here's the code, faster still and with radically reduced memory consumption, with empirical orders of growth of around ~ <math>n^{1.40}</math> (initially better, yet worsening for bigger ranges):<br />
<br />
<haskell><br />
primesLME = 2 : _Y ((3:) . minus [5,7..] . joinL . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
_Y :: (t -> t) -> t<br />
_Y g = g (_Y g) -- multistage, non-sharing, recursive<br />
-- g x where x = g x -- two stages, sharing, corecursive<br />
</haskell><br />
<br />
<code>_Y</code> is a non-sharing fixpoint combinator, here arranging for a recursive ''"telescoping"'' multistage primes production (a ''tower'' of producers).<br />
<br />
This allows the <code>primesLME</code> stream to be discarded immediately as it is being consumed by its consumer. With <code>primes'</code> from <code>primesLME1</code> definition above it is impossible, as each produced element of <code>primes'</code> is needed later as input to the same <code>primes'</code> corecursive stream definition. So the <code>primes'</code> stream feeds in a loop into itself, and thus is retained in memory. With multistage production, each stage feeds into its consumer above it at the square of its current element which can be immediately discarded after it's been consumed. <code>(3:)</code> jump-starts the whole thing.<br />
<br />
=== Tree merging ===<br />
Moreover, it can be changed into a '''''tree''''' structure. This idea [http://www.haskell.org/pipermail/haskell-cafe/2007-July/029391.html is due to Dave Bayer] and [[Prime_numbers_miscellaneous#Implicit_Heap|Heinrich Apfelmus]]:<br />
<br />
<haskell><br />
primesTME = 2 : _Y ((3:) . gaps 5 . joinT . map (\p-> [p*p, p*p+2*p..]))<br />
<br />
joinT ((x:xs):t) = x : (union xs . joinT . pairs) t -- set union, ~=<br />
where pairs (xs:ys:t) = union xs ys : pairs t -- nub.sort.concat<br />
<br />
gaps k s@(x:xs) | k < x = k:gaps (k+2) s -- ~= [k,k+2..]\\s, <br />
| True = gaps (k+2) xs -- when null(s\\[k,k+2..])<br />
</haskell><br />
<br />
This code is [http://ideone.com/p0e81 pretty fast], running at speeds and empirical complexities comparable with the code from Melissa O'Neill's article (about <math>O(n^{1.2})</math> in number of primes ''n'' produced).<br />
<br />
As an aside, <code>joinT</code> is equivalent to [[Fold#Tree-like_folds|infinite tree-like folding]] <code>foldi (\(x:xs) ys-> x:union xs ys) []</code>:<br />
<br />
[[Image:Tree-like_folding.gif|frameless|center|458px|tree-like folding]]<br />
<br />
=== Tree merging with Wheel ===<br />
Wheel factorization optimization can be further applied, and another tree structure can be used which is better adjusted for the primes multiples production (effecting about 5%-10% at the top of a total ''2.5x speedup'' w.r.t. the above tree merging on odds only, for first few million primes):<br />
<br />
<haskell><br />
primesTMWE = [2,3,5,7] ++ _Y ((11:) . tail . gapsW 11 wheel <br />
. joinT . hitsW 11 wheel)<br />
<br />
gapsW k (d:w) s@(c:cs) | k < c = k : gapsW (k+d) w s -- set difference<br />
| otherwise = gapsW (k+d) w cs -- k==c<br />
hitsW k (d:w) s@(p:ps) | k < p = hitsW (k+d) w s -- intersection<br />
| otherwise = scanl (\c d->c+p*d) (p*p) (d:w) <br />
: hitsW (k+d) w ps -- k==p <br />
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2:<br />
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel<br />
</haskell><br />
<br />
The <code>hitsW</code> is there to find the start point for rolling the wheel for each prime, but it can be found directly:<br />
<br />
<haskell><br />
primesW = [2,3,5,7] ++ _Y ( (11:) . tail . gapsW 11 wheel . joinT .<br />
map (\p-> <br />
map (p*) . dropWhile (< p) $<br />
scanl (+) (p - rem (p-11) 210) wheel) ) <br />
</haskell><br />
<br />
Seems to run about 1.4x faster, too.<br />
<br />
====Above Limit - Offset Sieve====<br />
Another task is to produce primes above a given value:<br />
<haskell><br />
{-# OPTIONS_GHC -O2 -fno-cse #-}<br />
primesFromTMWE primes m = dropWhile (< m) [2,3,5,7,11] <br />
++ gapsW a wh2 (compositesFrom a)<br />
where<br />
(a,wh2) = rollFrom (snapUp (max 3 m) 3 2)<br />
(h,p2:t) = span (< z) $ drop 4 primes -- p < z => p*p<=a<br />
z = ceiling $ sqrt $ fromIntegral a + 1 -- p2>=z => p2*p2>a<br />
compositesFrom a = joinT (joinST [multsOf p a | p <- h ++ [p2]]<br />
: [multsOf p (p*p) | p <- t] )<br />
<br />
snapUp v o step = v + (mod (o-v) step) -- full steps from o<br />
multsOf p from = scanl (\c d->c+p*d) (p*x) wh -- map (p*) $<br />
where -- scanl (+) x wh<br />
(x,wh) = rollFrom (snapUp from p (2*p) `div` p) -- , if p < from <br />
wheelNums = scanl (+) 0 wheel<br />
rollFrom n = go wheelNums wheel <br />
where m = (n-11) `mod` 210 <br />
go (x:xs) ws@(w:ws2) | x < m = go xs ws2<br />
| True = (n+x-m, ws) -- (x >= m)<br />
</haskell><br />
<br />
A certain preprocessing delay makes it worthwhile when producing more than just a few primes, otherwise it degenerates into simple [[#Optimal trial division|trial division]], which is then ought to be used directly:<br />
<br />
<haskell><br />
primesFrom m = filter isPrime [m..]<br />
</haskell><br />
<br />
=== Map-based ===<br />
Runs ~1.7x slower than [[#Tree_merging|TME version]], but with the same empirical time complexity, ~<math>n^{1.2}</math> (in ''n'' primes produced) and same very low (near constant) memory consumption:<br />
<br />
<haskell><br />
import Data.List -- based on http://stackoverflow.com/a/1140100<br />
import qualified Data.Map as M<br />
<br />
primesMPE :: [Integer]<br />
primesMPE = 2:mkPrimes 3 M.empty prs 9 -- postponed addition of primes into map;<br />
where -- decoupled primes loop feed <br />
prs = 3:mkPrimes 5 M.empty prs 9<br />
mkPrimes n m ps@ ~(p:t) q = case (M.null m, M.findMin m) of<br />
(False, (n2, skips)) | n == n2 -><br />
mkPrimes (n+2) (addSkips n (M.deleteMin m) skips) ps q<br />
_ -> if n<q<br />
then n : mkPrimes (n+2) m ps q<br />
else mkPrimes (n+2) (addSkip n m (2*p)) t (head t^2)<br />
<br />
addSkip n m s = M.alter (Just . maybe [s] (s:)) (n+s) m<br />
addSkips = foldl' . addSkip<br />
</haskell><br />
<br />
== Turner's sieve - Trial division ==<br />
<br />
David Turner's original 1975 formulation ''(SASL Language Manual, 1975)'' replaces non-standard <code>minus</code> in the sieve of Eratosthenes by stock list comprehension with <code>rem</code> filtering, turning it into a trial division algorithm:<br />
<br />
<haskell><br />
-- unbounded sieve, premature filters<br />
primesT = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]<br />
-- map fst . tail <br />
-- $ iterate (\(_,p:xs)->(p, [x | x <- xs, rem x p /= 0])) (1,[2..])<br />
</haskell><br />
<br />
This creates many superfluous implicit filters, because they are created prematurely. To be admitted as prime, ''each number'' will be ''tested for divisibility'' here by all its preceding primes, while just those not greater than its square root would suffice. To find e.g. the '''1001'''st prime (<code>7927</code>), '''1000''' filters are used, when in fact just the first '''24''' are needed (up to <code>89</code>'s filter only). Operational overhead here is huge.<br />
<br />
=== Guarded Filters ===<br />
But this really ought to be changed into bounded and guarded variant, [[#From Squares|again achieving]] the ''"miraculous"'' complexity improvement from above quadratic to about <math>O(n^{1.45})</math> empirically (in ''n'' primes produced):<br />
<br />
<haskell><br />
primesToGT m = sieve [2..m]<br />
where<br />
sieve (p:xs) <br />
| p*p > m = p : xs<br />
| True = p : sieve [x | x <- xs, rem x p /= 0]<br />
-- (\(a,(p,xs):_)-> map fst a ++ p:xs) . span ((< m).(^2).fst) . tail<br />
-- $ iterate (\(_,p:xs)->(p, [x | x <- xs, rem x p /= 0])) (1,[2..m])<br />
</haskell><br />
<br />
=== Postponed Filters ===<br />
Or it can remain unbounded, just filters creation must be ''postponed'' until the right moment:<br />
<haskell><br />
primesPT1 = 2 : sieve primesPT1 [3..] <br />
where <br />
sieve (p:ps) xs = let (h,t) = span (< p*p) xs <br />
in h ++ sieve ps [x | x<-t, rem x p /= 0]<br />
-- fix $ concat . map fst . <br />
-- iterate (\(_,(xs,p:ps))->let (h,t)=span (< p*p) xs in<br />
-- (h, ([x | x <- t, rem x p /= 0], ps))) . ((,) [2]) . ((,) [3..])<br />
</haskell><br />
This is better re-written with <code>span</code> and <code>(++)</code> inlined and fused into the <code>sieve</code>:<br />
<haskell><br />
primesPT = 2 : oddprimes<br />
where <br />
oddprimes = sieve [3,5..] 9 oddprimes<br />
sieve (x:xs) q ps@ ~(p:t)<br />
| x < q = x : sieve xs q ps<br />
| True = sieve [x | x <- xs, rem x p /= 0] (head t^2) t<br />
</haskell><br />
creating here [[#Linear merging |as well]] the linear nested structure at run-time, <code>(...(([3,5..] >>= filterBy [3]) >>= filterBy [5])...)</code>, where <code&