1use primal_bit::BitVec;
2use crate::wheel;
3use crate::streaming::StreamingSieve;
4
5use std::cmp;
6use std::slice;
7
8type SmallVec1<T> = ::smallvec::SmallVec<[T; 1]>;
9
10#[derive(Debug)]
31pub struct Sieve {
32 seg_bits: usize,
33 nbits: usize,
34 seen: SmallVec1<Item>,
35}
36
37#[derive(Debug)]
38struct Item {
39 count: usize,
40 bits: BitVec,
41}
42impl Item {
43 fn new(x: BitVec, so_far: &mut usize) -> Item {
44 *so_far += x.count_ones();
45 Item {
46 count: *so_far,
47 bits: x,
48 }
49 }
50}
51
52impl Sieve {
53 pub fn new(limit: usize) -> Sieve {
56 let mut seen = SmallVec1::new();
57 let mut nbits = 0;
58 let mut so_far = 0;
59 let mut seg_bits = None;
60 match wheel::small_for(limit) {
61 Some(bits) => {
62 nbits = bits.len();
63 seen.push(Item::new(bits, &mut 0));
64 seg_bits = Some(nbits)
65 }
66 None => {
67 let mut stream = StreamingSieve::new(limit);
68
69 while let Some((n, bits)) = stream.next() {
70 let bits_limit = wheel::bit_index((limit - n).saturating_add(1)).1;
71 seen.push(Item::new(bits.clone(), &mut so_far));
72 nbits += cmp::min(bits.len(), bits_limit);
73 match seg_bits {
74 None => seg_bits = Some(bits.len()),
75 Some(old) => assert_eq!(old, bits.len()),
76 }
77 }
78 }
79 }
80 let seg_bits_adjust = if seen.len() == 1 { 1 } else { 0 };
89
90 Sieve {
91 seg_bits: seg_bits.unwrap() + seg_bits_adjust,
92 nbits,
93 seen,
94 }
95 }
96 fn split_index(&self, idx: usize) -> (usize, usize) {
97 (idx / self.seg_bits, idx % self.seg_bits)
98 }
99 fn index_for(&self, n: usize) -> (bool, usize, usize) {
100 let (b, idx) = wheel::bit_index(n);
101 let (base, tweak) = self.split_index(idx);
102 (b, base, tweak)
103 }
104
105 fn prime_pi_chunk(&self, n: usize) -> usize {
106 if n == 0 {
107 0
108 } else {
109 self.seen[n - 1].count
110 }
111 }
112 pub fn upper_bound(&self) -> usize {
125 wheel::upper_bound(self.nbits)
126 }
127
128 pub fn is_prime(&self, n: usize) -> bool {
154 match self.index_for(n) {
155 (false, _, _) => n == 2 || n == 3 || n == 5 || n == 7,
156 (true, base, tweak) => self.seen[base].bits[tweak],
157 }
158 }
159
160 pub fn prime_pi(&self, n: usize) -> usize {
180 assert!(n <= self.upper_bound());
181 match n {
182 0..=1 => 0,
183 2 => 1,
184 3..=4 => 2,
185 5..=6 => 3,
186 7..=10 => 4,
187 _ => {
188 let (includes, base, tweak) = self.index_for(n);
189 let mut count = match wheel::BYTE_MODULO {
190 30 => 3,
191 _ => unimplemented!()
192 };
193
194 count += self.prime_pi_chunk(base);
195 count += self.seen[base].bits.count_ones_before(tweak + includes as usize);
196
197 count
198 }
199 }
200 }
201
202 pub fn factor(&self, mut n: usize) -> Result<Vec<(usize,usize)>,
244 (usize, Vec<(usize, usize)>)>
245 {
246 if n == 0 { return Err((0, vec![])) }
247 if n == 1 { return Ok(vec![]) }
248
249 let mut ret = Vec::new();
250
251 self.primes_from(0).for_each_while(|p| {
253 if n % p == 0 {
254 n /= p;
255 let mut count = 1;
256 while n % p == 0 {
257 n /= p;
258 count += 1;
259 }
260 ret.push((p,count));
261 }
262
263 p.saturating_mul(p) < n
264 });
265
266 if n != 1 {
267 let b = self.upper_bound();
268 if let Some(bb) = b.checked_mul(b) {
269 if bb < n {
270 return Err((n, ret))
272 }
273 }
274
275 ret.push((n, 1));
280 }
281 Ok(ret)
282 }
283
284 pub fn nth_prime(&self, n: usize) -> usize {
305 match n {
306 1 => 2,
307 2 => 3,
308 3 => 5,
309 _ => {
310 assert!(0 < n && n <= 3 + self.prime_pi_chunk(self.seen.len()));
311 let bit_n = n - 3;
314
315 let chunk_idx = self.seen.binary_search_by(|x| x.count.cmp(&bit_n))
316 .unwrap_or_else(|x| x);
317 let chunk_bits = self.prime_pi_chunk(chunk_idx);
318 let bit_idx = self.seen[chunk_idx].bits.find_nth_bit(bit_n - chunk_bits - 1);
319 wheel::from_bit_index(chunk_idx * self.seg_bits + bit_idx.unwrap())
320 }
321 }
322 }
323
324 pub fn primes_from(&self, n: usize) -> SievePrimes<'_> {
347 assert!(n <= self.upper_bound());
348 let early = match n {
349 0..=2 => Early::Two,
350 3 => Early::Three,
351 4..=5 => Early::Five,
352 _ => Early::Done
353 };
354 let (_, base, tweak) = self.index_for(n);
355 assert!(self.seen.len() == 1 || self.seg_bits % 8 == 0);
356 let base_byte_count = base * self.seg_bits / 8;
357
358 let bits = &self.seen[base].bits;
359
360 let current_base = base_byte_count * wheel::BYTE_MODULO;
361 let next_base = current_base.saturating_add(bits.len() * wheel::BYTE_MODULO / 8);
362
363 SievePrimes {
364 early,
365 base: current_base,
366 next_base,
367 ones: bits.ones_from(tweak),
368 limit: self.upper_bound(),
369 bits: self.seen[base + 1..].iter(),
370 }
371 }
372}
373
374#[derive(Clone)]
375enum Early {
376 Two,
377 Three,
378 Five,
379 Done,
380}
381
382#[derive(Clone)]
384pub struct SievePrimes<'a> {
385 early: Early,
386 base: usize,
387 next_base: usize,
388 limit: usize,
389 ones: primal_bit::Ones<'a>,
390 bits: slice::Iter<'a, Item>,
391}
392
393impl<'a> SievePrimes<'a> {
394 #[inline]
395 fn from_bit_index(&self, i: usize) -> Option<usize> {
396 let w = wheel::from_bit_index(i);
397 match self.base.checked_add(w) {
398 Some(p) if p <= self.limit => Some(p),
399 _ => None,
400 }
401 }
402
403 fn advance_ones(&mut self) -> bool {
404 match self.bits.next() {
405 Some(Item { bits, .. }) => {
406 self.base = self.next_base;
407 self.next_base = self
408 .next_base
409 .saturating_add(bits.len() * wheel::BYTE_MODULO / 8);
410 self.ones = bits.ones_from(0);
411 true
412 },
413 None => false,
414 }
415 }
416
417 fn for_each_while<F>(mut self, mut f: F)
421 where
422 F: FnMut(usize) -> bool,
423 {
424 if !match self.early {
425 Early::Done => true,
426 Early::Two => f(2) && f(3) && f(5),
427 Early::Three => f(3) && f(5),
428 Early::Five => f(5),
429 } {
430 return;
431 }
432 loop {
433 while let Some(i) = self.ones.next() {
434 match self.from_bit_index(i) {
435 Some(p) => if !f(p) { return },
436 None => return,
437 }
438 }
439 if !self.advance_ones() {
440 return;
441 }
442 }
443 }
444}
445
446impl<'a> Iterator for SievePrimes<'a> {
448 type Item = usize;
449
450 #[inline]
451 fn next(&mut self) -> Option<usize> {
452 match self.early {
453 Early::Done => {}
454 Early::Two => {
455 self.early = Early::Three;
456 return Some(2)
457 }
458 Early::Three => {
459 self.early = Early::Five;
460 return Some(3)
461 }
462 Early::Five => {
463 self.early = Early::Done;
464 return Some(5)
465 }
466 }
467 loop {
468 if let Some(i) = self.ones.next() {
469 return self.from_bit_index(i);
470 }
471 if !self.advance_ones() {
472 return None;
473 }
474 }
475 }
476
477 fn fold<Acc, F>(mut self, mut acc: Acc, mut f: F) -> Acc
478 where
479 F: FnMut(Acc, Self::Item) -> Acc
480 {
481 match self.early {
482 Early::Done => {}
483 Early::Two => {
484 acc = f(acc, 2);
485 acc = f(acc, 3);
486 acc = f(acc, 5);
487 }
488 Early::Three => {
489 acc = f(acc, 3);
490 acc = f(acc, 5);
491 }
492 Early::Five => {
493 acc = f(acc, 5);
494 }
495 }
496 loop {
497 while let Some(i) = self.ones.next() {
498 match self.from_bit_index(i) {
499 Some(p) => acc = f(acc, p),
500 None => return acc,
501 }
502 }
503 if !self.advance_ones() {
504 return acc;
505 }
506 }
507 }
508}
509
510#[cfg(test)]
511mod tests {
512 use primal_slowsieve::Primes;
513 use super::Sieve;
514
515 #[test]
516 fn small() {
517 let larger = Sieve::new(100_000);
518 for limit in 2..1_000 {
519 let sieve = Sieve::new(limit);
520 assert!(sieve.upper_bound() >= limit);
521 let primes = sieve.prime_pi(limit);
522 assert_eq!(primes, larger.prime_pi(limit));
523 let nth = sieve.nth_prime(primes);
524 assert!(nth <= limit);
525 assert_eq!(nth, larger.nth_prime(primes));
526 }
527 }
528
529 #[test]
530 fn is_prime() {
531 let limit = 2_000_000;
532 let real = Primes::sieve(limit);
533 let primes = Sieve::new(limit);
534
535 for i in 0..limit {
536 assert!(primes.is_prime(i) == real.is_prime(i),
537 "failed for {} (real = {})", i, real.is_prime(i));
538 }
539 }
540
541 #[test]
542 fn primes_from_smoke() {
543 let limit = 100;
544 let primes = Sieve::new(limit);
545 let real = &[2, 3, 5, 7, 11,
546 13, 17, 19, 23, 29,
547 31, 37, 41, 43, 47,
548 53, 59, 61, 67, 71,
549 73, 79, 83, 89, 97];
550 for i in 0..limit {
551 let idx = real.iter().position(|x| *x >= i).unwrap_or(real.len());
552 assert_eq!(primes.primes_from(i).take_while(|x| *x <= limit).collect::<Vec<_>>(),
553 &real[idx..]);
554 }
555 }
556 #[test]
557 fn primes_from_count() {
558 let limit = 2_100_000;
559 let primes = Sieve::new(limit);
560
561 let upto = 2_000_000;
562 assert_eq!(primes.primes_from(0).take_while(|x| *x <= upto).count(),
563 primes.prime_pi(upto));
564 }
565 #[test]
566 fn primes_from_equality() {
567 let limit = 2_000_000;
568 let primes = Sieve::new(limit);
569 let real = Primes::sieve(limit);
570
571 let real = real.primes().take_while(|x| *x <= limit);
572 let computed = primes.primes_from(0).take_while(|x| *x <= limit);
573 let mut i = 0;
574 for (r, p) in real.zip(computed) {
575 assert_eq!(r, p);
576 i += 1;
577 }
578 assert_eq!(i, primes.prime_pi(limit));
579 }
580 #[test]
581 fn primes_from_no_overrun() {
582 let real = Sieve::new(1000);
583
584 for i in 0..100 {
585 let i = i * 38 / 39 + 1;
586 let sieve = Sieve::new(i);
587
588 for p in sieve.primes_from(0) {
589 assert!(real.is_prime(p));
590 }
591 }
592 }
593 #[test]
594 fn upper_bound() {
595 for i in 1..1000 {
596 let primes = Sieve::new(i);
597 assert!(primes.upper_bound() >= i);
598 }
599
600 let range = if cfg!(feature = "slow_tests") {
601 1..200
602 } else {
603 100..120
604 };
605 for i in range {
606 let i = i * 10_000;
607 let primes = Sieve::new(i);
608 assert!(primes.upper_bound() >= i);
609 }
610 }
611
612 #[test]
613 fn prime_pi() {
614 let (limit, mult) = if cfg!(feature = "slow_tests") {
615 (2_000_000, 19_998)
616 } else {
617 (200_000, 1_998)
618 };
619 let primes = Sieve::new(limit);
620 let real = Primes::sieve(limit);
621
622 for i in (0..20).chain((0..100).map(|n| n * mult + 1)) {
623 let val = primes.prime_pi(i);
624 let true_ = real.primes().take_while(|p| *p <= i).count();
625 assert!(val == true_, "failed for {}, true {}, computed {}",
626 i, true_, val)
627 }
628 }
629
630 #[test]
631 fn factor() {
632 let primes = Sieve::new(1000);
633
634 let tests: &[(usize, &[(usize, usize)])] = &[
635 (1, &[]),
636 (2, &[(2_usize, 1)]),
637 (3, &[(3, 1)]),
638 (4, &[(2, 2)]),
639 (5, &[(5, 1)]),
640 (6, &[(2, 1), (3, 1)]),
641 (7, &[(7, 1)]),
642 (8, &[(2, 3)]),
643 (9, &[(3, 2)]),
644 (10, &[(2, 1), (5, 1)]),
645
646 (2*2*2*2*2 * 3*3*3*3*3, &[(2, 5), (3,5)]),
647 (2*3*5*7*11*13*17*19, &[(2,1), (3,1), (5,1), (7,1), (11,1), (13,1), (17,1), (19,1)]),
648 (7561, &[(7561, 1)]),
650 (2*7561, &[(2, 1), (7561, 1)]),
651 (4*5*7561, &[(2, 2), (5,1), (7561, 1)]),
652 ];
653 for &(n, expected) in tests.iter() {
654 assert_eq!(primes.factor(n), Ok(expected.to_vec()));
655 }
656 }
657
658 #[test]
659 fn factor_compare() {
660 let short = Sieve::new(30);
661 let long = Sieve::new(10000);
662
663 let short_lim = short.upper_bound() * short.upper_bound() + 1;
664
665 for n in 0..short_lim {
668 assert_eq!(short.factor(n), long.factor(n))
669 }
670 'next_n: for n in short_lim..10000 {
672 let possible = short.factor(n);
673 let real = long.factor(n).ok().unwrap();
674
675 let mut seen_small = None;
676 for (this_idx, &(p,i)) in real.iter().enumerate() {
677 let last_short_prime = if p >= short_lim {
678 this_idx
679 } else if p > short.upper_bound() {
680 match seen_small {
681 Some(idx) => idx,
682 None if i > 1 => this_idx,
683 None => {
684 seen_small = Some(this_idx);
686 continue
687 }
688 }
689 } else {
690 continue
692 };
693
694 let (low, hi) = real.split_at(last_short_prime);
696 let leftover = hi.iter().fold(1, |x, &(p, i)| x * p.pow(i as u32));
697
698 assert_eq!(possible, Err((leftover, low.to_vec())));
699 continue 'next_n;
700 }
701
702 assert_eq!(possible, Ok(real))
704 }
705 }
706
707 #[test]
708 #[cfg_attr(not(feature = "slow_tests"), ignore)]
709 fn factor_overflow() {
710 #[cfg(target_pointer_width = "32")]
716 const LIMIT_PRIME: (usize, usize) = (0x10000, 0x2001d);
717 #[cfg(target_pointer_width = "64")]
718 const LIMIT_PRIME: (usize, usize) = (0x100000000, 0x200000011);
719
720 let (limit, prime) = LIMIT_PRIME;
721 let primes = Sieve::new(limit);
722 assert!(prime > primes.upper_bound());
723 assert_eq!(primes.factor(prime), Ok(vec![(prime, 1)]));
724 }
725
726 #[test]
727 fn factor_failures() {
728 let primes = Sieve::new(30);
729
730 assert_eq!(primes.factor(0),
731 Err((0, vec![])));
732 assert_eq!(primes.factor(31 * 31),
734 Err((31 * 31, vec![])));
735 assert_eq!(primes.factor(2 * 3 * 31 * 31),
736 Err((31 * 31, vec![(2, 1), (3, 1)])));
737
738 assert_eq!(primes.factor(7561),
740 Err((7561, vec![])));
741 assert_eq!(primes.factor(2 * 3 * 7561),
742 Err((7561, vec![(2, 1), (3, 1)])));
743 }
744
745 #[test]
746 fn nth_prime() {
747 let primes = Sieve::new(2_000_000);
748
749 for (i, p) in primes.primes_from(0).enumerate() {
750 let n = i + 1;
751 if n < 2000 || n % 1000 == 0 {
752 assert_eq!(primes.nth_prime(n), p);
753 }
754 }
755 let total = primes.prime_pi(primes.upper_bound());
756 assert!(primes.nth_prime(total) <= primes.upper_bound());
757 }
758
759 #[test]
760 fn sum_primes() {
761 let primes = Sieve::new(2_000_000);
762
763 let mut manual_sum = 0u64;
764 for p in primes.primes_from(0) {
765 manual_sum += p as u64;
766 }
767 dbg!(manual_sum);
768
769 let folded_sum = primes.primes_from(0).fold(0u64, |acc, p| acc + p as u64);
770 let trait_sum = primes.primes_from(0).map(|p| p as u64).sum::<u64>();
771 assert_eq!(manual_sum, folded_sum);
772 assert_eq!(manual_sum, trait_sum);
773 }
774
775 #[test]
776 #[cfg_attr(not(feature = "slow_tests"), ignore)]
777 fn u32_primes() {
778 const COUNT: usize = 203_280_221; const LAST: usize = 4_294_967_291; const SUM: u64 = 425_649_736_193_687_430; let sieve = Sieve::new(::std::u32::MAX as usize);
783 assert!(sieve.upper_bound() >= LAST);
784 assert_eq!(sieve.primes_from(LAST - 100).last(), Some(LAST));
785
786 let mut count = 0;
787 let mut sum = 0;
788 for p in sieve.primes_from(0) {
789 count += 1;
790 sum += p as u64;
791 }
792 assert_eq!(count, COUNT);
793 assert_eq!(sum, SUM);
794 }
795
796 #[test]
797 fn prime_pi_sieve_limit() {
798 for limit in 19998..20004 {
802 let sieve = Sieve::new(limit);
803 sieve.prime_pi(limit);
804 }
805 }
806}