Struct primal_sieve::Sieve

source ·
pub struct Sieve { /* private fields */ }
Expand description

A heavily optimised prime sieve.

This stores information about primes up to some specified limit, allowing efficient queries of information about them. This caches the successive outputs of StreamingSieve and has very similar performance, modulo the differences in memory use: to cache the information Sieve uses approximately limit / 30 + O(sqrt(limit)) bytes of memory. Consider directly using StreamingSieve if repeated queries are unnecessary, since that uses only O(sqrt(limit)) bytes.

§Examples

let sieve = primal::Sieve::new(10_000_000);
assert_eq!(sieve.prime_pi(123456), 11601);

assert!(sieve.is_prime(6395047));
assert!(!sieve.is_prime(6395048));

Implementations§

source§

impl Sieve

source

pub fn new(limit: usize) -> Sieve

Create a new instance, sieving out all the primes up to limit.

source

pub fn upper_bound(&self) -> usize

Return the largest number that this sieve knows about.

It will be at least as large as the number passed to new, but may be slightly larger.

§Examples
let sieve = primal::Sieve::new(1000);

assert!(sieve.upper_bound() >= 1000);
source

pub fn is_prime(&self, n: usize) -> bool

Determine if n is a prime number.

§Panics

If n is out of range (greater than self.upper_bound()), is_prime will panic.

§Examples
let sieve = primal::Sieve::new(1000);

assert_eq!(sieve.is_prime(0), false);
assert_eq!(sieve.is_prime(1), false);
assert_eq!(sieve.is_prime(2), true);
assert_eq!(sieve.is_prime(3), true);
assert_eq!(sieve.is_prime(4), false);
assert_eq!(sieve.is_prime(5), true);

assert_eq!(sieve.is_prime(991), true);
assert_eq!(sieve.is_prime(993), false);
assert_eq!(sieve.is_prime(995), false);
assert_eq!(sieve.is_prime(997), true);
assert_eq!(sieve.is_prime(999), false);
source

pub fn prime_pi(&self, n: usize) -> usize

Count the number of primes upto and including n.

§Panics

If n is out of range (greater than self.upper_bound()), prime_pi will panic.

§Examples
let sieve = primal::Sieve::new(1000);

assert_eq!(sieve.prime_pi(10), 4);
// the endpoint is included
assert_eq!(sieve.prime_pi(11), 5);

assert_eq!(sieve.prime_pi(100), 25);
assert_eq!(sieve.prime_pi(1000), 168);
source

pub fn factor( &self, n: usize, ) -> Result<Vec<(usize, usize)>, (usize, Vec<(usize, usize)>)>

Factorise n into (prime, exponent) pairs.

Returns Err((leftover, partial factorisation)) if n cannot be fully factored, or if n is zero (leftover == 0). A number can not be completely factored if and only if the prime factors of n are too large for this sieve, that is, if there is

  • a prime factor larger than U^2, or
  • more than one prime factor between U and U^2

where U is the upper bound of the primes stored in this sieve.

Notably, any number between U and U^2 can always be fully factored, since these numbers are guaranteed to only have zero or one prime factors larger than U.

§Examples
let sieve = primal::Sieve::new(100);

assert_eq!(sieve.factor(2), Ok(vec![(2, 1)]));
assert_eq!(sieve.factor(4), Ok(vec![(2, 2)]));
assert_eq!(sieve.factor(1 << 31), Ok(vec![(2, 31)]));

assert_eq!(sieve.factor(18), Ok(vec![(2, 1), (3, 2)]));

assert_eq!(sieve.factor(25 * 81), Ok(vec![(3, 4), (5, 2)]));

// "large" prime factors are OK, as long as there's only one
assert_eq!(sieve.factor(2 * 3 * 97 * 97 * 991),
           Ok(vec![(2, 1), (3, 1), (97, 2), (991, 1)]));

// too many large factors is problematic
assert_eq!(sieve.factor(991 * 991),
           Err((991 * 991, vec![])));
assert_eq!(sieve.factor(2 * 3 * 17 * 17 * 991 * 991),
           Err((991 * 991, vec![(2, 1), (3, 1), (17, 2)])));
source

pub fn nth_prime(&self, n: usize) -> usize

Compute pn, the n prime number, 1-indexed (i.e. p1 = 2, p2 = 3).

§Panics

n must be larger than 0 and less than the total number of primes in this sieve (that is, self.prime_pi(self.upper_bound())).

§Example
let (_, hi) = primal::estimate_nth_prime(1_000);

let sieve = primal::Sieve::new(hi as usize);

assert_eq!(sieve.nth_prime(10), 29);
assert_eq!(sieve.nth_prime(100), 541);
assert_eq!(sieve.nth_prime(1_000), 7919);
source

pub fn primes_from(&self, n: usize) -> SievePrimes<'_>

Return an iterator over the primes from n (inclusive) to the end of this sieve.

NB. it is not guaranteed that the end is the same as the limit passed to new: it may be larger. Consider using take_while if the limit must be exact.

§Panics

If n is out of range (greater than self.upper_bound()), primes_from will panic.

§Examples
let sieve = primal::Sieve::new(1_000);

// print the three digit primes
for p in sieve.primes_from(100).take_while(|x| *x < 1000) {
    println!("{}", p);
}

Trait Implementations§

source§

impl Debug for Sieve

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Sieve

§

impl RefUnwindSafe for Sieve

§

impl Send for Sieve

§

impl Sync for Sieve

§

impl Unpin for Sieve

§

impl UnwindSafe for Sieve

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.