;;; This is the code for the Heartbeat problem set. ;;; adapted from code copyright 1990 by MIT ;; ;; some useful stream functions ;; (define (print-stream s) (define (loop rest) (if (stream-null? rest) (display ")") (begin (display (stream-car rest)) (display " ") (loop (stream-cdr rest))))) (display "#STREAM(") (loop s)) (define (limited-print-stream n s) (define (loop n rest) (cond ((stream-null? rest) (display ")")) ((= n 0) (display " ...)")) (else (display (stream-car rest)) (display " ") (loop (- n 1) (stream-cdr rest))))) (display "#STREAM(") (loop n s)) (define (filter-stream pred s) (cond ((stream-null? s) the-empty-stream) ((pred (stream-car s)) (cons-stream (stream-car s) (filter-stream pred (stream-cdr s)))) (else (filter-stream pred (stream-cdr s))))) (define (map-stream proc s) (if (stream-null? s) the-empty-stream (cons-stream (proc (stream-car s)) (map-stream proc (stream-cdr s))))) (define (map-streams proc s . ss) ;; any is a generally useful procedure, but defined inside of map-streams ;; here sinc that is the only place it is used in the problem set. (define (any pred xs) (if (null? xs) #f (or (pred (car xs)) (any pred (cdr xs))))) ;; adaption of map-stream to take any number of streams > 1 ;; and a procedure that takes as many arguments as the number of streams. (let ((sss (cons s ss))) (if (any stream-null? sss) the-empty-stream (cons-stream (apply proc (map stream-car sss)) (apply map-streams (cons proc (map stream-cdr sss))))))) (define (for-each-stream proc s) (if (stream-null? s) 'done (begin (proc (stream-car s)) (for-each-stream proc (stream-cdr s))))) (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 (scale-stream constant s) (map (lambda (x) (* constant x)) s)) (define (enumerate-interval lo hi) (if (> lo hi) the-empty-stream (cons-stream lo (enumerate-interval (+ lo 1) hi)))) ;;; Some basic streams (define ones (cons-stream 1 ones)) (define integers (cons-stream 1 (add-streams ones integers))) ;;; code specifically relevant to problem set: ;; This is deliberately lousy code: if you copy it into your answer to ;; problem 1b you will not get as much credit as you would if you included a ;; better version written by yourself... (define (random-bounded lower upper) (let ((x (random upper))) (if (< x lower) (random-bounded lower upper) x))) ;; return 0 or 1 (define (flip-a-coin) (= (random 2) 0)) ;; retuen 0, 1, 2, or 3 (define (select-one-of-four) (random 4)) ;; ;; Make a heartbeat signal. ;; We have 7 x 90 random inputs to make-signal. ;; Should be able to plot the output steam with height 15. ;; (define (get-patient-heart-signal) (make-signal (random-bounded 7 14) (random-bounded 10 100))) ;; ;; Make a heartbeat signal ;; Formal parameter n is the (peak) signal strength ;; Formal parameter noise-bound is the maximum amount of noise * 100 ;; The elements of the output stream should be ;; between 0 and (+ 1 n (/ noise-bound 100)) ;; (define (make-signal n noise-bound) (let ((interval (random-bounded 7 20)) (speed-variation 0)) (let ((tolerance (random-bounded 1 interval)) (make-random (select-one-of-four))) (define (loop count) (let ((noise (/ (random noise-bound) 100))) (if (= make-random 0) (if (not (= count interval)) (cond ((= (select-one-of-four) 0) (set! count 0)) ((= (select-one-of-four) 1) (set! count (+ 7 count)))))) (cond ((= count 0) (cons-stream (if (flip-a-coin) (- (+ n 1) noise) (+ (+ n 1) noise)) (cond ((= interval 0)(loop interval)) (else (set! interval (+ interval speed-variation)) (loop interval))))) ((= count tolerance) (if (flip-a-coin) (loop (- count 1)) (cons-stream (if (flip-a-coin) (- 0 noise) noise) (loop (- count 1))))) (else (cons-stream (if (flip-a-coin) (- 0 noise) noise) (loop (- count 1))))))) (if (not (= make-random 0)) (cond ((> make-random 1) ;;; speed up/slow down OR normal (cond ((= make-random 2) (set! interval 7) ;;; Speeding up (set! speed-variation (random-bounded 1 4))) (else ;;; Slowing down (set! interval 21) (set! speed-variation (- (random-bounded 1 4)))))))) (loop interval))))