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