さかもとのブログ

つらつらと

SICP演習問題3.64~3.65

id:rsakamot:20090615:1245075079の表示用を直した.

(define (stream-ref-print s n)
  (let loop ((count 0))
    (if (> count n)
        'done
        (begin
          (print (stream-ref s count))
          (loop (+ count 1))))))
;;exercise3.64
(define (stream-limit stream tolerance)
  (let ((s1 (stream-car stream))
        (s2 (stream-car (stream-cdr stream))))
    (if (< (abs (- s1 s2)) tolerance)
        s2
        (stream-limit (stream-cdr stream) tolerance))))

(define (sqrt x tolerance)
  (stream-limit (sqrt-stream x) tolerance))

(sqrt 2 0.00001)

3.65は3つの方法の効率の差が歴然.

;;exercise3.65
(define (ln2-summands n)
  (cons-stream (/ 1.0 n)
               (stream-map - (ln2-summands (+ n 1)))))

(define ln2-stream
  (partial-sums (ln2-summands 1)))
  • 何も使わない
(stream-ref-print ln2-stream 10)
;gosh> 1.0
;0.5
;0.8333333333333333
;0.5833333333333333
;0.7833333333333332
;0.6166666666666666
;0.7595238095238095
;0.6345238095238095
;0.7456349206349207
;0.6456349206349207
  • euler transformをつかう
(stream-ref-print (euler-transform ln2-stream) 10)
;gosh> 0.7
;0.6904761904761905
;0.6944444444444444
;0.6924242424242424
;0.6935897435897436
;0.6928571428571428
;0.6933473389355742
;0.6930033416875522
;0.6932539682539683
;0.6930657506744464
;done
  • tableauを使う
(stream-ref-print (accelerated-sequence euler-transform ln2-stream)
                  10)
;gosh> 1.0
;0.7
;0.6932773109243697
;0.6931488693329254
;0.6931471960735491
;0.6931471806635636
;0.6931471805604039
;0.6931471805599445
;0.6931471805599427
;0.6931471805599454
;done