(load "util.scm") (define (pi-summands n) (cons-stream (/ 1. n) (stream-map - (pi-summands (+ n 2))))) (define pi-stream (scale-stream (partial-sums (pi-summands 1)) 4)) (define (euler-transform s) (let ((s0 (stream-ref s 0)) ; Sn-1 (s1 (stream-ref s 1)) ; Sn (s2 (stream-ref s 2))) ; Sn+1 (cons-stream (- s2 (/ (square (- s2 s1)) (+ s0 (* -2 s1) s2))) (euler-transform (stream-cdr s))))) (define (make-tableau transform s) (cons-stream s (make-tableau transform (transform s)))) (define (accelerated-sequence transform s) (stream-map stream-car (make-tableau transform s))) ; (display (take 5 pi-stream)) ; (newline) ; (display (take 5 (euler-transform pi-stream))) ; (newline) ; (display (take 5 (accelerated-sequence euler-transform pi-stream))) ; (newline) (display "\nex-3.63 - sqrt-stream\n") (define (sqrt-improve guess x) (average guess (/ x guess))) (define (sqrt-stream x) (cons-stream 1.0 (stream-map (lambda (guess) (sqrt-improve guess x)) (sqrt-stream x)))) (define (sqrt-stream x) (define guesses (cons-stream 1.0 (stream-map (lambda (guess) (sqrt-improve guess x)) guesses))) guesses) (display (stream-ref (sqrt-stream 2) 1000)) (newline) ; The first implementation of sqrt-stream computes each value of the stream ; only once. Louis' suggestion computes all previous values because of the ; recursive calls to sqrt-stream. If memoization was not used the two solutions ; would behave in the same way. (display "\nex-3.64 - stream-limit\n") (define (stream-limit stream tolerance) (if (< (abs (- (stream-car stream) (stream-car (stream-cdr stream)))) tolerance) (stream-car (stream-cdr stream)) (stream-limit (stream-cdr stream) tolerance))) (define (sqrt-tol x tolerance) (stream-limit (sqrt-stream x) tolerance)) (assert (< (abs (- 1.4142135623730951 (sqrt-tol 2 0.01))) 0.01) #t) (assert (< (abs (- 4.795831523312719 (sqrt-tol 23 0.001))) 0.001) #t) (display "\nex-3.65 - ln2\n") (define (ln2-summands n) (cons-stream (/ 1. n) (stream-map - (ln2-summands (+ n 1))))) (define ln2-stream (partial-sums (ln2-summands 1))) ; slow (define (ln2-tol tolerance) (stream-limit ln2-stream tolerance)) ; fast (define (ln2-tol tolerance) (stream-limit (accelerated-sequence euler-transform ln2-stream) tolerance)) (assert (ln2-tol 0.00000000001) 0.6931471805599445) ; The series converges slowly. Only with acceleration we get a good result in ; reasonable time. (display "\nex-3.66\n") ; (display "\nex-3.67\n")