hmatrix-0.5.1.1: examples/benchmarks.hs
{-# LANGUAGE BangPatterns #-}
-- $ ghc --make -O2 benchmarks.hs
import Numeric.LinearAlgebra
import System.Time
import System.CPUTime
import Text.Printf
import Data.List(foldl1')
time act = do
t0 <- getCPUTime
act
t1 <- getCPUTime
printf "%.3f s CPU\n" $ (fromIntegral (t1 - t0) / (10^12 :: Double)) :: IO ()
--------------------------------------------------------------------------------
main = sequence_ [bench1,
bench2,
bench4,
bench5 1000000 3, bench5 100000 50,
bench6 100 (100000::Double), bench6 100000 (100::Double), bench6 10000 (1000::Double)]
w :: Vector Double
w = constant 1 5000000
w2 = 1 * w
v = flatten $ ident 500 :: Vector Double
bench1 = do
time $ print$ vectorMax (w+w2) -- evaluate it
putStrLn "Sum of a vector with 5M doubles:"
print$ vectorMax (w+w2) -- evaluate it
time $ printf " BLAS: %.2f: " $ sumVB w
time $ printf "BLAS only dot: %.2f: " $ w <.> w2
time $ printf " Haskell: %.2f: " $ sumVH w
time $ printf " innerH: %.2f: " $ innerH w w2
time $ printf "foldVector: %.2f: " $ sumVector w
let getPos k s = if k `mod` 500 < 200 && w@>k > 0 then k:s else s
putStrLn "foldLoop for element selection:"
time $ print $ (`divMod` 500) $ maximum $ foldLoop getPos [] (dim w)
putStrLn "constant 5M:"
time $ print $ constant (1::Double) 5000001 @> 7
time $ print $ constant i 5000001 @> 7
time $ print $ conj (constant i 5000001) @> 7
putStrLn "zips C vs H:"
time $ print $ (w / w2) @> 7
time $ print $ (zipVector (/) w w2) @> 7
putStrLn "folds C/BLAS vs H:"
let t = constant (1::Double) 5000002
print $ t @> 7
time $ print $ foldVector max (t@>0) t
time $ print $ vectorMax t
time $ print $ sqrt $ foldVector (\v s -> v*v+s) 0 t
time $ print $ pnorm PNorm2 t
putStrLn "scale C/BLAS vs H:"
time $ print $ mapVector (*2) t @> 7
time $ print $ (2 * t) @> 7
sumVB v = constant 1 (dim v) <.> v
sumVH v = go (d - 1) 0
where
d = dim v
go :: Int -> Double -> Double
go 0 s = s + (v @> 0)
go !j !s = go (j - 1) (s + (v @> j))
innerH u v = go (d - 1) 0
where
d = min (dim u) (dim v)
go :: Int -> Double -> Double
go 0 s = s + (u @> 0) * (v @> 0)
go !j !s = go (j - 1) (s + (u @> j) * (v @> j))
-- sumVector = foldVectorG (\k v s -> v k + s) 0.0
sumVector = foldVector (+) 0.0
--------------------------------------------------------------------------------
bench2 = do
putStrLn "-------------------------------------------------------"
putStrLn "Multiplication of 1M different 3x3 matrices:"
-- putStrLn "from [[]]"
-- time $ print $ manymult (10^6) rot'
-- putStrLn "from (3><3) []"
time $ print $ manymult (10^6) rot
print $ cos (10^6/2)
rot' :: Double -> Matrix Double
rot' a = matrix [[ c,0,s],
[ 0,1,0],
[-s,0,c]]
where c = cos a
s = sin a
matrix = fromLists
rot :: Double -> Matrix Double
rot a = (3><3) [ c,0,s
, 0,1,0
,-s,0,c ]
where c = cos a
s = sin a
manymult n r = foldl1' (<>) (map r angles)
where angles = toList $ linspace n (0,1)
-- angles = map (k*) [0..n']
-- n' = fromIntegral n - 1
-- k = recip n'
--------------------------------------------------------------------------------
bench4 = do
putStrLn "-------------------------------------------------------"
putStrLn "1000x1000 inverse"
let a = ident 1000 :: Matrix Double
let b = 2*a
print $ vectorMax $ flatten (a+b) -- evaluate it
time $ print $ vectorMax $ flatten $ linearSolve a b
--------------------------------------------------------------------------------
op1 a b = a <> trans b
op2 a b = a + trans b
timep = time . print . vectorMax . flatten
bench5 n d = do
putStrLn "-------------------------------------------------------"
putStrLn "transpose in add"
let ms = replicate n ((ident d :: Matrix Double))
timep $ foldl1' (+) ms
timep $ foldl1' op2 ms
putStrLn "-------------------------------------------------------"
putStrLn "transpose in multiply"
timep $ foldl1' (<>) ms
timep $ foldl1' op1 ms
--------------------------------------------------------------------------------
bench6 sz n = do
putStrLn "-------------------------------------------------------"
putStrLn "many constants"
time $ print $ sum $ map ((@>0). flip constant sz) [1..n]