Title: Primality Testing
1Lecture 5
2Primality Testing
- (define (prime? n)
- ( n (smallest-divisor n)))
- (define (smallest-divisor n)
- (find-divisor n 2))
- (define (find-divisor n test-divisor)
- (cond ((divides? test-divisor n) test-divisor)
- (else (find-divisor n ( test-divisor
1))))) - (define (divides? a b)
- ( (remainder b a) 0))
3Analysis
- Time complexity ?(n) linear
There are infinitely many ns for which it takes
cn time
4A more efficient test
- (define (prime? n)
- ( n (smallest-divisor n)))
- (define (smallest-divisor n)
- (find-divisor n 2))
- (define (find-divisor n test-divisor)
- (cond ((gt (square test-divisor) n) n)
- ((divides? test-divisor n) test-divisor)
- (else (find-divisor n ( test-divisor
1))))) - (define (divides? a b)
- ( (remainder b a) 0))
5Analysis
6The Fermat Primality Test
- Fermats little theorem
- If n is a prime number then
- an mod n a for every 0 lt a lt n, integer
- If n is not a prime, most numbers a lt n will not
- meet the conditions of the theorem.
- The Fermat Test
- 1. Pick a random a lt n and compute an mod n
- If ? a return not prime
- If a chances are good that it is prime.
- 2. Repeat step 1
7A more efficient test
- (define (expmod base exp m)
- (cond (( exp 0) 1)
- ((even? exp)
- (remainder (square (expmod base (/ exp
2) m)) m)) - (else
- (remainder ( base (expmod base (- exp 1)
m) m)))) - (define (fermat-test n)
- (define (try-it a)( (expmod a n n) a))
- (try-it ( 1 (random (- n 1)))))
- (define (fast-prime? n times)
- (cond (( times 0) true)
- ((fermat-test n) (fast-prime? n (- times
1))) - (else false)))
8Some mathematical facts
- There are composite numbers n that pass the
Fermat test, that is - an mod n a for every 0 lt a lt n, integer
- They are called Carmichael numbers.
- The smallest is 561.
- A slight modification of fast-prime? due to Rabin
- and Miller can handle every input and return
- an answer which is correct with very high
probability - within Q(1) number of tests and Q(log(n)) time .
9Types
- ( 5 10) gt 15( 5 "hi") The object "hi",
passed as the second argument to integer-add, is
not the correct type - Addition is not defined for strings
- The type of the integer-add procedure is
number, number ? number
10Type examples
- expression evaluates to a value of type
- 15 number
- "hi" string
- square number ? number
- gt number,number ? boolean (gt 5 4) gt t
-
- The type of a procedure is a contract
- If the operands have the specified types,the
procedure will result in a value of the specified
type - otherwise, its behavior is undefined
- maybe an error, maybe random behavior
11Types, precisely
- A type describes a set of scheme values
- number ? number describes the setall
procedures, whose result is a number, which
require one argument that must be a number - Every scheme value has a type
12Your turn
- The following expressions evaluate to values of
what type?(lambda (a b c) (if (gt a 0) ( b c)
(- b c)))(lambda (p) (if p "hi" "bye"))(
3.14 ( 2 5))
number
13Types (summary)
- type a set of values
- every value has a type
- procedure types (types which include ?) indicate
- number of arguments required
- type of each argument
- type of result of the procedure
- Types a mathematical theory for reasoning
efficiently about programs - useful for preventing certain common types of
errors - basis for many analysis and optimization
algorithms
14What is procedure abstraction?
- Capture a common pattern
- ( 2 2)
- ( 57 57)
- ( k k)
Give it a name (define square (lambda (x) ( x
x)))
Note the type number ? number
15Other common patterns
- 1 2 100 (100 101)/2
- 1 4 9 1002 (100 101 201)/6
- 1 1/32 1/52 1/1012 p2/8
- (define (sum-integers a b) (if (gt a b)
0 ( a (sum-integers ( 1 a) b)))) - (define (sum-squares a b) (if (gt a b)
0 ( (square a) (sum-squares
( 1 a) b)))) - (define (pi-sum a b) (if (gt a b) 0
( (/ 1 (square a)) (pi-sum ( a 2)
b))))
(define (sum term a next b) (if (gt a b)
0 ( (term a) (sum term (next a)
next b))))
16Lets check this new procedure out!
- (define (sum term a next b)
- (if (gt a b)
- 0
- ( (term a)
- (sum term (next a) next b))))
- What is the type of this procedure?
(number ? number, number, number? number, number)
? number
17Higher order procedures
- A higher order proceduretakes a procedure as an
argument or returns one as a value - (define (sum-integers1 a b)
- (sum (lambda (x) x) a (lambda (x) ( x 1))
b)) - (define (sum-squares1 a b)
- (sum square a (lambda (x) ( x 1)) b))
- (define (pi-sum1 a b)
- (sum (lambda (x) (/ 1 (square x))) a (lambda
(x) ( x 2)) b))
18Does it work?
- (define (sum term a next b)
- (if (gt a b) 0
- ( (term a) (sum term (next a) next b))))
- (sum-sq 1 10)
- (sum square 1 (lambda (x) ( x 1)) 10)
- ( (sq 1) (sum sq ((lambda (x) ( x 1)) 1)
- (lambda (x) ( x 1)) 10))
- ( 1 (sum sq 2 (lambda (x) ( x 1)) 10))
- ( 1 ( (sq 2) (sum sq ((lambda (x) ( x 1)) 2)
- (lambda (x) ( x 1)) 10)))
- ( 1 ( 4 (sum sq 3 (lambda (x) ( x 1)) 10)))
19Integration as a procedure
- Integration under a curve f is given roughly by
- dx (f(a) f(a dx) f(a 2dx) f(b))
(define (integral f a b) ( (sum f a (lambda
(x) ( x dx)) b) dx)) (define dx 1.0e-3)
(define atan (lambda (a)
(integral (lambda (x) (/ 1 ( 1 (square x)))) 0
a)))
20The syntactic sugar Let
Suppose we wish to implement the function
f(x,y) x(1xy)2 y(1-y) (1xy)(1-y)
We can also express this as a 1xy b
1-y f(x,y) xa2 yb ab
21The syntactic sugar Let
(define (f x y) ((lambda (a b) ( ( x
(square a)) ( y b) ( a b)))
( 1 ( x y)) (- 1 y)))
(define (f x y) (define (f-helper a b) (
( x (square a)) ( y b) ( a b)))
(f-helper ( 1 ( x y)) (- 1 y)))
(define (f x y) (let ((a ( 1 ( x y)))
(b (- 1 y))) ( ( x (square a)) ( y
b) ( a b))))
22The syntactic sugar Let
(Let ((ltvar1gt ltexp1gt) (ltvar2gt ltexp2gt)
.. (ltvarngt ltexpngt)) ltbodygt)
((lambda (ltvar1gt .. ltvarngt) ltbodygt)
ltexp1gt ltexp2gt ltexpngt)
23Finding fixed points
- Heres a common way of finding fixed points
- Given a guess x1, let new guess by f(x1)
- Keep computing f of last guess, till close enough
(define (fixed-point f first-guess) (define
(close-enough? v1 v2) (lt (abs (- v1 v2))
tolerance)) (define (try guess) (let ((next
(f guess))) (if (close-enough? guess next)
next (try next)))) (try
first-guess)) (define tolerance 0.00001)
24Using fixed points
- (fixed-point (lambda (x) ( 1 (/ 1 x))) 1) --gt
1.6180 - Â or x 1 1/x when x (1 5)/2
(define (sqrt x) (fixed-point (lambda (y)
(/ x y)) 1))
Unfortunately if we try (sqrt 2), this oscillates
between 1, 2, 1, 2,
(define (fixed-point f first-guess) (define
(close-enough? v1 v2) (lt (abs (- v1 v2))
tolerance)) (define (try guess) (let ((next
(f guess))) (if (close-enough? guess next)
next (try next)))) (try
first-guess))
25So damp out the oscillation
- (define (average-damp f)
- (lambda (x)
- (average x (f x))))
Check out the type (number ? number) ?
(number ? number) that is, this takes a procedure
as input, and returns a NEW procedure as output!!!
- ((average-damp square) 10)
- ((lambda (x) (average x (square x))) 10)
- (average 10 (square 10))
- 55
26 which gives us a clean version of sqrt
- (define (sqrt x)
- (fixed-point
- (average-damp
- (lambda (y) (/ x y)))
- 1))
- Compare this to our previous implementation
same process. - (define (cbrt x)
- (fixed-point
- (average-damp
- (lambda (y) (/ x (square y))))
- 1))