;; Stream definitions developed in class Tuesday, December 3 ;; This code is written in Ruse ;;---------------------------------------------------------------- ;; stream definitions developed in class last week (def nth (fun (n s) : (if (n == 0) then (zcar s) else (nth (n - 1) (zcdr s))))) (def get-first (fun (n s) : (if (n == 0) then nil ;; must use cons here to build an ordinary list else (cons (zcar s) (get-first (n - 1) (zcdr s)))))) (def print-first (fun (n s) : (if (n == 0) then (print "...") else (do (print (zcar s)) (print-first (n - 1) (zcdr s)))))) (def constant-stream (fun (n) : (zcons n (constant-stream n)))) (def ascending-stream (fun (n) : (zcons n (ascending-stream (n + 1))))) (def zmap (fun (f s) : (zcons (f (zcar s)) (zmap f (zcdr s))))) (def add1 (fun (n) : (n + 1))) ;; the natural numbers: 0 1 2 3 4 5 6 7 ... (def nats (zcons 0 (zmap add1 nats))) ;; the squares of the natural numbers: 0 1 4 9 16 25 36 49 ... (def squares (zmap square nats)) (def add-streams (fun (s1 s2) : (zcons ((zcar s1) + (zcar s2)) (add-streams (zcdr s1) (zcdr s2))))) (def multiply-streams (fun (s1 s2) : (zcons ((zcar s1) * (zcar s2)) (multiply-streams (zcdr s1) (zcdr s2))))) ;; the Fibonacci numbers: 0 1 1 2 3 5 8 13 21 34 55 ... (def fibs (zcons 0 (zcons 1 (add-streams fibs (zcdr fibs))))) ;; the factorials: 0! 1! 2! 3! 4! 5! 6! ... (def facts (zcons 1 (multiply-streams facts (zcdr nats)))) (def ! (fun (n) : (nth n facts))) ;; the powers of 2: 1 2 4 8 16 32 64 128 256 512 1024 ... (def powers-of-two (zcons 1 (add-streams powers-of-two powers-of-two))) (def 2-to-the (fun (n) : (nth n powers-of-two))) (def random-stream (fun (n) : (zcons (random n) (random-stream n)))) (def rands (random-stream 100)) ;;---------------------------------------------------------------- ;; new definitions (from Homework 18) (def scale (fun (factor s) : (zcons ((zcar s) * factor) (scale factor (zcdr s))))) (def evens (zcons 0 (zmap add2 evens))) (def add2 (fun (n) : (n + 2))) ;; alternative version (def evens (add-streams nats nats)) (def odds (zcons 1 (zmap add2 odds))) (def odd-reciprocals (zmap (fun (n) : (1 / n)) odds)) (def alternating-signs (zcons 1 (zcons -1 alternating-signs))) (def terms (multiply-streams odd-reciprocals alternating-signs)) ;; s = (n0 n1 n2 n3 n4 ...) ;; (partial-sums s) = (n0 n0+n1 n0+n1+n2 n0+n1+n2+n3 ...) (def partial-sums (fun (s) : (zcons (zcar s) (zmap (fun (n) : ((zcar s) + n)) (partial-sums (zcdr s)))))) ;;---------------------------------------------------------------- ;; computing pi ;; pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + ... ;; pi = 4 - 4/3 + 4/5 - 4/7 + 4/9 - 4/11 + 4/13 - 4/15 + ... (def pi-terms (scale 4.0 terms)) (def pi-stream (partial-sums pi-terms)) (def euler (fun (a b c) : (with [denominator = ((a - (2 * b)) + c)] : (if (denominator == 0.0) ;; avoids division by 0 then a else (c - ((square (c - b)) / denominator)))))) (def euler-transform (fun (s) : (with [a = (nth 0 s)] [b = (nth 1 s)] [c = (nth 2 s)] : (zcons (euler a b c) (euler-transform (zcdr s)))))) (def pi-stream2 (euler-transform pi-stream)) (def pi-stream3 (euler-transform pi-stream2)) (def pi-stream4 (euler-transform pi-stream3)) (def accelerate (fun (n s) : (if (n == 0) then s else (accelerate (n - 1) (euler-transform s))))) (def pi-stream5 (accelerate 5 pi-stream)) (def accelerated-streams (fun (s) : (zcons s (accelerated-streams (euler-transform s))))) (def super-pi (zmap zcar (accelerated-streams pi-stream))) ;; converges to the limit of floating-point accuracy in just 9 steps (print-first 15 super-pi)