Stabilise benchmarks wrt. GC
[nofib.git] / imaginary / bernouilli / Main.hs
1 -- There was a lot of discussion about various ways of computing
2 -- Bernouilli numbers (whatever they are) on haskell-cafe in March 2003
3 -- Here's one of the programs.
4
5 -- It's not a very good test, I suspect, because it manipulates big integers,
6 -- and so probably spends most of its time in GMP.
7
8 import Data.Ratio
9 import System.Environment
10 import Control.Monad
11 import NofibUtils
12
13 -- powers = [[r^n | r<-[2..]] | n<-1..]
14 -- type signature required for compilers lacking the monomorphism restriction
15 powers :: [[Integer]]
16 powers = [2..] : map (zipWith (*) (head powers)) powers
17
18 -- powers = [[(-1)^r * r^n | r<-[2..]] | n<-1..]
19 -- type signature required for compilers lacking the monomorphism restriction
20 neg_powers :: [[Integer]]
21 neg_powers =
22 map (zipWith (\n x -> if n then x else -x) (iterate not True)) powers
23
24 pascal:: [[Integer]]
25 pascal = [1,2,1] : map (\line -> zipWith (+) (line++[0]) (0:line)) pascal
26
27 bernoulli 0 = 1
28 bernoulli 1 = -(1%2)
29 bernoulli n | odd n = 0
30 bernoulli n =
31 (-1)%2
32 + sum [ fromIntegral ((sum $ zipWith (*) powers (tail $ tail combs)) -
33 fromIntegral k) %
34 fromIntegral (k+1)
35 | (k,combs)<- zip [2..n] pascal]
36 where powers = (neg_powers!!(n-1))
37
38 main = replicateM_ 500 $ do
39 [arg] <- getArgs
40 let n = (read arg)::Int
41 print (hash (show (bernoulli n)))