Skip to main content

malachite_base/num/factorization/
primes.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library and the FLINT Library.
4//
5// Prime sieve code contributed to the GNU project by Marco Bodrato.
6//
7//      Copyright © 2009 Tom Boothby
8//
9//      Copyright © 2009 William Hart
10//
11//      Copyright © 2010 Fredrik Johansson
12//
13//      Copyright © 2010–2012, 2015, 2016 Free Software Foundation, Inc.
14//
15// This file is part of Malachite.
16//
17// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
18// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
19// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
20
21use crate::num::basic::unsigneds::PrimitiveUnsigned;
22use crate::num::conversion::traits::{ExactFrom, WrappingFrom};
23use crate::num::factorization::prime_sieve::{
24    id_to_n, limbs_prime_sieve_size, limbs_prime_sieve_u64, n_to_bit,
25};
26use crate::num::factorization::traits::Primes;
27use crate::num::logic::traits::TrailingZeros;
28use alloc::vec::Vec;
29use core::marker::PhantomData;
30
31const NUM_SMALL_PRIMES: usize = 172;
32// The same count as a `u64`, for comparing against the `u64` index of a prime iterator.
33const NUM_SMALL_PRIMES_U64: u64 = NUM_SMALL_PRIMES as u64;
34
35// The sieve bit index of the first prime past the small-prime table (1031 is the next prime after
36// 1021, the largest prime below 2^10).
37const NEXT_INDEX: u64 = n_to_bit(1031) - 1;
38
39// This is flint_primes_small from ulong_extras/compute_primes.c, FLINT 3.1.2.
40pub(crate) const SMALL_PRIMES: [u16; NUM_SMALL_PRIMES] = [
41    2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
42    101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
43    197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307,
44    311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
45    431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547,
46    557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
47    661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
48    809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929,
49    937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021,
50];
51
52// This differs from the identically-named function in malachite-nz; this one returns None if there
53// are no more false bits.
54fn limbs_index_of_next_false_bit<T: PrimitiveUnsigned>(xs: &[T], start: u64) -> Option<u64> {
55    let starting_index = usize::exact_from(start >> T::LOG_WIDTH);
56    if starting_index >= xs.len() {
57        return None;
58    }
59    if let Some(result) = xs[starting_index].index_of_next_false_bit(start & T::WIDTH_MASK)
60        && result != T::WIDTH
61    {
62        return Some((u64::wrapping_from(starting_index) << T::LOG_WIDTH) + result);
63    }
64    if starting_index == xs.len() - 1 {
65        return None;
66    }
67    let false_index = starting_index
68        + 1
69        + xs[starting_index + 1..]
70            .iter()
71            .take_while(|&&y| y == T::MAX)
72            .count();
73    if false_index == xs.len() {
74        None
75    } else {
76        Some(
77            (u64::exact_from(false_index) << T::LOG_WIDTH)
78                + TrailingZeros::trailing_zeros(!xs[false_index]),
79        )
80    }
81}
82
83/// An iterator over that generates all primes less than a given value.
84///
85/// This `struct` is created by [`Primes::primes_less_than`] and
86/// [`Primes::primes_less_than_or_equal_to`]; see their documentation for more.
87#[derive(Clone, Debug)]
88pub struct PrimesLessThanIterator<T: PrimitiveUnsigned> {
89    small: bool,
90    i: u64,
91    limit: T,
92    sieve: Vec<u64>,
93    phantom: PhantomData<*const T>,
94}
95
96impl<T: PrimitiveUnsigned> PrimesLessThanIterator<T> {
97    fn new(n: T) -> Self {
98        let limit = n;
99        let n: u64 = n.saturating_into();
100        let mut sieve;
101        // 1031 is the smallest prime greater than 2^10.
102        if n < 1031 {
103            sieve = Vec::with_capacity(0);
104        } else {
105            sieve = alloc::vec![0; limbs_prime_sieve_size::<u64>(n)];
106            limbs_prime_sieve_u64(&mut sieve, n);
107        }
108        Self {
109            small: true,
110            i: 0,
111            limit,
112            sieve,
113            phantom: PhantomData,
114        }
115    }
116
117    /// Moves the iterator to just after a given value, returning whether the iterator will return
118    /// any more values after that point. If `false` is returned, calling `next` will return `None`;
119    /// if `true` is returned, calling `next` will return smallest prime greater than $n$.
120    ///
121    /// # Worst-case complexity (amortized)
122    /// $T(n) = O(n\log \log n)$
123    ///
124    /// $M(n) = O(1)$
125    ///
126    /// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
127    ///
128    /// # Examples
129    /// ```
130    /// use malachite_base::num::factorization::traits::Primes;
131    ///
132    /// let mut primes = u32::primes_less_than(&10_000);
133    /// assert_eq!(primes.jump_after(1000), true);
134    /// assert_eq!(primes.next(), Some(1009));
135    ///
136    /// assert_eq!(primes.jump_after(10_000), false);
137    /// assert_eq!(primes.next(), None);
138    /// ```
139    pub fn jump_after(&mut self, n: T) -> bool {
140        // 1021 is the greatest prime smaller than 2^10.
141        if n < T::saturating_from(1021) {
142            self.small = true;
143            self.i = u64::wrapping_from(match SMALL_PRIMES.binary_search(&n.wrapping_into()) {
144                Ok(i) => i + 1,
145                Err(i) => i,
146            });
147            if self.i == NUM_SMALL_PRIMES_U64 {
148                if self.sieve.is_empty() {
149                    false
150                } else {
151                    self.small = false;
152                    self.i = NEXT_INDEX;
153                    let next_i =
154                        if let Some(next_i) = limbs_index_of_next_false_bit(&self.sieve, self.i) {
155                            next_i
156                        } else {
157                            return false;
158                        };
159                    let next_p = T::exact_from(id_to_n(next_i + 1));
160                    next_p <= self.limit
161                }
162            } else if let Ok(next_p) = T::try_from(SMALL_PRIMES[self.i as usize]) {
163                next_p <= self.limit
164            } else {
165                false
166            }
167        } else {
168            self.small = false;
169            self.i = if let Ok(n) = n.try_into() {
170                n_to_bit(n) + 1
171            } else {
172                return false;
173            };
174            let next_i = if let Some(next_i) = limbs_index_of_next_false_bit(&self.sieve, self.i) {
175                next_i
176            } else {
177                return false;
178            };
179            let next_p = T::exact_from(id_to_n(next_i + 1));
180            next_p <= self.limit
181        }
182    }
183}
184
185impl<T: PrimitiveUnsigned> Iterator for PrimesLessThanIterator<T> {
186    type Item = T;
187
188    fn next(&mut self) -> Option<T> {
189        if self.small {
190            let p = if let Ok(p) = T::try_from(SMALL_PRIMES[self.i as usize]) {
191                p
192            } else {
193                return None;
194            };
195            if p > self.limit {
196                return None;
197            }
198            self.i += 1;
199            if self.i == NUM_SMALL_PRIMES_U64 {
200                self.small = false;
201                self.i = NEXT_INDEX;
202            }
203            Some(p)
204        } else {
205            self.i = limbs_index_of_next_false_bit(&self.sieve, self.i)? + 1;
206            let p = T::exact_from(id_to_n(self.i));
207            if p > self.limit { None } else { Some(p) }
208        }
209    }
210}
211
212/// An iterator over that generates all primes.
213///
214/// This `struct` is created by [`Primes::primes`]; see its documentation for more.
215#[derive(Clone, Debug)]
216pub struct PrimesIterator<T: PrimitiveUnsigned> {
217    limit: T,
218    xs: PrimesLessThanIterator<T>,
219}
220
221impl<T: PrimitiveUnsigned> PrimesIterator<T> {
222    fn new() -> Self {
223        let limit = T::saturating_from(1024u16);
224        Self {
225            limit,
226            xs: PrimesLessThanIterator::new(limit),
227        }
228    }
229
230    /// Moves the iterator to just after a given value, returning whether the iterator will return
231    /// any more values after that point. If `false` is returned, calling `next` will return `None`
232    /// (which only happens if $n$ is very close to the maximum value of `T`); if `true` is
233    /// returned, calling `next` will return smallest prime greater than $n$.
234    ///
235    /// # Worst-case complexity (amortized)
236    /// $T(n) = O(n\log \log n)$
237    ///
238    /// $M(n) = O(n)$
239    ///
240    /// where $T$ is time, $M$ is additional memory, and $n$ is `n`.
241    ///
242    /// # Examples
243    /// ```
244    /// use malachite_base::num::factorization::traits::Primes;
245    ///
246    /// let mut primes = u16::primes();
247    /// assert_eq!(primes.jump_after(1000), true);
248    /// assert_eq!(primes.next(), Some(1009));
249    ///
250    /// assert_eq!(primes.jump_after(u16::MAX), false);
251    /// assert_eq!(primes.next(), None);
252    /// ```
253    pub fn jump_after(&mut self, n: T) -> bool {
254        loop {
255            if self.xs.jump_after(n) {
256                return true;
257            } else if self.limit == T::MAX {
258                return false;
259            }
260            self.limit.saturating_mul_assign(T::TWO);
261            while self.limit != T::MAX && self.limit <= n {
262                self.limit.saturating_mul_assign(T::TWO);
263            }
264            let i = self.xs.i;
265            self.xs = T::primes_less_than_or_equal_to(&self.limit);
266            self.xs.i = i;
267        }
268    }
269}
270
271impl<T: PrimitiveUnsigned> Iterator for PrimesIterator<T> {
272    type Item = T;
273
274    fn next(&mut self) -> Option<T> {
275        loop {
276            let p = self.xs.next();
277            if p.is_some() {
278                return p;
279            } else if self.limit == T::MAX {
280                return None;
281            }
282            self.limit.saturating_mul_assign(T::TWO);
283            let i = if self.xs.small {
284                n_to_bit(1031)
285            } else {
286                self.xs.i
287            };
288            self.xs = T::primes_less_than_or_equal_to(&self.limit);
289            self.xs.small = false;
290            self.xs.i = i;
291        }
292    }
293}
294
295macro_rules! impl_primes {
296    ($t:ident) => {
297        impl Primes for $t {
298            type I = PrimesIterator<$t>;
299            type LI = PrimesLessThanIterator<$t>;
300
301            /// Returns an iterator that generates all primes less than a given value.
302            ///
303            /// The iterator produced by `primes_less_than(n)` generates the same primes as the
304            /// iterator produced by `primes().take_while(|&p| p < n)`, but the latter would be
305            /// slower because it doesn't know in advance how large its prime sieve should be, and
306            /// might have to create larger and larger prime sieves.
307            ///
308            /// # Worst-case complexity (amortized)
309            /// $T(i) = O(\log \log i)$
310            ///
311            /// $M(i) = O(1)$
312            ///
313            /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
314            ///
315            /// # Examples
316            /// See [here](super::primes#primes_less_than).
317            #[inline]
318            fn primes_less_than(n: &$t) -> PrimesLessThanIterator<$t> {
319                PrimesLessThanIterator::new(n.saturating_sub(1))
320            }
321
322            /// Returns an iterator that generates all primes less than or equal to a given value.
323            ///
324            /// The iterator produced by `primes_less_than_or_equal_to(n)` generates the same primes
325            /// as the iterator produced by `primes().take_while(|&p| p <= n)`, but the latter would
326            /// be slower because it doesn't know in advance how large its prime sieve should be,
327            /// and might have to create larger and larger prime sieves.
328            ///
329            /// # Worst-case complexity (amortized)
330            /// $T(i) = O(\log \log i)$
331            ///
332            /// $M(i) = O(1)$
333            ///
334            /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
335            ///
336            /// # Examples
337            /// See [here](super::primes#primes_less_than_or_equal_to).
338            #[inline]
339            fn primes_less_than_or_equal_to(&n: &$t) -> PrimesLessThanIterator<$t> {
340                PrimesLessThanIterator::new(n)
341            }
342
343            /// Returns all primes that fit into the specified type.
344            ///
345            /// The iterator produced by `primes(n)` generates the same primes as the iterator
346            /// produced by `primes_less_than_or_equal_to(T::MAX)`. If you really need to generate
347            /// _every_ prime, and `T` is `u32` or smaller, then you should use the latter, as it
348            /// will allocate all the needed memory at once. If `T` is `u64` or larger, or if you
349            /// probably don't need every prime, then `primes()` will be faster as it won't allocate
350            /// too much memory right away.
351            ///
352            /// # Worst-case complexity (amortized)
353            /// $T(i) = O(\log \log i)$
354            ///
355            /// $M(i) = O(1)$
356            ///
357            /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
358            ///
359            /// # Examples
360            /// See [here](super::primes#primes).
361            #[inline]
362            fn primes() -> PrimesIterator<$t> {
363                PrimesIterator::new()
364            }
365        }
366    };
367}
368apply_to_unsigneds!(impl_primes);
369
370/// An iterator that generates `bool`s up to a certain limit, where the $n$th `bool` is `true` if
371/// and only if $n$ is prime. See [`prime_indicator_sequence_less_than`] for more information.
372#[derive(Clone, Debug)]
373pub struct PrimeIndicatorSequenceLessThan {
374    primes: PrimesLessThanIterator<u64>,
375    limit: u64,
376    i: u64,
377    next_prime: u64,
378}
379
380impl Iterator for PrimeIndicatorSequenceLessThan {
381    type Item = bool;
382
383    fn next(&mut self) -> Option<bool> {
384        if self.i >= self.limit {
385            None
386        } else if self.i == self.next_prime {
387            self.i += 1;
388            self.next_prime = self.primes.next().unwrap_or(0);
389            Some(true)
390        } else {
391            self.i += 1;
392            Some(false)
393        }
394    }
395}
396
397/// Returns an iterator that generates an sequence of `bool`s, where the $n$th `bool` is `true` if
398/// and only if $n$ is prime. The first `bool` generated has index 1, and the last one has index
399/// $\max(0,\ell-1)$, where $\ell$ is `limit`.
400///
401/// The output length is $max(0,\ell-1)$, where $\ell$ is `limit`.
402///
403/// # Worst-case complexity (amortized)
404/// $T(i) = O(\log \log \log i)$
405///
406/// $M(i) = O(1)$
407///
408/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
409///
410/// # Examples
411/// ```
412/// use malachite_base::num::factorization::primes::prime_indicator_sequence_less_than;
413///
414/// let s: String = prime_indicator_sequence_less_than(101)
415///     .map(|b| if b { '1' } else { '0' })
416///     .collect();
417/// assert_eq!(
418///     s,
419///     "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\
420///     00000001000"
421/// )
422/// ```
423pub fn prime_indicator_sequence_less_than(limit: u64) -> PrimeIndicatorSequenceLessThan {
424    let mut primes = u64::primes_less_than(&limit);
425    primes.next(); // skip 2
426    PrimeIndicatorSequenceLessThan {
427        primes,
428        limit,
429        i: 1,
430        next_prime: 2,
431    }
432}
433
434/// Returns an iterator that generates an sequence of `bool`s, where the $n$th `bool` is `true` if
435/// and only if $n$ is prime. The first `bool` generated has index 1, and the last one has index
436/// `limit`.
437///
438/// The output length is `limit`.
439///
440/// # Worst-case complexity (amortized)
441/// $T(i) = O(\log \log \log i)$
442///
443/// $M(i) = O(1)$
444///
445/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
446///
447/// # Examples
448/// ```
449/// use malachite_base::num::factorization::primes::prime_indicator_sequence_less_than_or_equal_to;
450///
451/// let s: String = prime_indicator_sequence_less_than_or_equal_to(100)
452///     .map(|b| if b { '1' } else { '0' })
453///     .collect();
454/// assert_eq!(
455///     s,
456///     "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\
457///     00000001000"
458/// )
459/// ```
460#[inline]
461pub fn prime_indicator_sequence_less_than_or_equal_to(
462    limit: u64,
463) -> PrimeIndicatorSequenceLessThan {
464    prime_indicator_sequence_less_than(limit.checked_add(1).unwrap())
465}
466
467/// An iterator that generates `bool`s, where the $n$th `bool` is `true` if and only if $n$ is
468/// prime. See [`prime_indicator_sequence`] for more information.
469#[derive(Clone, Debug)]
470pub struct PrimeIndicatorSequence {
471    primes: PrimesIterator<u64>,
472    i: u64,
473    next_prime: u64,
474}
475
476impl Iterator for PrimeIndicatorSequence {
477    type Item = bool;
478
479    fn next(&mut self) -> Option<bool> {
480        Some(if self.i == self.next_prime {
481            self.i += 1;
482            self.next_prime = self.primes.next().unwrap();
483            true
484        } else {
485            self.i += 1;
486            false
487        })
488    }
489}
490
491/// Returns an iterator that generates an infinite sequence of `bool`s, where the $n$th `bool` is
492/// `true` if and only if $n$ is prime. The first `bool` generated has index 1.
493///
494/// The output length is infinite.
495///
496/// # Worst-case complexity (amortized)
497/// $T(i) = O(\log \log \log i)$
498///
499/// $M(i) = O(1)$
500///
501/// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
502///
503/// # Examples
504/// ```
505/// use malachite_base::num::factorization::primes::prime_indicator_sequence;
506///
507/// let s: String = prime_indicator_sequence()
508///     .take(100)
509///     .map(|b| if b { '1' } else { '0' })
510///     .collect();
511/// assert_eq!(
512///     s,
513///     "01101010001010001010001000001010000010001010001000001000001010000010001010000010001000001\
514///     00000001000"
515/// )
516/// ```
517pub fn prime_indicator_sequence() -> PrimeIndicatorSequence {
518    let mut primes = u64::primes();
519    primes.next(); // skip 2
520    PrimeIndicatorSequence {
521        primes,
522        i: 1,
523        next_prime: 2,
524    }
525}