racket/collects/math/scribblings/math-number-theory.scrbl
Neil Toronto f2dc2027f6 Initial math library commit. The history for these changes is preserved
in the original GitHub fork:

  https://github.com/ntoronto/racket

Some things about this are known to be broken (most egregious is that the
array tests DO NOT RUN because of a problem in typed/rackunit), about half
has no coverage in the tests, and half has no documentation. Fixes and
docs are coming. This is committed now to allow others to find errors and
inconsistency in the things that appear to be working, and to give the
author a (rather incomplete) sense of closure.
2012-11-16 11:39:51 -07:00

432 lines
14 KiB
Racket

#lang scribble/doc
@(require (for-label racket/flonum
racket/fixnum
racket/unsafe/ops
racket/require
math)
scribble/extract
scribble/eval
scribble/base
scribble/manual
racket/sandbox
racket/math
"utils.rkt")
@(define untyped-eval (make-untyped-math-eval))
@title[#:tag "number-theory" #:style '(toc)]{Number Theory}
@(author-jens-axel)
@local-table-of-contents[]
@; ----------------------------------------
@section[#:tag "congruences"]{Congruences and Modular Arithmetic}
@defproc[(divides? [m Integer] [n Integer]) boolean?]{
Returns @racket[#t] if @racket[m] divides @racket[n],
@racket[#f] otherwise.
Note: That a non-zero integer @racket[m] divides an integer @racket[n]
means there exists an integer @racket[k] such that m*k=n.
Test whether 2 divides 9:
@interaction[#:eval untyped-eval
(require math)
(divides? 2 9)]
@; http://en.wikipedia.org/wiki/Divisor
}
@defproc[(bezout [a Integer] [b Integer] [c Integer] ...) (Listof Integer)]{
Given integers @racket[a], @racket[b], @racket[c] ...
returns a list of integers @racket[u], @racket[v], @racket[q] ...
such that @racket[gcd](@racket[a],@racket[b],@racket[c],...)
= @racket[au + bv + cw + ...]
The greatest common divisor of 6 and 15 is 3.
@interaction[#:eval untyped-eval
(bezout 6 15)
(+ (* -2 6) (* 1 15))]
@; http://en.wikipedia.org/wiki/B%C3%A9zout's_identity
}
@defproc[(bezout-binary [a Integer] [b Integer]) (Listof Integer)]{
Same as @racket[bezout] but restricted to two arguments.
}
@defproc[(coprime? [a Integer] [b Integer] ...) boolean?]{
Returns @racket[#t] if the integers @racket[a],@racket[b],... are coprime.
Note: A set of integers are considered coprime (also called relatively prime)
if their greatest common divisor is 1.
The numbers 2, 6, and, 15 are coprime.
@interaction[#:eval untyped-eval
(coprime? 2 6 15)]
@; http://en.wikipedia.org/wiki/Coprime
}
@defproc[(pairwise-coprime? [a Integer] [b Integer] ...) boolean?]{
Returns @racket[#t] if the integers @racket[a],@racket[b],... are pairwise coprime.
The numbers 2, 6, and, 15 are not pairwise coprime, since 2 and 6 share the factor 3.
@interaction[#:eval untyped-eval
(pairwise-coprime? 2 6 15)]
@; http://en.wikipedia.org/wiki/Pairwise_coprime
}
@defproc[(inverse [a Integer] [n Integer]) natural?]{
Returns the inverse of @racket[a] module @racket[n],
if @racket[a] and @racket[n] are coprime,
otherwise @racket[#f] is returned.
Note: If @racket[a] and @racket[n] are coprime, then
the inverse, @racket[b], is a number in the set @racket[{0,...,n-1}]
such that @racket[ab=1 mod n].
The number 3 is an inverse to 2 modulo 5.
@interaction[#:eval untyped-eval
(inverse 2 5)
(modulo (* 2 3) 5)]
The number 0 has no inverse modulo 5.
@interaction[#:eval untyped-eval
(inverse 0 5)]
@; http://en.wikipedia.org/wiki/Modular_multiplicative_inverse
}
@defproc[(solve-chinese [as (Listof Integer)] [bs (Listof Integer)]) natural?]{
Given a list of integers @racket[as] and a list of coprime moduli @racket[ns]
the function @racket[solve-chinese] will return
the single natural solution @racket[x] in @racket[{0,...,n-1}]
to the equations
@racket[x=a1 mod n1, ..., x=ak mod nk]
where @racket[a1], ... are the elements of @racket[as],
and @racket[n1], ... are the elements of @racket[ns],
and @racket[n=n1*...*nk].
What is the least number @racket[x] that when divided by 3 leaves
a remainder of 2, when divided by 5 leaves a remainder of 3, and
when divided by 7 leaves a remainder of 2?
@interaction[#:eval untyped-eval
(solve-chinese '(2 3 2) '(3 5 7))]
@; http://en.wikipedia.org/wiki/Chinese_remainder_theorem
}
@; ----------------------------------------
@section[#:tag "primes"]{Primes}
@defproc[(prime? [z Integer]) boolean?]{
Returns @racket[#t] if @racket[z] is a prime,
@racket[#f] otherwise.
Note: An integer @racket[z] is considered a prime, if the only
positive divisors of @racket[z] are @racket[1] and @racket[|z|].
The positive primes below 20 are:
@interaction[#:eval untyped-eval
(require racket/list)
(filter prime? (range 1 21))]
The corresponding negative primes are:
@interaction[#:eval untyped-eval
(filter prime? (range 1 -21 -1))]
}
@defproc[(odd-prime? [z Integer]) boolean?]{
Returns @racket[#t] if @racket[z] is a odd prime,
@racket[#f] otherwise.
@interaction[#:eval untyped-eval
(odd-prime? 2)
(odd-prime? 3)]
}
@defproc[(nth-prime [n Natural]) natural?]{
Returns the n'th positive prime.
@interaction[#:eval untyped-eval
(nth-prime 0)
(nth-prime 1)
(nth-prime 2)]
}
@defproc[(next-prime [z Integer]) prime?]{
Returns the first prime larger than @racket[z].
@interaction[#:eval untyped-eval
(untyped-next-prime 4)
(untyped-next-prime 5)]
TODO: Figure out how to export next-prime even though
TR can't make contract automatically.
}
@defproc[(prev-prime [z Integer]) prime?]{
Returns the first prime smaller than @racket[z].
@interaction[#:eval untyped-eval
(untyped-prev-prime 4)
(untyped-prev-prime 5)]
TODO: Figure out how to export prev-prime even though
TR can't make contract automatically.
}
@defproc[(next-primes [z Integer] [n Natural]) (Listof prime?)]{
Returns list of the next @racket[n] primes larger than @racket[z].
@interaction[#:eval untyped-eval
(next-primes 2 4)]
}
@defproc[(prev-primes [z Integer] [n Natural]) (Listof prime?)]{
Returns list of the next @racket[n] primes smaller than @racket[z].
@interaction[#:eval untyped-eval
(prev-primes 13 4)]
}
@defproc[(factorize [n Natural]) (Listof (List prime? natural?))]{
Returns the factorization of a natural number @racket[n].
The factorization consists of a list of corresponding
primes and exponents. The primes will be in ascending order.
The prime factorization of 600 = 2^3 * 3^1 * 5^2:
@interaction[#:eval untyped-eval
(factorize 600)]
}
@defproc[(defactorize [f (Listof (List prime? natural?))]) natural?]{
Returns the natural number, whose factorization is given
by @racket[f]. The factorization @racket[f] is represented
as described in @racket[factorize].
@interaction[#:eval untyped-eval
(defactorize '((2 3) (3 1) (5 2)))]
}
@defproc[(divisors [z Integer]) (Listof Natural)]{
Returns a list of all positive divisors of the integer @racket[z].
The divisors appear in ascending order.
@interaction[#:eval untyped-eval
(divisors 120)
(divisors -120)]
}
@defproc[(prime-divisors [z Integer]) (Listof Natural)]{
Returns a list of all positive prime divisors of the integer
@racket[z]. The divisors appear in ascending order.
@interaction[#:eval untyped-eval
(prime-divisors 120)]
}
@defproc[(prime-exponents [z Integer]) (Listof Natural)]{
Returns a list of the exponents of in a factorization of the integer
@racket[z].
@interaction[#:eval untyped-eval
(define z (* 2 2 2 3 5 5))
(prime-divisors z)
(prime-exponents z)]
}
@; ----------------------------------------
@section[#:tag "roots"]{Roots}
@defproc[(integer-root [n Natural] [m Natural]) natural?]{
Returns the @racket[m]'th integer root of @racket[n].
This is the largest number @racket[r] such that
@racket[r^m<=n].
@interaction[#:eval untyped-eval
(integer-root (expt 3 4) 4)
(integer-root (+ (expt 3 4) 1) 4)]
}
@defproc[(integer-root/remainder [n Natural] [m Natural])
(values natural? natural?)]{
Returns two values. The first, @racket[r], is the @racket[m]'th
integer root of @racket[n]. The second is @racket[n-r^m].
@interaction[#:eval untyped-eval
(integer-root/remainder (expt 3 4) 4)
(integer-root/remainder (+ (expt 3 4) 1) 4)]
}
@; ----------------------------------------
@section[#:tag "powers"]{Powers}
@defproc[(max-dividing-power [a Integer] [b Integer]) natural?]{
Returns the largest exponent, @racket[n], of a power with
base @racket[a] that divides @racket[b].
That is, @racket[a^n] divides @racket[b] but @racket[a^(n+1)] does not divide
@racket[b].
@interaction[#:eval untyped-eval
(max-dividing-power 3 (expt 3 4))
(max-dividing-power 3 5)]
}
@defproc[(perfect-power [m Integer])
(Union (List natural? natural?) #f)]{
If @racket[m] is a perfect power, a list with two elements
@racket[b] and @racket[n] such that @racket[b^n = m]
is returned, otherwise @racket[#f] is returned.
@interaction[#:eval untyped-eval
(perfect-power (expt 3 4))
(perfect-power (+ (expt 3 4) 1))]
}
@defproc[(perfect-power? [m Integer]) boolean?]{
Returns @racket[#t] if @racket[m] is a perfect power,
otherwise @racket[#f].
@interaction[#:eval untyped-eval
(perfect-power? (expt 3 4))
(perfect-power? (+ (expt 3 4) 1))]
}
@defproc[(prime-power [m Natural])
(Union (List prime? natural?) #f)]{
If @racket[m] is a power of the form @racket[p^n]
where @racket[p] is prime, then a list with the
prime and the exponent is returned, otherwise
@racket[#f] is returned.
@interaction[#:eval untyped-eval
(prime-power (expt 3 4))
(prime-power (expt 6 4))]
}
@defproc[(prime-power? [m Natural]) boolean?]{
Returns @racket[#t] if @racket[m] is a prime power,
otherwise @racket[#f].
@interaction[#:eval untyped-eval
(prime-power? (expt 3 4))
(prime-power? (expt 6 4))
(prime-power? 1)
(prime-power? 0)]
}
@defproc[(odd-prime-power? [m Natural]) boolean?]{
Returns @racket[#t] if @racket[m] is a power of an odd prime,
otherwise @racket[#f].
@interaction[#:eval untyped-eval
(odd-prime-power? (expt 2 4))
(odd-prime-power? (expt 3 4))
(odd-prime-power? (expt 15 4))]
}
@defproc[(as-power [m Positive-Integer])
(values natural? natural?)]{
Returns two values @racket[b] and @racket[n]
such that @racket[m=b^r] and @racket[n] is maximal.
@interaction[#:eval untyped-eval
(as-power (* (expt 2 4) (expt 3 4)))
(expt 6 4)
(* (expt 2 4) (expt 3 4))
(as-power (* (expt 2 4) (expt 3 5)))]
}
@defproc[(perfect-square [m Natural])
(Union natural? #f)]{
Returns @racket[sqrt(m)] if @racket[m] is perfect
square, otherwise @racket[#f].
@interaction[#:eval untyped-eval
(perfect-square 9)
(perfect-square 10)]
}
@; ----------------------------------------
@section[#:tag "multiplicative"]{Multiplicative Functions}
In number theory a multiplicative function is a
function @racket[f] such that @racket[f(a b) = f(a) f(b)]
for all coprime natural numbers @racket[a] and @racket[b].
The functions @racket[totient], @racket[moebius-mu], and,
@racket[divisor-sum] are multiplicative.
@defproc[(totient [n Natural]) natural?]{
Returns the number of integers from 1 to @racket[n]
that are coprime with @racket[n].
This function is known as Eulers totient or phi function.
Note: The function @racket[totient] is multiplicative.
@interaction[#:eval untyped-eval
(totient 9)
(length (filter (curry coprime? 9) (range 10)))]
@; http://en.wikipedia.org/wiki/Euler%27s_totient_function
}
@defproc[(moebius-mu [n Natural]) (Union -1 0 1)]{
Returns:
@racket[1] if @racket[n] is a product of an even number of primes
@racket[-1] if @racket[n] is a product of an odd number of primes
@racket[0] if @racket[n] has a multiple prime factor
Note: The function @racket[moebius-mu] is multiplicative.
@interaction[#:eval untyped-eval
(moebius-mu (* 2 3 5))
(moebius-mu (* 2 3 5 7))
(moebius-mu (* 2 2 3 5 7))]
@; http://en.wikipedia.org/wiki/M%C3%B6bius_function
}
@defproc[(divisor-sum [n Natural] [k Natural]) natural?]{
Returns sum of the @racket[k]th powers of
all divisors of @racket[n].
Note: The function @racket[divisor-sum] is multiplicative.
@interaction[#:eval untyped-eval
(divisor-sum 12 2)
(apply + (map sqr (divisors 12)))]
@; http://en.wikipedia.org/wiki/Divisor_function
}
@; ----------------------------------------
@section[#:tag "number-sequences"]{Number Sequences}
@defproc[(bernoulli [n Natural]) exact-rational?]{
Returns the @racket[n]th Bernoulli number.
Definition:
@racket[http://en.wikipedia.org/wiki/Bernoulli_number].
@interaction[#:eval untyped-eval
(map bernoulli (range 9))]
}
@(close-eval untyped-eval)