Newton法で平方根をもとめる
cf. http://hpcgi2.nifty.com/1to100pen/wiki/wiki.cgi?p=����Haskell 2006-05-21
最近流行りの SICP の 1.1.7 Newton法からお題を拝借。
おわっと,流行だったのか。もしかして乗り遅れた?
上の [1…100]>>=pen さんのもそうだし,hasko さんとこ(id:hasko:20060520:1148133213)のコメントにもあるように,先に予測値のリストを作ってしまうことにしよう。
guess x = iterate (\g -> (g + x/g) / 2.0) 1.0
goodEnough eps old new = abs (1.0 - old/new) < eps
find2 f i (x:xs) | f i x = x
| otherwise = find2 f x xs
squareRoot x = find2 (goodEnough 0.0001) x (guess x)
guess で予測値のリストを作って,goodEnough で判定。判定は新旧予測値の比を利用し,引数で指定できるようにした。 で,あとは適当な値をリストから探すだけなんだけど,ちょうどいい関数が見あたらなかったので find2 を定義してみた。 結果。
*Main> squareRoot 4
2.000000000000002
*Main> squareRoot 1.0e-6
1.0000000000000117e-3
*Main> squareRoot 1.0e29
3.162277660171076e14
*Main> (squareRoot 1.0e-6) ^ 2
1.0000000000000235e-6
*Main> (squareRoot 1.0e29) ^ 2
1.0000000000017057e29
ふむ,よさげ。
