«前の日記(2008年11月21日) 最新 次の日記(2008年11月23日)» 編集

ema log


2008年11月22日 [長年日記]

_ [Gauche][Event] 「プログラミングGauche」読書会#5 お疲れ様でした

主催が、寝坊してすみませんでした。

今回は、第13章〜第16章を読むことができました。次回は第17章、第18章の重そうな章に突入します。次回、次々回がコアな回で楽しめるのではないかと思います。

次回は12/13に予定しております。 次回は、最初に暖房をお願いするようにしたいと思います。

寮にルータとタップを忘れてしまったため、実家の無線LANルータをぱくってきたのでネットワークの設定に時間もかかってしまいました。

Kaprs」ともどもよろしくお願いいたします。

なお、12/7 には Kansai.AR#1も開催されます!参加者はそろそろ上限に達しそうとのことですが、発表者は絶賛募集中と言うことです。

_ [SICP][Event] SICP勉強会#5 ログ

1.36

途中経過を出力する fixed-point
(define tolerance 0.000001)
(define (average x y) (/ (+ x y) 2))
(define (close-enough? x y) (< (abs (- x y)) 0.0001))

(define (fixed-point f first-guess)
  (define (close-enough? v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (define (try guess)
    (let ((next (f guess)))
      (display guess)
      (newline)
      (if (close-enough? guess next)
	  next
	  (try next))))
  (try first-guess))
黄金比
> (fixed-point (lambda (y) (average y (+ 1 (/ 1 y)))) 1.0)
1.0
1.5
1.5833333333333333
1.6074561403508771
1.6147785476652068
1.61702925556443
1.617723628348796
1.6179380934832117
1.6180043565683029
1.6180248320058461
1.6180311591702674
1.618033114362648
1.618033718549466
x^x == 1000 の平均を使う版
> (fixed-point (lambda (y) (average y (/ (log 1000) (log y)))) 0.5)
 1> 0.5
 2> -4.7328921423310435
 3> -1.9294367464856617-0.8831605544952358i
 4> -0.6367404417038983+0.7408451809785208i
 5> -0.33390127567646233-1.1437670056900082i
 6> 0.007399706701754605+1.2737412375384936i
 7> 0.3369697820779475-1.5185687703971407i
 8> 0.9223014102315796+1.548287537124875i
 9> 1.8986842272540216-1.7484010483951409i
10> 3.203369020863236+0.8949152458920809i
11> 4.335196566268348-0.17218050758326126i
(snip)
19> 4.555535557172372-8.920402326580877e-8i
x^x == 1000 の平均を使わない版,
> (fixed-point (lambda (y) (/ (log 1000) (log y))) 0.5))
 1> 0.5
 2> -9.965784284662087
 3> 1.0479216829770386-1.4318909598643041i
 4> 3.2721632144996313+5.358070758799561i
 5> 2.87075534145715-1.5979029081330443i
 6> 4.911698079655922+2.097221141263437i
 7> 3.897044834247144-0.9386983476898267i
 8> 4.555511086354771-5.173344975628601e-5i
(snip)
43> 4.555535538588542-3.5011025728274154e-7i

1.37

再帰版のつもり

これでいいのかなぁ?

(define (cont-frac n d k)
  (define (cont-frac-helper n d k j)
    (if (= k 0)
      (/ (n j) (d j))
      (/ (n j) (+ (d j) (cont-frac-helper n d (- k 1) (+ j 1))))))
  (cont-frac-helper n d k 0))
反復版のつもり
(define (cont-frac n d k)
  (define (cont-frac-iter n d k acc)
    (if (= k 0)
      acc
      (cont-frac-iter n d (- k 1) (/ (n k) (+ (d k) acc)))))
  (cont-frac-iter n d k 1))
実行結果
> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 100)
0.6180339887498948

といった感じ

> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 8)
0.6181818181818182
> (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 9)
0.6179775280898876

となるので,小数点以下4桁の精度にはk=9かな?(小数点以下5桁で四捨五入すると 0.6180)

1.38

1 2 1 1 4 1 1 6 1 1 8 1 ... を生成する式として

(lambda (i) (if (= (modulo i 3) 2)
                (* 2 (+ 1 (quotient i 3)))
                1))

を用いた

> (+ 2.0 (cont-frac (lambda (i) 1.0)
                    (lambda (i) (if (= (modulo i 3) 2)
                                (* 2 (+ 1 (quotient i 3)))
                                1))
                    20))
2.7182818284590455

ちなみに,有理数を使うと

> (exact->inexact (+ 2 (cont-frac (lambda (i) 1)
                                  (lambda (i) (if (= (modulo i 3) 2)
                                              (* 2 (+ 1 (quotient i 3)))
                                              1))
                                  20)))
2.718281828459045

いずれも,Wikipedia に示されている値と,小数点以下15桁まで一致する.

1.39

最初の一項目を特別扱いして,残りを連分数で表した.

(define (tan-cf x k) (/ x (+ 1 (cont-frac (lambda (i) (* (- x) x))
                                          (lambda (i) (+ (* 2 i) 1))
                                          (- k 1)))))

検算は以下のように行った

(define (check-tan x)
      (display (tan x))
      (newline)
      (display (tan-cf x 10)))
> (check-tan 0)
0.0
0#<undef>
> (check-tan 3.14)
-0.001592654936407223
-0.001592660421047437#<undef>
> (check-tan (/ 3.14 6))
0.5769964003928729
0.576996400392872
本日のツッコミ(全2件) [ツッコミを入れる]
_ murase_syuka (2008年11月24日 01:07)

1.37で、kの次数の順序が逆。再帰(降順)、反復(昇順)。<br>1.38を「1.37の再帰」で計算すると、「1.37の反復」の場合と食い違い。

_ ema (2008年11月24日 12:48)

検証ありがとうございます。<br>推測ですが、再帰版のつもりとしていた方が妖しいのだと思われます。