330 likes | 342 Views
This lecture covers topics such as finite and infinite streams, generating the Fibonacci sequence, finding primes using the sieve of Eratosthenes, and formulating iterations as stream processes.
E N D
Lecture 16 Streams continue Infinite Streams מבוא מורחב - שיעור 16
Finite Streams (define (stream-enumerate-interval low high) (if (> low high) the-empty-stream (cons-stream low (stream-enumerate-interval (+ low 1) high)))) (define s (stream-enumerate-interval 1 1000000000)) מבוא מורחב - שיעור 16
Infinite streams Since streams are delayed, we are not limited to finite streams!! Some objects are more naturally infinite מבוא מורחב - שיעור 16
The integers (define (integers-from n) (cons-stream n (integers-from (+ n 1)))) (define integers (integers-from 1)) מבוא מורחב - שיעור 16
Integers not divisible by 7 (define (divisible? x y) (= (remainder x y) 0)) (define no-sevens (stream-filter (lambda (x) (not (divisible? x 7))) integers)) (stream-ref no-sevens 100) 117 מבוא מורחב - שיעור 16
Fibonacci sequence (define (fib-seq-from a b) (cons-stream a (fib-seq-from b (+ a b)))) (define fib-seq (fib-seq-from 0 1)) מבוא מורחב - שיעור 16
Fibonacci sequence • (define (fib-seq-from a b) (cons-stream a (fib-seq-from b (+ a b)))) • (define fib-seq (fib-seq-from 0 1)) • fib-seq (0 . #<struct:promise>[fib-seq-from 1 1]) • (stream-ref fib-seq 3) (stream-ref (stream-cdr fib-seq) 2) (stream-ref (fib-seq-from 1 1) 2) (stream-ref (cons 1 (delay (fib-seq-from 1 2))) 2) (stream-ref (stream-cdr (cons 1 (delay (fib-seq-from 1 2)) 1) (stream-ref (fib-seq-from 1 2) 1) (stream-ref (cons 1 (delay (fib-seq from 2 3))) 1) (stream-ref (stream-cdr (cons 1 (delay (fib-seq-from 2 3)))) 0) (stream-ref (fib-seq-from 2 3) 0) (stream-ref (cons 2 (delay (fib-seq-from 3 5))) 0) 2 מבוא מורחב - שיעור 16
2 3 4 5 6 7 8 9 10 2 X X 7 X XX 11 12 13 14 15 16 17 18 19 20 XX XX XX XX XX XX 21 22 23 24 25 26 27 28 29 30 XX XX XX XX XX XX XX 3 5 X X XX 31 32 33 34 35 36 37 38 39 40 XX XX XX XX XX XX XX XX XX XX XX 41 42 43 44 45 46 47 48 49 50 XX XX XX XX XX XX XX XX XX XX XX XX XX 51 52 53 54 55 56 57 58 59 60 XX XX XX XX XX XX XX XX XX XX XX 61 62 63 64 65 66 67 68 69 60 XX XX XX XX XX XX XX XX XX XX XX XX 71 72 73 74 75 76 77 78 79 80 XX XX XX XX XX XX XX XX XX XX XX XX 81 82 83 84 85 86 87 88 89 90 XX XX XX XX XX XX XX XX XX XX XX XX XX 91 92 93 94 95 96 97 98 99 100 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX Finding all the primes using the sieve of Eratosthenes מבוא מורחב - שיעור 16
The sieve of Eratosthenes using streams (define (sieve str) (cons-stream (stream-car str) (sieve (stream-filter (lambda (x) (not (divisible? x (stream-car str)))) (stream-cdr str))))) (define primes (sieve (stream-cdr integers))) מבוא מורחב - שיעור 16
The integers, again (implicit version) We saw the definition: (define (integers-from n) (cons-stream n (integers-from (+ n 1)))) (define integers (integers-from 1)) An alternative definition: (define integers (cons-stream 1 (stream-map (lambda (x) (+ x 1)) integers)) input to stream-map (integers) 1 2 ..... integers result: element + 1 ..... 3 1 2 מבוא מורחב - שיעור 16
The integers – another way (define ones (cons-stream 1 ones)) (define integers (cons-stream 1 (add-streams ones integers)) (define (add-streams s1 s2) (stream-map + s1 s2)) A direct implementation of add-streams: (define (add-streams s1 s2) (cons-stream (+ (stream-car s1) (stream-car s2)) (add-streams (stream-cdr s1) (stream-cdr s2)))) מבוא מורחב - שיעור 16
3 2 1 (stream-cdr fibs) 3 2 1 fibs 1 1 0 0 fibs Implicit definition of the Fibonacci numbers (define fibs (cons-stream 0 (cons-stream 1 (add-streams (stream-cdr fibs) fibs)))) 1 1 2 3 מבוא מורחב - שיעור 16
double 1 (scale-factor double 2) 2 4 8 2 4 8 More implicit definitions (define (scale-stream str factor) (stream-map (lambda (x) (* x factor)) str) (define double (cons-stream 1 (scale-stream double 2))) מבוא מורחב - שיעור 16
The stream of primes – another way (define primes (cons-stream 2 (stream-filter prime? (integers-from 3)))) (define (prime? n) (define (iter ps) (cond ((> (square (stream-car ps)) n) #t) ((divisible? n (stream-car ps)) #f) (else (iter (stream-cdr ps))))) (iter primes) • A recursive definition. • Works because the primes needed to check primality of the next number are always ready. מבוא מורחב - שיעור 16
Formulating iterations as stream processes (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (sqrt-improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (sqrt-improve guess)))) (sqrt-iter 1.0)) מבוא מורחב - שיעור 16
Formulating iterations as stream processes (cont’d) (define (sqrt-stream x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (sqrt-improve guess x) (average guess (/ x guess))) (define guesses (cons-stream 1.0 (stream-map (lambda (guess) (sqrt-improve guess x)) guesses))) ________________________________________________ ________________________________________________ ________________________________________________) (stream-car (stream-filter (lambda(x) (good-enough? x)) guesses))) מבוא מורחב - שיעור 16
1 1 1 . . . + - - 1 = 4 5 3 7 Formulating iterations as stream processes (Cont.) (define (pi-summands n) (cons-stream (/ 1.0 n) (stream-map - (pi-summands (+ n 2))))) (pi-summands 1) (1 (stream-map - (pi-summands 3))) (1 (stream-map - (1/3 (stream-map - (pi-summands 5)))) (1 -1/3 (stream-map - (stream-map - (pi-summands 5)))) (1 -1/3 +1/5 (stream-map - (stream-map - (stream-map - (pi-summands 7))))) מבוא מורחב - שיעור 16
1 1 1 . . . + - - 1 = 4 7 5 3 S = S0,S0+S1,S0+S1+S2,… Replacing state variables with streams (Cont.) (define (pi-summands n) (cons-stream (/ 1.0 n) (stream-map - (pi-summands (+ n 2))))) (define pi-stream (scale-stream (partial-sums (pi-summands 1)) 4)) (display-stream pi-stream) 4. 2.6666 3.4666 2.8952 3.3396 2.9760 converges very slowly! מבוא מורחב - שיעור 16
(Sn+1 - Sn)2 Sn+1 S’n = - Sn-1 - 2Sn + Sn+1 Speeding up convergence (define (euler-transform s) (let ((s0 (stream-ref s 0)) (s1 (stream-ref s 1)) (s2 (stream-ref s 2))) (cons-stream (- s2 (/ (square (- s2 s1)) (+ s0 (* -2 s1) s2))) (euler-transform (stream-cdr s))))) מבוא מורחב - שיעור 16
Speeding Up Convergence (Cont.) (display-stream (euler-transform pi-stream)) 3.1666 3.1333 3.1452 3.1396 3.1427 3.1408 מבוא מורחב - שיעור 16
Speeding up convergence even further (define (make-tableau transform s) (cons-stream s (make-tableau transform (transform s)))) produces a stream of streams: s, (transform s), (transform (transform s)) . . . S00 S01 S02 S03 … S10 S11 S12 … S20 S21 … S30 … מבוא מורחב - שיעור 16
Speeding up convergence even further (Cont.) (define (accelerated-sequence transform s) (stream-map stream-car (make-tableau transform s))) S00 S01 S02 S03 . . S10 S11 S12 . . . S20 S21 ,. . . . . . (display-stream (accelerated-sequence euler-transform pi-stream)) 4. 3.1666… 3.1421… 3.1415… מבוא מורחב - שיעור 16
Infinite streams of pairs Want to produce the stream of pairs of all integers (i,j) with i j and bind it to int-pairs. Abstraction: Let’s solve an even more general problem. Given two streams S=(S1, S2 . . . . .) T=(T1, T2 . . . . .) Consider the infinite rectangular array (S1,T1) (S1,T2) (S1,T3) . . . (S2,T1) (S2,T2) (S2,T3) . . . (S3,T1) (S3,T2) (S3,T3) . . . . . . . . . . . . מבוא מורחב - שיעור 16
Infinite streams of pairs (S1,T1) (S1,T2) (S1,T3) . . . (S2,T1) (S2,T2) (S2,T3) . . . (S3,T1) (S3,T2) (S3,T3) . . . . . . . . . . . . Wish to produce all pairs that lie on or above the diagonal: j (S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . . i If S and T are both the integers then this would be int-pairs מבוא מורחב - שיעור 16
Infinite streams of pairs (S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . . 2 1 3 Write a function pairs such that (pairs s t) would be the desired stream. Wishful thinking: Break the desired stream into three pieces מבוא מורחב - שיעור 16
Produce by (pairs (stream-cdr s) (stream-cdr t)) Produce by (list (stream-car s) (stream-car t)) 3 1 Produce by (stream-map (lambda (x) (list (stream-car s) x)) (stream-cdr t)) 2 Infinite streams of pairs (S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . . 2 1 3 מבוא מורחב - שיעור 16
How do we combine? Infinite streams of pairs (define (pairs s t) (cons-stream (list (stream-car s) (stream-car t)) (combine-in-some-way (stream-map (lambda (x) (list (stream-car s) x)) (stream-cdr t)) (pairs (stream-cdr s) (stream-cdr t))))) 1 2 3 (define (stream-append s1 s2) (if (stream-null? s1) s2 (cons-stream (stream-car s1) (stream-append (stream-cdr s1) s2)))) מבוא מורחב - שיעור 16
(display-stream int-pairs) (1 1) (1 2) (1 3) (1 4) … • will never produce a pair with first component different from 1 !! stream-append does not work when the first stream in infinite We want to be able to produce any pair by applying stream-cdr enough times. Infinite streams of pairs (cont’d) (define int-pairs (pairs integers integers)) מבוא מורחב - שיעור 16
Infinite streams of pairs (cont’d) (define (pairs s t) (cons-stream (list (stream-car s) (stream-car t)) (interleave (stream-map (lambda (x) (list (stream-car s) x)) (stream-cdr t)) (pairs (stream-cdr s) (stream-cdr t))))) (define (interleave s1 s2) (if (stream-null? s1) s2 (cons-stream (stream-car s1) (interleave s2 (stream-cdr s1))))) מבוא מורחב - שיעור 16
Infinite streams of pairs (cont’d) (define (pairs s t) (cons-stream (list (stream-car s) (stream-car t)) (interleave (stream-map (lambda (x) (list (stream-car s) x)) (stream-cdr t)) (pairs (stream-cdr s) (stream-cdr t))))) • (define int-pairs (pairs integers integers)) • (display-stream int-pairs) (1 1) (1 2) (2 2) (1 3) (2 3) (1 4) (3 3) (1 5)… מבוא מורחב - שיעור 16
Produce by (pairs (stream-cdr s) (stream-cdr t)) Produce by (stream-map (lambda (x) (list (stream-car s) x)) t) 2 1 Isn’t there a simpler solution? (S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . . 1 2 (define (pairs s t) (interleave (stream-map (lambda (x) (list (stream-car s) x)) t) (pairs (stream-cdr s) (stream-cdr t))))) מבוא מורחב - שיעור 16
Would this work? Infinite loop!!! pairs calls interleave with pairs as a parameter, which causes pairs to be evaluated (S1,T1) (S1,T2) (S1,T3) . . . (S2,T2) (S2,T3) . . . (S3,T3) . . . . . . 1 2 (define (pairs s t) (interleave (stream-map (lambda (x) (list (stream-car s) x)) t) (pairs (stream-cdr s) (stream-cdr t))))) (define (interleave s1 s2) (if (stream-null? s1) s2 (cons-stream (stream-car s1) (interleave s2 (stream-cdr s1))))) Because there is no pre-computed “car”, interleave is called again…which calls pairs and so on. מבוא מורחב - שיעור 16
The generalized stream-map(multiple streams) (define (stream-map proc . argstreams) (if (or (null? argstreams) (stream-null? (car argstreams))) the-empty-stream (cons-stream (apply proc (map stream-car argstreams)) (apply stream-map (cons proc (map stream-cdr argstreams)))))) • Does it work for finite/infinite streams? • What if some are finite and others infinite? • What about finite streams with different lengths? מבוא מורחב - שיעור 16