This module provides utilities related to prime numbers.
all-primes
[Variable]An infinite lazy sequence of primes.
;; show 10 prime numbers from 100-th one. (lseq-take (lseq-drop all-primes 100) 10) ⇒ (547 557 563 569 571 577 587 593 599 601) |
reset-primes
Once you take a prime out of all-primes
, all smaller primes
have been calculated and remain in memory, since the
head of the sequence is held in all-primes
. Sometimes you know
you need no more prime numbers and you wish the ones that have already been computed
to be garbage-collected. Calling reset-primes
rebinds
primes
to an unrealized lazy sequence, allowing the previously
realized primes to be garbage collected.
primes
Returns a fresh lazy sequence of primes. It is useful when you need certain for a short period of time — if you don’t keep a reference to the head of the returned sequence, it will be garbage collected after you’re done with the primes. (Note that the calculation of a prime number needs the sequence of primes from the beginning, so even if your code only keeps a reference into the middle of the sequence, the entire sequence will be stored — you have to release all references in order to allow the sequence to be garbage collected.)
On the other hand,
each sequence returned by primes
is computed individually,
duplicating computation.
The rule of thumb is: if you use primes repeatedly throughout
the program, just use all-primes
and you’ll save computation.
If you need primes just once, call primes
and abandon the result
and you’ll save space.
small-prime?
nFor positive integers
less than small-prime-bound
, this procedure
determines if n is prime or not, quickly and deterministically.
If n is greater than or equal to this bound, this procedure returns #f
.
This can be used to quickly filter out known primes; it never returns
#t
on composite numbers, but it may return #f
on
sufficiently large prime numbers).
The Miller-Rabin test below can tell if the input is definitely composite,
but it may return #t
on some composite numbers.
small-prime-bound
[Variable]For all positive integers below this value
small-prime?
can determine whether it is a prime or not.
miller-rabin-prime?
n [ num-tests ]Check if an exact integer n is a prime number, using
probabilistic Miller-Rabin algorithm (n must be greater than 1).
If this procedure returns #f
,
n is a composite number. If this procedure returns #t
,
n is likely a prime, but there’s a small probability
that it is a false positive.
Note that if n is smaller than small-prime-bound
, the algorithm is
deterministic; if it returns #t
, n is certainly a prime.
If n is greater than or equal to
small-prime-bound
, we use a probabilistic test.
We choose a random base integer
to perform the Miller-Rabin test up to num-tests (7 times by default).
The probability
of returning #t
for a composite number
is at most (expt 4 (- num-tests))
.
bpsw-prime?
nCheck if an exact integer n is a prime number, using
the Baillie-PSW primality test
(http://www.trnicely.net/misc/bpsw.html). It is deterministic,
and is known to return a definitive answer for all numbers less than 2#t
on a composite number,
although nosuch number has been found yet. This procedure never returns #f
on a prime number.
This test is slower than Miller-Rabin but fast enough for casual use, so it is handy when you want a definitive answer below the above range.
naive-factorize
n [ divisor-limit ]Factorize a positive integer n by trying to divide it into
all primes up to (sqrt n)
. Returns a list of prime factors,
smallest first.
(naive-factorize 142857) ⇒ (3 3 3 11 13 37) |
Although this is a pretty naive method, this works well as far as any of n’s factors are not larger than about ten million.
(naive-factorize 3644357367494986671013)) ⇒ (10670053 10670053 32010157) |
If n includes any larger prime factors, the performance becomes abysmal.
Alternatively, providing the divisor-limit argument specifies
the upper bound of the prime number to be tried. If it is given,
naive-factorize
returns a factor f unchanged if it can’t be
divided by any primes less than or equal to divisor-limit.
So, the last element of the returned list may be a composite number.
This is useful for excluding trivial factors before applying more sophisticated
factorizing algorithms.
(naive-factorize 825877877739 1000) ⇒ (3 43 6402154091) ;; whereas (naive-factorize 825877877739) ⇒ (3 43 4591 1394501) |
The procedure also memoizes the results on smaller values of n to make things faster.
mc-factorize
nFactorize a positive integer n using the algorithm described in R. P. Brent, An improved Monte Carlo factorization algorithm, BIT 20 (1980), 176-184. http://maths-people.anu.edu.au/~brent/pub/pub051.html.
This one is capable of handling much larger factors than
naive-factorize
, somewhere around 10
Since this method is probabilistic, the execution time may vary on the same n. But it will always return the definitive results as long as every prime factor of n is smaller than an implementation-specified limit. If n contains a prime factor greater than the limit, the procedure may loop forever.
jacobi
a nCalculates the Jacobi symbol (a/n)
(http://en.wikipedia.org/wiki/Jacobi_symbol).