SICP問題3.75

Louis Reasonerが定義したバグの入った平滑化make-zero-crossings(教科書で定義)

(define (make-zero-crossings input-stream last-value)
  (let ((avpt (/ (+ (stream-car input-stream) last-value) 2)))
    (cons-straem (sign-change-detector avpt last-value)
                 (make-zero-crossings (stream-cdr input-stream)
                                      avpt))))

バグは平均値をlast-valueとして渡していること。
またsign-change-detectorは前回の平均値と今回の平均値でとる必要があるため、修正した手続きは以下のようになる。

(define (make-zero-crossings input-stream last-value last-avpt)
  (let ((avpt (/ (+ (stream-car input-stream) last-value) 2)))
    (cons-straem (sign-change-detector avpt last-avpt)
                 (make-zero-crossings (stream-cdr input-stream)
                                      (stream-car input-stream) avpt))))

ただ、この修正だけだと zero-crossings 定義時に無限ループしてしまったので以下のように修正

(define (make-zero-crossings input-stream last-value last-avpt)
  (cons-stream (sign-change-detector (/ (+ (stream-car input-stream) last-value) 2)
                                     last-avpt)
               (make-zero-crossings (stream-cdr input-stream)
                                    (stream-car input-stream)
                                    (/ (+ (stream-car input-stream) last-value) 2))))
(define zero-crossings (make-zero-crossings sense-data 0 0))

テスト

(stream-ref-range zero-crossings 0 20)
; 0
; 0
; 0
; 0
; 0
; 0
; -1
; 0
; 0
; 0
; 0
; 1
; 0
; 0
; 0
; 0
; 0
; 0
; 0
; -1
; #<undef>