cs220 programming principles
DESCRIPTION
CS220 Programming Principles. 프로그래밍의 이해 2002 가을학기 Class 13: Streams 한 태숙. Stream Data Abstraction. ; stream - a sequence of state in time ; list with delayed evaluation ; Delayed List ; recursive process with list (define (sum-prime a b) (accumulate + 0 - PowerPoint PPT PresentationTRANSCRIPT
CS220Programming Principles
프로그래밍의 이해 2002 가을학기Class 13: Streams
한 태숙
2
Stream Data Abstraction
; stream - a sequence of state in time
; list with delayed evaluation
; Delayed List
; recursive process with list
(define (sum-prime a b)
(accumulate + 0
(filter prime?
(enumerate-interval a
b))))
; requires many copies of list
3
List with Iterative Style
(define sum-primes a b)
(define (iter count accum)
(cond ((> count b) accum)
((prime? count)
(iter (+ count 1)(+ count accum)))
(else (iter (+ count 1) accum))))
(iter a 0))
; no need to copy the list
; necessary part of the list are traversed
; no intermediate storage are required
4
Inefficiency in using list
; get the second prime in the interval given
(car (cdr (filter prime?
(enumerate-interval 10000
1000000))))
;With Streams
;We can formulate programs elegantly as
; sequence manipulations
; while attaining the efficiency of
; incremental computation.
(stream-car (cons-stream x y)) == x
(stream-cdr (cons-stream x y)) == y
the-empty-stream, stream-null?
5
List HOPs to Stream HOPs (I)
(define (list-ref lst n)
(if (= n 0)
(car lst)
(list-ref (cdr lst) (- n 1))))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
6
List HOPs to Stream HOPs (II)
(define (map proc lst)
(if (null? lst)
’()
(cons (proc (car lst))
(map proc (cdr lst)))))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream (proc (stream-car s))
(stream-map proc
(stream-cdr s)))))
7
List HOPs to Stream HOPs (III)(define (filter pred lst)
(cond ((null? lst) ’())
((pred (car lst))
(cons (car lst)
(filter pred (cdr lst))))
(else (filter pred (cdr lst)))))
(define (stream-filter pred s)
(cond ((stream-null? s) the-empty-stream)
((pred (stream-car s))
(cons-stream (stream-car s)
(stream-filter pred (stream-cdr s))))
(else (stream-filter pred (stream-cdr s)))))
8
List HOPs to Stream HOPs (IV)
(define (enum-interval low high)
(if (> low high)
’()
(cons low
(enum-interval (+ low 1) high))))
(define (enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream low
(enumerate-interval (+ low 1)
high))))
9
List HOPs to Stream HOPs (V)
(define (stream-for-each proc s)
(if (stream-null? s)
’done
(begin (proc (stream-car s))
(stream-for-each proc
(stream-cdr s)))))
(define (display-stream s)
(stream-for-each display-line s))
(define (display-line x)
(newline)
(display x))
10
List HOPs to Stream HOPs (VI)
(define (accumulate-stream combiner init s)
(if (stream-null? s)
init
(combiner (stream-car s)
(accumulate-stream combiner
init
(stream-cdr s)))))
11
Program without Iteration
(define (sum-odd-square from to)
(accumulate-stream + 0
(stream-map square
(stream-filter odd?
(enumerate-interval from to)))))
(define (integral f lo hi dx)
(* dx (accumulate-stream + 0
(stream-map f
(stream-map (lambda (x) (+ lo x))
(stream-scale dx
(enumerate-interval 0
(ceiling (/ (- hi lo) dx))))))))
12
Stream Implementation
;Arrange so that the cdr of a stream
; is evaluated when it is accessed
; by the stream-cdr rather than when
; the stream is constructed
(cons-stream <x> <y>)
=== (cons <x> (delay <y>))
(define (stream-car s)(car s))
(define (stream-cdr s)(force (cdr s)))
13
(delay <exp>)
special form: not evaluating <exp> returns an object that will later evaluate exp whe
n that object is given to a procedure force as its argument : delayed object (“promise”)
force takes a delayed object as argument and perform evaluation.– (force (delay <exp>)) == <exp>
(define (cons-stream a b)
(cons a (delay b)))
is not feasible.
14
Stream : “Demand-driven” programming
(stream-car
(stream-cdr
(stream-filter prime?
(enumerate-interval 10 1000))))
-> (cons 10
(delay (enumerate... 11..))
15
Implementing delay and force
(delay <exp>) is syntactic sugar for
(lambda () <exp>)
(define (force delayed-object)
(delay-object)) Inefficiency in recursive program Call-by-need
– once evaluated, remember the value.– returns remembered value when called again.– (memo-proc proc)
16
(memo-proc proc)
(define (memo-proc proc)
(let ((already-run? false)(result false))
(lambda ()
(if (not already-run?)
(begin (set! result (proc))
(set! already-run? true)
result)
result))))
(delay <exp>) is equivalent to
(memo-proc (lambda () <exp>))
17
cons-stream :macro
;(define (cons-stream <x> <y>)
; (cons <x> (delay <y>)))
(define ones (cons-stream 1 ones))
;(define ones (cons 1 (delay ones)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream)
(force (cdr stream)))
(define-macro cons-stream
(lambda (x . y)
`(cons ,x (delay ,@y))))
18
Some Simple Streams
;;Recursive definition
(define (integers-from n)
(cons-stream n
(integers-from (+ 1 n))))
;; infiniite streams
(define integers (integers-from 1))
(define fibgen a b)
(cons-stream a (fibgen b (+ a b))))
(define fibs (fibgen 0 1))
19
Stream using HOP
;; Examples using stream HOP
(define no-sevens
(stream-filter
(lambda (x) (not (divisible? x 7)))
integers))
(define (divisible? x y)
(= (remainder x y) 0))
(stream-ref no-sevens 100)
; => Value 117
20
Sieve of Eratosthenes
;manipulate just like a finite sized object
(define (sieve s)
(cons-stream
(stream-car s)
(sieve
(stream-filter
(lambda (x)
(not (divisible? x (stream-car s))))
(stream-cdr s)))))
(define primes (sieve (integer-from 2)))
(stream-ref primes 200)
; Value: 1229
21
More Stream Utilities(define (add-streams s1 s2)
(cond ((stream-null? s1) s2)
((stream-null? s2) s1)
(else
(cons-stream (+ (stream-car s1)
(stream-car s2))
(add-streams (stream-cdr s1)
(stream-cdr s2))))))
(define (show-stream s n)
(cond ((= n 0) ’done)
(else (newline)
(display (stream-car s))
(show-stream (stream-cdr s) (- n 1)))))
22
More More Stream Utilities
(define (stream-map2 proc s1 s2)
(if (stream-null? s1)
the-empty-stream
(cons-stream (proc (stream-car s1)
(stream-car s2))
(stream-map2 proc
(stream-cdr s1)
(stream-cdr s2)))))
;
(define ones (cons-stream 1 ones))
(define integers
(cons-stream 1 (add-streams ones integers)))
23
Stream of Fibonacci numbers
(define fibs
(cons-stream
0
(cons-stream
1
(add-streams (stream-cdr fibs)
fibs))))
(show-stream fibs 9)
0
1
; 0 1 1 2 3 5 8 13 21
24
More Example
(define (scale-stream s factor)
(stream-map (lambda (x)(* x factor)) s))
; 1 2 4 8 16 32 .........
(define double
(cons-steam 1 (scale-stream double 2)))
;Exercise 3.53
(define s (cons-stream 1 (add-streams s s)))
25
Prime Numbers
(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))
26
Square Roots
;;Previous procedural implementation
(define (sqrt x)
(define (try guess)
(if (good-enough? guess)
guess
(try (improve guess)))) (define (improve guess)
(average guess (/ x guess)))
(define (good-enough? guess)
(close? (* guess guess) x))
(try 1))
27
Stream of Square Roots
(define (sqrt-improve guess x)
(average guess (/ x guess)))
(define (average a b) (/ (+ a b) 2))
(define (sqrt-stream x)
(cons-stream
1.0
(stream-map (lambda (g)
(sqrt-improve g x))
(sqrt-stream x))))
28
Running square-root
(show-stream (sqrt-stream 2) 7)
1.
1.5
1.4166666666666665
1.4142156862745097
1.4142135623746899
1.414213562373095
1.414213562373095
;Value: done
29
Ex 3.63
(define (sqrt-stream x)
(define guesses
(cons-stream
1.0
(stream-map (lambda (g)
(sqrt-improve g x))
guesses)))
guesses)
;;Ex. 3.63 difference in efficiency?
30
Stream to Desired Tolerance Limit
(define (stream-limit s tol) ; Exercise 3.64
(define (iter s)
(let ((f1 (stream-car s))
(f2 (stream-car (stream-cdr s))))
(if (close-enuf? f1 f2 tol)
f2
(iter (stream-cdr s)))))
(iter s))
(define (close-enuf? x y tol)
(< (abs (- x y)) tol))
(stream-limit (sqrt-stream 2) 1.e-5)
;Value: 1.4142135623746899
31
Witch of AgnesiThe bell-shaped witch of Maria Agnesi can be constructed in the following way.
Start with a circle of diameter a , centered at the point (0,a/2) on the y-axis. Choose a point A on the line y=a and connect it to the origin with a line segment. Call the point where the segment crosses the circle B. Let P be the point where the vertical line through A crosses the horizontal line through B. The witch is the curve traced by P as A over along the line y=a.
y=a C A
B P(x,y)
0
y=a3
x2+a2
32
Trapezoidal Integration
;Trapezoidal Integration
(define (trapezoid f a b h)
(let ((dx (* (- b a) h))
(n (/ 1 h)))
(define (iter i sum)
(let ((x (+ a (* i dx))))
(if (>= i n)
sum
(iter (+ i 1) (+ sum (f x))))))
(* dx (iter 1 (+ (/ (f a) 2)
(/ (f b) 2))))))
33
Caculation of ;The Witch of Agnesi and Approximation to (define (witch x)
(/ 4 (+ 1 (* x x))))
(trapezoid witch 0. 1. .1)
3.1399259889071587
(trapezoid witch 0. 1. .01)
3.141575986923129
; see http://www.agnesscott.edu/lriddle/women/agnesi.htm
34
Stream of Approximation to ; Stream of Approximation to pi
(define (keep-halving R h)
(cons-stream (R h)
(keep-halving R (/ h 2))))
(show-stream
(keep-halving
(lambda (h) (trapezoid witch 0 1 h)) 0.1)
9)
(stream-limit
(keep-halving
(lambda (h) (trapezoid witch 0 1 h)) 0.5)
1.e-9)
35
Result
3.1399259889071587
3.1411759869541287
3.1414884869236115
3.141566611923134
3.1415861431731273
3.1415910259856252
3.1415922466887523
3.1415925518645325
3.1415926281584774
done
3.1415926534345684
; after 65549 evaluation of witch
36
Accelerating the Approximation
Suppose we want to approximate a function R(0).
Given a sequence of values:
R(h), R(h/2), R(h/4), .....
If we know that R has the form
R(h)= A + Bhp + Ch2p + Dh3p + ....
Then
= A + C2h2p + D2h3p + ...
2pR(h/2)-R(h)
2p-1
37
Accelerating the Stream
This new sequence converges to the same value as the original, but it converges faster.
(define (accel-halving-seq s p)
(let ((2**p (expt 2 p)))
(let ((2**p-1 (- 2**p 1)))
(stream-map2 (lambda (Rh Rh/2)
(/ (- (* 2**p Rh/2)
Rh)
2**p-1))
s
(stream-cdr s)))))
38
Rapid Acceleration
;Make a table, where each row is the
; accelerated version of the previous row.
(define (make-tableau s p)
(define (rows s order)
(cons-stream s
(rows (accel-halving-seq
s order)
(+ order p))))
(rows s p))
39
Richardson acceleration
;take just the first element of each row
; "Richardson acceleration" of the original
; series
(define (richardson-accel s p)
(stream-map stream-car
(make-tableau s p)))
40
; test
(show-stream
(richardson-accel
(keep-halving
(lambda (h)(trapezoid witch 0 1 h)) .1)
2)
5)
3.1399259889071587
3.1415926529697855
3.1415926536207945
3.141592653589793
3.1415926535897944
41
(stream-limit
(richardson-accel
(keep-halving
(lambda (h) (trapezoid witch 0 1 h)) .1)
2)
1.e-9)
3.1415926536207945
;This requires only 73 evaluations of the
;witch!
42
Streams as signals
integrator– input stream x = (xi)
– initial value C increment dt
– output stream S = (Si)
Si = C + ij=1 xj dt
scale:dt
addcons
input C integral
43
(define (integral intergrand
initial-value dt)
(define int
(cons-stream
initial-value
(add-stream (scale-stream
integrand dt)
int)))
int)
44
Solving dy/dt=f(y)
(define (solve f y0 dt)
(define y (integral dy y0 dt))
(define dy (stream-map f y))
y)
map: fdy y
integral
y0
45
Integral with delayed argument; Streams and Delayed Evaluation
(define (integral delayed-integrand initial-value dt)
(define int
(cons-stream initial-value
(let ((integrand
(force delayed-integrand)))
(add-streams (scale-stream integrand
dt)
int))))
int)
;estimating e
(stream-ref (solve (lambda (y) y) 1 0.001) 1000)
2.716923932235896
46
Normal-Order Evaluation
We sometimes need delayed arguments. Why don’t we make all arguments are evaluated
when necessary? – normal order evaluation – Evaluation overhead
• “call by need”, strictness analysis
– hard to read programs