Scheme
SICP

オンラインSICP読書女子会 #10(1.3.3 無限連分数) まとめ

More than 1 year has passed since last update.

オンラインSICP読書女子会 #10 (1.3.3~1.3.4) - connpassのまとめです!

1.37

N_i, D_i がすべて1の無限連分数は1/φ (φは黄金比)

;; 再帰プロセス
(define (cont-frac n d k)
  (define (iter i)
    (if (= i k)
    (/ (n i) (d i))
    #?= (/ (n i) (+ (d i) (iter (+ i 1))))))
  (iter 1))

(cont-frac (lambda (i) 1.0)
       (lambda (i) 1.0)
       20)

;; #?-    0.5
;; #?-    0.6666666666666666
;; #?-    0.6000000000000001
;; #?-    0.625
;; #?-    0.6153846153846154
;; #?-    0.6190476190476191
;; #?-    0.6176470588235294
;; #?-    0.6181818181818182
;; #?-    0.6179775280898876
;; #?-    0.6180555555555556
;; #?-    0.6180257510729613
;; #?-    0.6180371352785146
;; #?-    0.6180327868852459
;; #?-    0.6180344478216819
;; #?-    0.6180338134001252
;; #?-    0.6180340557275542
;; #?-    0.6180339631667064
;; #?-    0.6180339985218034
;; #?-    0.6180339850173578

;; 反復プロセス(末尾再帰)
(define (cont-frac n d k)
  (define (iter i result)
    (print i "->" result)
    (if (= i 0)
    result
    (iter (- i 1)
          (/ (n i)
         (+ (d i) result)))))
  (iter k 0))

(cont-frac (lambda (i) 1.0)
       (lambda (i) 1.0)
       20)


;; 20->0
;; 19->1.0
;; 18->0.5
;; 17->0.6666666666666666
;; 16->0.6000000000000001
;; 15->0.625
;; 14->0.6153846153846154
;; 13->0.6190476190476191
;; 12->0.6176470588235294
;; 11->0.6181818181818182
;; 10->0.6179775280898876
;; 9->0.6180555555555556
;; 8->0.6180257510729613
;; 7->0.6180371352785146
;; 6->0.6180327868852459
;; 5->0.6180344478216819
;; 4->0.6180338134001252
;; 3->0.6180340557275542
;; 2->0.6180339631667064
;; 1->0.6180339985218034
;; 0->0.6180339850173578
;; 0.6180339850173578

k = 11 くらいから4桁の精度になった

1.38 自然対数の無限連分数

(define (cont-frac n d k)
  (define (iter i)
    (if (= i k)
    (/ (n i) (d i))
    (/ (n i) (+ (d i) (iter (+ i 1))))))
  (iter 1))

(define (n-cont-frac n)
  (define (n-iter j)
    (if (> j n)
    "end"
    (let ((ans
           (cont-frac (lambda (i) 1.0)
              (lambda (i)
                (let ((div (quotient i 3))
                  (mod (modulo i 3)))
                  (if (= mod 2)
                  (- i div)
                  1.0)))
              j)))
      (print j "=>" (+ 2 ans))
      (n-iter (+ j 1)))
    ))
  (n-iter 1))

(n-cont-frac 10)
;; 1=>3.0
;; 2=>2.6666666666666665
;; 3=>2.75
;; 4=>2.7142857142857144
;; 5=>2.71875
;; 6=>2.717948717948718
;; 7=>2.7183098591549295
;; 8=>2.718279569892473
;; 9=>2.718283582089552
;; 10=>2.7182817182817183
;; "end"


;;反復プロセス
(define (cont-frac n d k)
  (define (iter i result)
    (if (= i 0)
    result
    (iter (- i 1)
          (/ (n i)
         (+ (d i) result)))))
    (iter k 0))
(n-cont-frac 10)

;; 1=>3.0
;; 2=>2.6666666666666665
;; 3=>2.75
;; 4=>2.7142857142857144
;; 5=>2.71875
;; 6=>2.717948717948718
;; 7=>2.7183098591549295
;; 8=>2.718279569892473
;; 9=>2.718283582089552
;; 10=>2.7182817182817183```

反復プロセスも再帰プロセスもちゃんとうごいてるっぽい!

1.39 tan_x の∞連分数

(define (cont-frac n d k)
  (define (iter i)
    (if (= i k)
    (/ (n i) (d i))
    (/ (n i) (+ (d i) (iter (+ i 1))))))
  (iter 1))

(define (tan x)
  (cont-frac (lambda (i)
           (if (= i 0) x
           (* -1 (* x x))))
         (lambda (i) (- (* 2 i) 1))
         n))

(define pi 3.141592)
(tan (/ pi 4)) ;; 0.9999996732051569