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