SICP問題1.36
修正した fixed-point
(define (fixed-point f first-guess) (define (close-enough? v1 v2) (< (abs (- v1 v2)) tolerance)) (define (try guess) (let ((next (f guess))) (display next) (newline) (if (close-enough? guess next) next (try next)))) (try first-guess))
x |-> log(1000)/log(x) の不動点を探索することで (x^2) = 1000 を求める。
まず平均緩和を使用使用しない場合
(fixed-point (lambda (x) (/ (log 1000) (log x))) 10) ; 2.9999999999999996 ; 1 ; 6.2877098228681545 ; 2 ; 3.7570797902002955 ; 3 ; 5.218748919675316 ; 4 ; 4.1807977460633134 ; 5 ; 4.828902657081293 ; 6 ; 4.386936895811029 ; 7 ; 4.671722808746095 ; 8 ; 4.481109436117821 ; 9 ; 4.605567315585735 ; 10 ; 4.522955348093164 ; 11 ; 4.577201597629606 ; 12 ; 4.541325786357399 ; 13 ; 4.564940905198754 ; 14 ; 4.549347961475409 ; 15 ; 4.5596228442307565 ; 16 ; 4.552843114094703 ; 17 ; 4.55731263660315 ; 18 ; 4.554364381825887 ; 19 ; 4.556308401465587 ; 20 ; 4.555026226620339 ; 21 ; 4.55587174038325 ; 22 ; 4.555314115211184 ; 23 ; 4.555681847896976 ; 24 ; 4.555439330395129 ; 25 ; 4.555599264136406 ; 26 ; 4.555493789937456 ; 27 ; 4.555563347820309 ; 28 ; 4.555517475527901 ; 29 ; 4.555547727376273 ; 30 ; 4.555527776815261 ; 31 ; 4.555540933824255 ; 32 ; 4.555532257016376 ; 33 ; 4.555532257016376 ; 34
答えは正しいか?
(expt 4.555532257016376 4.555532257016376) ; 999.991323238027
ということで、OKそう。
次に平均緩和を使用使用する場合
平均緩和は y = x/y を y = 1/2(y + y/x)に単純に変換するヤツ y の次の予測値は y/x でなく 1/2(y + y/x)となるということ。
(両辺に y を足して 2 で割っている。)この場合だと元の式が
x = log(1000)/log(x)
なので、以下のようになる。
x = 1/2(x + log(1000)/log(x))
(fixed-point (lambda (x) (average x (/ (log 1000) (log x)))) 10) ; 6.5 ; 1 ; 5.095215099176933 ; 2 ; 4.668760681281611 ; 3 ; 4.57585730576714 ; 4 ; 4.559030116711325 ; 5 ; 4.55613168520593 ; 6 ; 4.555637206157649 ; 7 ; 4.55555298754564 ; 8 ; 4.555538647701617 ; 9 ; 4.555536206185039 ; 10 ; 4.555536206185039 ; 11
ステップ数は 34 => 11 ステップ数になった