Tuesday, January 22, 2008

Simple comparison of iteration with Python and use of Map in Haskell

Here is a simple code snippet that shows the variation between how to approach problems in python and how to approach problems in haskell. More often than not, the same problem or task that you want to accomplish is the same but the methods used are going to be different. There is no question that python is an imperative language. You will tackle a problem by figuring how how to perform step 1 and then step 2, possibly N number of times. Haskell is a purely functional programming language but some like Simon Peyton Jones call Haskell "the best imperative language".

`Perform the invchi2 calculation in pythonexample_data = [    (4.3, 6),    (2.2, 60),    (60, 2.2),    (0.3, 4),    (32.123, 20),    (12.4, 5),    (0.04, 3),    (0, 0),    (1, 1)]def invchi(chi, df):    m = chi / 2.0    sum = term = math.exp(-m)    for i in range(1, df//2):        term *= m / i        sum += term    return min(sum, 1.0)if __name__  == '__main__':    print "Running InvChi Test"    for chi, df in example_data:        print "[ chi=%s df=%s ] res=%s" % (chi, df, invchi(chi, df))    print "Done"`

`exampleData :: [(Double, Double)]exampleData = [    (4.3, 6),    (2.2, 60),    (60, 2.2),    (0.3, 4),    (32.123, 20),    (12.4, 5),    (0.04, 3),    (0, 0),    (1, 1)]-- Inverted Chi2 formulainvChi :: Double -> Double -> DoubleinvChi chi df = minimum([snd newsum, 1.0])    where m = chi / 2.0          initsum = exp (-m)          trm = exp (-m)          maxrg = fromIntegral (floor (df / 2.0)) :: Double          -- Return a tuple with current sum and term, given these inputs          newsum = foldl (\(trm,sm) elm -> ((trm*(m/elm)), sm+trm))                    (trm,initsum) [1..maxrg]runBayesTest = do  putStrLn "Bayes Test: Inv Chi"  mapM_ (\x -> putStrLn \$ (show x) ++ " res=" ++ (show (invChi (fst x) (snd x)))) exampleData  putStrLn "Done Bayes"`