「やさしくわかる数学のはなし77」という本に「ウォリス積」、「マダヴァの公式」による円周率の計算式が載っていましたのでやってみました。
- ウォリス積
import Ratio -- ウォリス積 -- 2・2・4・4・6・6・8・8... -- 2 pi = ----------------------- -- 1・3・3・5・5・7・7・9... -- 無限数列を作る -- x : 初期値 -- c : True と False の二進カウンタ numSeque :: Integer -> Bool -> [Integer] numSeque x c = x: case c of False -> numSeque x True True -> numSeque (x+2) False -- [2,2,4,4,6,6,8,8,10,10,12,12,14,14...] nume :: [Integer] nume = numSeque 2 False -- [1,3,3,5,5,7,7,9,9,11,11,13,13,15...] denomi :: [Integer] denomi = tail $ numSeque 1 False -- n は数列の長さを指定します。 p :: Int -> Double p n = fromRational $ ((product (take n nume)) % (product (take n denomi))) * 2 {- *Main> mapM_ putStrLn $ map (show.p) $ take 10 [100,200..] -- => 3.1260789002154112 3.1337874906281624 3.1363784027059802 3.137677900950936 3.1384588976716157 3.138980103882128 3.139352659682266 3.1396322219293964 3.139849745446556 3.1400238186005973 -}
- マダヴァの公式
import Ratio -- マダヴァの公式 -- pi / 4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 ... p2 :: Integer -> Int -> Rational -> Double p2 n count acc | count == 0 = fromRational $ acc * 4 | countIsEven = p2 (n + 2) (count-1) $ acc + 1 % n | otherwise = p2 (n + 2) (count-1) $ acc - 1 % n where countIsEven = count `mod` 2 == 0 pai :: Int -> Double pai n = p2 1 n 0 {- *Main> mapM_ putStrLn $ map (show.pai) $ take 10 [100,200..] 3.131592903558553 3.1365926848388166 3.1382593295155905 3.1390926574960125 3.1395926555897833 3.13992598808053 3.1401640828900828 3.1403426540780734 3.1404815428216173 3.140592653839793 -}
import Ratio -- ゼータ関数 -- pi**2 / 6 = 1/1**2 + 1/2**2 + 1/3**2 + 1/4**2 + 1/5**2 .... p2 :: Integer -> Int -> Rational -> Double p2 n 0 acc = sqrt $ fromRational $ acc * 6 p2 n count acc = p2 (n + 1) (count-1) $ acc + 1 % (n * n) pai :: Int -> Double pai n = p2 1 n 0 {- ghci> mapM_ putStrLn $ map (show.pai) $ take 10 [100,200..] 3.132076531809106 3.136826306330968 3.1384132451584095 3.1392074056144135 3.139684123138722 3.140002027036458 3.1402291464241046 3.140399510673162 3.1405320308436044 3.1406380562059932 -}
import Ratio -- ゼータ関数 -- pi**4 / 90 = 1/1**4 + 1/2**4 + 1/3**4 + 1/4**4 + 1/5**4 p2 :: Integer -> Int -> Rational -> Double p2 n 0 acc = sqrt $ sqrt $ fromRational $ acc * 90 p2 n count acc = p2 (n + 1) (count-1) $ acc + 1 % (n * n * n *n) pai :: Int -> Double pai n = p2 1 n 0 {- ghci> mapM_ putStrLn $ map (show.pai) $ take 10 [100,200..] 3.1415924153073678 3.141592623579992 3.141592644675728 3.141592649824466 3.1415926516604986 3.141592652472745 3.1415926528860942 3.1415926531182436 3.14159265325854 3.1415926533482694 -}