primal_slowsieve/
lib.rs

1//! Sieve small numbers.
2//!
3//! This is designed to be used via the `primal` crate.
4
5use primal_bit::BitVec;
6use std::{iter, cmp};
7
8/// Stores information about primes up to some limit.
9///
10/// This uses at least `limit / 16 + O(1)` bytes of storage.
11#[derive(Debug)]
12pub struct Primes {
13    // This only stores odd numbers, since even numbers are mostly
14    // non-prime.
15    //
16    // This indicates which numbers are composite.
17    v: BitVec
18}
19
20/// Iterator over the primes stored in a sieve.
21#[derive(Clone)]
22pub struct PrimeIterator<'a> {
23    two: bool,
24    iter: iter::Enumerate<primal_bit::Iter<'a>>,
25}
26
27impl Primes {
28    /// Construct a `Primes` via a sieve up to at least `limit`.
29    ///
30    /// This stores all primes less than `limit` (and possibly some
31    /// more), allowing for very efficient iteration and primality
32    /// testing below this, and guarantees that all numbers up to
33    /// `limit^2` can be factorised.
34    pub fn sieve(limit: usize) -> Primes {
35        // having this out-of-line like this is faster (130 us/iter
36        // vs. 111 us/iter on sieve_large), and using a manual while
37        // rather than a `range_step` is a similar speedup.
38        #[inline(never)]
39        fn filter(is_prime: &mut BitVec, limit: usize, p: usize) {
40            let mut zero = p * p / 2;
41            while zero < limit / 2 {
42                is_prime.set(zero, true);
43                zero += p;
44            }
45        }
46
47        // bad stuff happens for very small bounds.
48        let limit = cmp::max(10, limit);
49
50        let mut is_prime = BitVec::from_elem((limit + 1) / 2, false);
51        // 1 isn't prime
52        is_prime.set(0, true);
53
54        // multiples of 3 aren't prime (3 is handled separately, so
55        // the ticking works properly)
56        filter(&mut is_prime, limit, 3);
57
58        let bound = (limit as f64).sqrt() as usize + 1;
59        // skip 2.
60        let mut check = 2;
61        let mut tick = if check % 3 == 1 {2} else {1};
62
63        while check <= bound {
64            if !is_prime[check] {
65                filter(&mut is_prime, limit, 2 * check + 1)
66            }
67
68            check += tick;
69            tick = 3 - tick;
70        }
71
72        Primes { v: is_prime }
73    }
74
75    /// The largest number stored.
76    pub fn upper_bound(&self) -> usize {
77        self.v.len() * 2
78    }
79
80    /// Check if `n` is prime, possibly failing if `n` is larger than
81    /// the upper bound of this Primes instance.
82    pub fn is_prime(&self, n: usize) -> bool {
83        if n % 2 == 0 {
84            // 2 is the evenest prime.
85            n == 2
86        } else {
87            assert!(n <= self.upper_bound());
88            !self.v[n / 2]
89        }
90    }
91
92    /// Iterator over the primes stored in this map.
93    pub fn primes(&self) -> PrimeIterator<'_> {
94        PrimeIterator {
95            two: true,
96            iter: self.v.iter().enumerate()
97        }
98    }
99
100    /// Factorise `n` into (prime, exponent) pairs.
101    ///
102    /// Returns `Err((leftover, partial factorisation))` if `n` cannot
103    /// be fully factored, or if `n` is zero (`leftover == 0`). A
104    /// number can not be completely factored if and only if the prime
105    /// factors of `n` are too large for this sieve, that is, if there
106    /// is
107    ///
108    /// - a prime factor larger than `U^2`, or
109    /// - more than one prime factor between `U` and `U^2`
110    ///
111    /// where `U` is the upper bound of the primes stored in this
112    /// sieve.
113    ///
114    /// Notably, any number between `U` and `U^2` can always be fully
115    /// factored, since these numbers are guaranteed to only have zero
116    /// or one prime factors larger than `U`.
117    pub fn factor(&self, mut n: usize) -> Result<Vec<(usize,usize)>,
118                                                 (usize, Vec<(usize, usize)>)>
119    {
120        if n == 0 { return Err((0, vec![])) }
121
122        let mut ret = Vec::new();
123
124        for p in self.primes() {
125            if n == 1 { break }
126
127            let mut count = 0;
128            while n % p == 0 {
129                n /= p;
130                count += 1;
131            }
132            if count > 0 {
133                ret.push((p,count));
134            }
135        }
136        if n != 1 {
137            let b = self.upper_bound();
138            if b * b >= n {
139                // n is not divisible by anything from 1..=sqrt(n), so
140                // must be prime itself! (That is, even though we
141                // don't know this prime specifically, we can infer
142                // that it must be prime.)
143                ret.push((n, 1));
144            } else {
145                // large factors :(
146                return Err((n, ret))
147            }
148        }
149        Ok(ret)
150    }
151
152    /// Count the primes upto and including `n`.
153    ///
154    /// # Panics
155    ///
156    /// `count_upto` panics if `n > self.upper_bound()`.
157    pub fn count_upto(&self, n: usize) -> usize {
158        if n < 2 { return 0 }
159
160        assert!(n <= self.upper_bound());
161        let bit = (n + 1) / 2;
162        1 + (bit - self.v.count_ones_before(bit))
163    }
164}
165
166impl<'a> Iterator for PrimeIterator<'a> {
167    type Item = usize;
168    #[inline]
169    fn next(&mut self) -> Option<usize> {
170        if self.two {
171            self.two = false;
172            Some(2)
173        } else {
174            for (i, is_not_prime) in &mut self.iter {
175                if !is_not_prime {
176                    return Some(2 * i + 1)
177                }
178            }
179            None
180        }
181    }
182
183    fn size_hint(&self) -> (usize, Option<usize>) {
184        let mut iter = self.clone();
185        // TODO: this doesn't run in constant time, is it super-bad?
186        match (iter.next(), iter.next_back()) {
187            (Some(lo), Some(hi)) => {
188                let (below_hi, above_hi) = primal_estimate::prime_pi(hi as u64);
189                let (below_lo, above_lo) = primal_estimate::prime_pi(lo as u64);
190
191                ((below_hi - cmp::min(above_lo, below_hi)) as usize,
192                 Some((above_hi - below_lo + 1) as usize))
193            }
194            (Some(_), None) => (1, Some(1)),
195            (None, _) => (0, Some(0))
196        }
197    }
198}
199
200impl<'a> DoubleEndedIterator for PrimeIterator<'a> {
201    #[inline]
202    fn next_back(&mut self) -> Option<usize> {
203        loop {
204            match self.iter.next_back() {
205                Some((i, false)) => return Some(2 * i + 1),
206                Some((_, true)) => {/* continue */}
207                None if self.two => {
208                    self.two = false;
209                    return Some(2)
210                }
211                None => return None
212            }
213        }
214    }
215}
216
217
218#[cfg(test)]
219mod tests {
220    use super::Primes;
221
222    #[test]
223    fn is_prime() {
224        let primes = Primes::sieve(1000);
225        let tests = [
226            (0, false),
227            (1, false),
228            (2, true),
229            (3, true),
230            (4, false),
231            (5, true),
232            (6, false),
233            (7, true),
234            (8, false),
235            (9, false),
236            (10, false),
237            (11, true)
238                ];
239
240        for &(n, expected) in tests.iter() {
241            assert_eq!(primes.is_prime(n), expected);
242        }
243    }
244
245    #[test]
246    fn upper_bound() {
247        for i in 1..1000 {
248            let primes = Primes::sieve(i);
249            assert!(primes.upper_bound() >= i);
250        }
251
252        let range = if cfg!(feature = "slow_tests") {
253            1..200
254        } else {
255            100..120
256        };
257        for i in range {
258            let i = i * 10000;
259            let primes = Primes::sieve(i);
260            assert!(primes.upper_bound() >= i);
261        }
262    }
263
264    #[test]
265    fn primes_iterator() {
266        let primes = Primes::sieve(50);
267        let mut expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
268
269        assert_eq!(primes.primes().collect::<Vec<usize>>(), expected);
270
271        expected.reverse();
272        assert_eq!(primes.primes().rev().collect::<Vec<usize>>(), expected);
273    }
274
275    #[test]
276    fn factor() {
277        let primes = Primes::sieve(1000);
278
279        let tests: &[(usize, &[(usize, usize)])] = &[
280            (1, &[]),
281            (2, &[(2_usize, 1)]),
282            (3, &[(3, 1)]),
283            (4, &[(2, 2)]),
284            (5, &[(5, 1)]),
285            (6, &[(2, 1), (3, 1)]),
286            (7, &[(7, 1)]),
287            (8, &[(2, 3)]),
288            (9, &[(3, 2)]),
289            (10, &[(2, 1), (5, 1)]),
290
291            (2*2*2*2*2 * 3*3*3*3*3, &[(2, 5), (3,5)]),
292            (2*3*5*7*11*13*17*19, &[(2,1), (3,1), (5,1), (7,1), (11,1), (13,1), (17,1), (19,1)]),
293            // a factor larger than that stored in the map
294            (7561, &[(7561, 1)]),
295            (2*7561, &[(2, 1), (7561, 1)]),
296            (4*5*7561, &[(2, 2), (5,1), (7561, 1)]),
297            ];
298        for &(n, expected) in tests.iter() {
299            assert_eq!(primes.factor(n), Ok(expected.to_vec()));
300        }
301    }
302
303    #[test]
304    fn factor_compare() {
305        let short = Primes::sieve(30);
306        let long = Primes::sieve(10000);
307
308        let short_lim = short.upper_bound() * short.upper_bound() + 1;
309
310        // every number less than bound^2 can be factored (since they
311        // always have a factor <= bound).
312        for n in 0..short_lim {
313            assert_eq!(short.factor(n), long.factor(n))
314        }
315        // larger numbers can only sometimes be factored
316        'next_n: for n in short_lim..10000 {
317            let possible = short.factor(n);
318            let real = long.factor(n).ok().unwrap();
319
320            let mut seen_small = None;
321            for (this_idx, &(p,i)) in real.iter().enumerate() {
322                let last_short_prime = if p >= short_lim {
323                    this_idx
324                } else if p > short.upper_bound() {
325                    match seen_small {
326                        Some(idx) => idx,
327                        None if i > 1 => this_idx,
328                        None => {
329                            // we can cope with one
330                            seen_small = Some(this_idx);
331                            continue
332                        }
333                    }
334                } else {
335                    // small enough
336                    continue
337                };
338
339                // break into the two parts
340                let (low, hi) = real.split_at(last_short_prime);
341                let leftover = hi.iter().fold(1, |x, &(p, i)| x * p.pow(i as u32));
342
343                assert_eq!(possible, Err((leftover, low.to_vec())));
344                continue 'next_n;
345            }
346
347            // if we're here, we know that everything should match
348            assert_eq!(possible, Ok(real))
349        }
350    }
351
352    #[test]
353    fn factor_failures() {
354        let primes = Primes::sieve(30);
355
356        assert_eq!(primes.factor(0),
357                   Err((0, vec![])));
358        // can only handle one large factor
359        assert_eq!(primes.factor(31 * 31),
360                   Err((31 * 31, vec![])));
361        assert_eq!(primes.factor(2 * 3 * 31 * 31),
362                   Err((31 * 31, vec![(2, 1), (3, 1)])));
363
364        // prime that's too large (bigger than 30*30).
365        assert_eq!(primes.factor(7561),
366                   Err((7561, vec![])));
367        assert_eq!(primes.factor(2 * 3 * 7561),
368                   Err((7561, vec![(2, 1), (3, 1)])));
369    }
370
371    #[test]
372    fn size_hint() {
373        let mut i = 0;
374        while i < 1000 {
375            let sieve = Primes::sieve(i);
376
377            let mut primes = sieve.primes();
378
379            // check the size hint at each and every iteration
380            loop {
381                let (lo, hi) = primes.size_hint();
382
383                let copy = primes.clone();
384                let len = copy.count();
385
386                let next = primes.next();
387
388                assert!(lo <= len && len <= hi.unwrap(),
389                        "found failing size_hint for {:?} to {}, should satisfy: {} <= {} <= {:?}",
390                        next, i, lo, len, hi);
391
392                if next.is_none() {
393                    break
394                }
395            }
396
397            i += 100;
398        }
399    }
400
401    #[test]
402    fn count_upto() {
403        let (limit, mult) = if cfg!(feature = "slow_tests") {
404            (2_000_000, 19_998)
405        } else {
406            (200_000, 1_998)
407        };
408        let sieve = Primes::sieve(limit);
409
410        for i in (0..20).chain((0..100).map(|n| n * mult + 1)) {
411            let val = sieve.count_upto(i);
412            let true_ = sieve.primes().take_while(|p| *p <= i).count();
413            assert!(val == true_, "failed for {}, true {}, computed {}",
414                    i, true_, val)
415        }
416    }
417}