hiroshi-manabe様の日本語訳を使わせてもらいます。
練習問題等はGaucheで実行。
練習問題1.37
無限連分数というものがある。
f=\cfrac{N_1}{D_1+\cfrac{N_2}{D_2+\cfrac{N_3}{D_3+\cdots}}}
$k$で展開を打ち切るとすると。
f=\cfrac{N_1}{D_1+\cfrac{N_2}{\ddots+\cfrac{N_k}{D_k}}}
これを手続きにしよう。
nとdは、添字を引数で受け取ると対応する項の値を返す手続きだとする。
まずは再帰プロセス版。
_.scm
(define (cont-frac n d k)
(define (iter i)
(if (> i k)
0
(/ (n i) (+ (d i) (iter (+ i 1))))))
(iter 1))
反復プロセス版。数える順を逆にする必要がある。
_.scm
(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))
以下の手続きで $1/\varphi=0.6180339...$ の近似値を求めることができる。
_.scm
(cont-frac (lambda (i) 1.0) (lambda (i) 1.0) k)
kをどれだけ大きすれば、小数点以下4桁の制度が得られるか?
_.scm
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 5)
0.625
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 6)
0.6153846153846154
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 7)
0.6190476190476191
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 8)
0.6176470588235294
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 9)
0.6181818181818182
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 10)
0.6179775280898876
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 11)
0.6180555555555556
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 12)
0.6180257510729613
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 13)
0.6180371352785146
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 14)
0.6180327868852459
gosh> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 15)
0.6180344478216819
11以上。
練習問題1.38
連分数展開によって、$e-2=0.71828...$の近似値を求められる。
$N_i$を全て1。$D_i$を$1,2,1,1,4,1,1,6,1,1...$とすればいいらしい。
_.scm
(define (napier k)
(+ 2
(cont-frac
(lambda (i) 1.0)
(lambda (i)
(if (= (remainder i 3) 2)
(/ (* (+ i 1) 2) 3)
1))
k)))
実行結果。
_.scm
gosh> (napier 5)
2.71875
gosh> (napier 6)
2.717948717948718
gosh> (napier 7)
2.7183098591549295
gosh> (napier 8)
2.718279569892473
gosh> (napier 9)
2.718283582089552
gosh> (napier 10)
2.7182817182817183
練習問題1.39
以下の式で、正接(タンジェント)を計算できる。
\tan{x}=\cfrac{x}{1-\cfrac{x^2}{3-\cfrac{x^2}{5-\cdots}}}
再帰プロセス版。
_.scm
(define (tan-cf x k)
(define (iter i)
(if (> i k)
0
(/ (if (= i 1) x (* x x))
(- (* i 2) 1 (iter (+ i 1))))))
(iter 1))
反復プロセス版。
_.scm
(define (tan-cf x k)
(define (iter i result)
(if (= i 0)
result
(iter (- i 1)
(/ (if (= i 1) x (* x x))
(- (* i 2) 1 result)))))
(iter k 0))
組み込みの tan 手続きと比較しながら実行してみよう。
_.scm
gosh> (tan-cf 0.1 10)
0.10033467208545055
gosh> (tan 0.1)
0.10033467208545055
gosh> (tan-cf 0.2 10)
0.2027100355086725
gosh> (tan 0.2)
0.20271003550867248
gosh> (tan-cf 0.3 10)
0.3093362496096232
gosh> (tan 0.3)
0.3093362496096232
gosh> (tan-cf 0.4 10)
0.4227932187381618
gosh> (tan 0.4)
0.4227932187381618
gosh> (tan-cf 0.5 10)
0.5463024898437905
gosh> (tan 0.5)
0.5463024898437905
gosh> (tan-cf 0.6 10)
0.6841368083416923
gosh> (tan 0.6)
0.6841368083416923
gosh> (tan-cf 0.7 10)
0.8422883804630793
gosh> (tan 0.7)
0.8422883804630793
gosh> (tan-cf 0.8 10)
1.0296385570503641
gosh> (tan 0.8)
1.029638557050364
gosh> (tan-cf 0.9 10)
1.2601582175503392
gosh> (tan 0.9)
1.260158217550339
gosh> (tan-cf 1.0 10)
1.557407724654902
gosh> (tan 1.0)
1.557407724654902