module Numeric.LinearAlgebra.Tests(
qCheck,
utest,
runTests,
runBenchmarks
, binaryTests
) where
import Numeric.LinearAlgebra hiding (unitary)
import Numeric.LinearAlgebra.Devel
import Numeric.LinearAlgebra.Static(L)
import Numeric.LinearAlgebra.Tests.Instances
import Numeric.LinearAlgebra.Tests.Properties
import Test.HUnit hiding ((~:),test,Testable,State)
import System.Info
import Data.List(foldl1')
import Prelude hiding ((^))
import qualified Prelude
import System.CPUTime
import System.Exit
import Text.Printf
import Numeric.LinearAlgebra.Devel(unsafeFromForeignPtr,unsafeToForeignPtr)
import Control.Arrow((***))
import Debug.Trace
import Control.Monad(when)
import Control.Applicative
import Control.Monad(ap)
import Control.DeepSeq ( NFData(..) )
import Test.QuickCheck(Arbitrary,arbitrary,coarbitrary,choose,vector
,sized,classify,Testable,Property
,quickCheckWithResult,maxSize,stdArgs,shrink)
import qualified Test.QuickCheck as T
import Test.QuickCheck.Test(isSuccess)
qCheck n x = do
r <- quickCheckWithResult stdArgs {maxSize = n} x
when (not $ isSuccess r) (exitFailure)
a ^ b = a Prelude.^ (b :: Int)
utest str b = TestCase $ assertBool str b
feye n = flipud (ident n) :: Matrix Double
detTest1 = det m == 26
&& det mc == 38 :+ (3)
&& det (feye 2) == 1
where
m = (3><3)
[ 1, 2, 3
, 4, 5, 7
, 2, 8, 4 :: Double
]
mc = (3><3)
[ 1, 2, 3
, 4, 5, 7
, 2, 8, iC
]
detTest2 = inv1 |~| inv2 && [det1] ~~ [det2]
where
m = complex (feye 6)
inv1 = inv m
det1 = det m
(inv2,(lda,sa)) = invlndet m
det2 = sa * exp lda
nd1 = (3><3) [ 1/2, 1/4, 1/4
, 0/1, 1/2, 1/4
, 1/2, 1/4, 1/2 :: Double]
nd2 = (2><2) [1, 0, 1, 1:: Complex Double]
expmTest1 = expm nd1 :~14~: (3><3)
[ 1.762110887278176
, 0.478085470590435
, 0.478085470590435
, 0.104719410945666
, 1.709751181805343
, 0.425725765117601
, 0.851451530235203
, 0.530445176063267
, 1.814470592751009 ]
expmTest2 = expm nd2 :~15~: (2><2)
[ 2.718281828459045
, 0.000000000000000
, 2.718281828459045
, 2.718281828459045 ]
mbCholTest = utest "mbCholTest" (ok1 && ok2) where
m1 = (2><2) [2,5,5,8 :: Double]
m2 = (2><2) [3,5,5,9 :: Complex Double]
ok1 = mbChol (trustSym m1) == Nothing
ok2 = mbChol (trustSym m2) == Just (chol $ trustSym m2)
randomTestGaussian = (unSym c) :~3~: unSym (snd (meanCov dat))
where
a = (3><3) [1,2,3,
2,4,0,
2,2,1]
m = 3 |> [1,2,3]
c = mTm a
dat = gaussianSample 7 (10^6) m c
randomTestUniform = c :~2~: unSym (snd (meanCov dat))
where
c = diag $ 3 |> map ((/12).(^2)) [1,2,3]
dat = uniformSample 7 (10^6) [(0,1),(1,3),(3,6)]
rot :: Double -> Matrix Double
rot a = (3><3) [ c,0,s
, 0,1,0
,s,0,c ]
where c = cos a
s = sin a
rotTest = fun (10^5) :~11~: rot 5E4
where fun n = foldl1' (<>) (map rot angles)
where angles = toList $ linspace n (0,1)
offsetTest = y == y' where
x = fromList [0..3 :: Double]
y = subVector 1 3 x
(f,o,n) = unsafeToForeignPtr y
y' = unsafeFromForeignPtr f o n
normsVTest = TestList [
utest "normv2CD" $ norm2PropC v
#ifndef NONORMVTEST
, utest "normv2D" $ norm2PropR x
#endif
, utest "normv1CD" $ norm_1 v == 8
, utest "normv1D" $ norm_1 x == 6
, utest "normvInfCD" $ norm_Inf v == 5
, utest "normvInfD" $ norm_Inf x == 3
] where v = fromList [1,2,3:+4] :: Vector (Complex Double)
x = fromList [1,2,3] :: Vector Double
#ifndef NONORMVTEST
norm2PropR a = norm_2 a =~= sqrt (udot a a)
#endif
norm2PropC a = norm_2 a =~= realPart (sqrt (a `dot` a))
a =~= b = fromList [a] |~| fromList [b]
normsMTest = TestList [
utest "norm2mCD" $ norm_2 v =~= 8.86164970498005
, utest "norm2mD" $ norm_2 x =~= 5.96667765076216
, utest "norm1mCD" $ norm_1 v == 9
, utest "norm1mD" $ norm_1 x == 7
, utest "normmInfCD" $ norm_Inf v == 12
, utest "normmInfD" $ norm_Inf x == 8
, utest "normmFroCD" $ norm_Frob v =~= 8.88819441731559
, utest "normmFroD" $ norm_Frob x =~= 6.24499799839840
] where v = (2><2) [1,2*iC,3:+4,7] :: Matrix (Complex Double)
x = (2><2) [1,2,3,5] :: Matrix Double
a =~= b = fromList [a] :~10~: fromList [b]
sumprodTest = TestList [
utest "sumCD" $ sumElements z == 6
, utest "sumCF" $ sumElements (single z) == 6
, utest "sumD" $ sumElements v == 6
, utest "sumF" $ sumElements (single v) == 6
, utest "prodCD" $ prodProp z
, utest "prodCF" $ prodProp (single z)
, utest "prodD" $ prodProp v
, utest "prodF" $ prodProp (single v)
] where v = fromList [1,2,3] :: Vector Double
z = fromList [1,2iC,3+iC]
prodProp x = prodElements x == product (toList x)
chainTest = utest "chain" $ foldl1' (<>) ms |~| optimiseMult ms where
ms = [ diag (fromList [1,2,3 :: Double])
, konst 3 (3,5)
, (5><10) [1 .. ]
, konst 5 (10,2)
]
conjuTest m = cmap conjugate (flatten (conj (tr m))) == flatten (tr m)
newtype State s a = State { runState :: s -> (a,s) }
instance Functor (State s)
where
fmap f x = pure f <*> x
instance Applicative (State s)
where
pure = return
(<*>) = ap
instance Monad (State s) where
return a = State $ \s -> (a,s)
m >>= f = State $ \s -> let (a,s') = runState m s
in runState (f a) s'
state_get :: State s s
state_get = State $ \s -> (s,s)
state_put :: s -> State s ()
state_put s = State $ \_ -> ((),s)
evalState :: State s a -> s -> a
evalState m s = let (a,s') = runState m s
in seq s' a
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance Monad m => Functor (MaybeT m)
where
fmap f x = pure f <*> x
instance Monad m => Applicative (MaybeT m)
where
pure = return
(<*>) = ap
instance Monad m => Monad (MaybeT m) where
return a = MaybeT $ return $ Just a
m >>= f = MaybeT $ do
res <- runMaybeT m
case res of
Nothing -> return Nothing
Just r -> runMaybeT (f r)
fail _ = MaybeT $ return Nothing
lift_maybe m = MaybeT $ do
res <- m
return $ Just res
successive_ t v = maybe False (\_ -> True) $ evalState (runMaybeT (mapVectorM_ stp (subVector 1 (size v 1) v))) (v ! 0)
where stp e = do
ep <- lift_maybe $ state_get
if t e ep
then lift_maybe $ state_put e
else (fail "successive_ test failed")
successive f v = evalState (mapVectorM stp (subVector 1 (size v 1) v)) (v ! 0)
where stp e = do
ep <- state_get
state_put e
return $ f ep e
succTest = utest "successive" $
successive_ (>) (fromList [1 :: Double,2,3,4]) == True
&& successive_ (>) (fromList [1 :: Double,3,2,4]) == False
&& successive (+) (fromList [1..10 :: Double]) == 9 |> [3,5,7,9,11,13,15,17,19]
findAssocTest = utest "findAssoc" ok
where
ok = m1 == m2
m1 = assoc (6,6) 7 $ zip (find (>0) (ident 5 :: Matrix Float)) [10 ..] :: Matrix Double
m2 = diagRect 7 (fromList[10..14]) 6 6
condTest = utest "cond" ok
where
ok = step v * v == cond v 0 0 0 v
v = fromList [7 .. 7 ] :: Vector Float
conformTest = utest "conform" ok
where
ok = 1 + row [1,2,3] + col [10,20,30,40] + (4><3) [1..]
== (4><3) [13,15,17
,26,28,30
,39,41,43
,52,54,56]
accumTest = utest "accum" ok
where
x = ident 3 :: Matrix Double
ok = accum x (+) [((1,2),7), ((2,2),3)]
== (3><3) [1,0,0
,0,1,7
,0,0,4]
&&
toList (flatten x) == [1,0,0,0,1,0,0,0,1]
convolutionTest = utest "convolution" ok
where
b = fromList [1..3] :: Vector Double
c = (5><7) [1..] :: Matrix Double
ok = separable (corr b) c == corr2 (outer b b) c
&& separable (conv b) c == conv2 (outer b b) c
sparseTest = utest "sparse" (fst $ checkT (undefined :: GMatrix))
staticTest = utest "static" (fst $ checkT (undefined :: L 3 5))
intTest = utest "int ops" (fst $ checkT (undefined :: Matrix I))
modularTest = utest "modular ops" (fst $ checkT (undefined :: Matrix (Mod 13 I)))
indexProp g f x = a1 == g a2 && a2 == a3 && b1 == g b2 && b2 == b3
where
l = map g (toList (f x))
a1 = maximum l
b1 = minimum l
a2 = x `atIndex` maxIndex x
b2 = x `atIndex` minIndex x
a3 = maxElement x
b3 = minElement x
sliceTest = utest "slice test" $ and
[ testSlice (chol . trustSym) (gen 5 :: Matrix R)
, testSlice (chol . trustSym) (gen 5 :: Matrix C)
, testSlice qr (rec :: Matrix R)
, testSlice qr (rec :: Matrix C)
, testSlice hess (agen 5 :: Matrix R)
, testSlice hess (agen 5 :: Matrix C)
, testSlice schur (agen 5 :: Matrix R)
, testSlice schur (agen 5 :: Matrix C)
, testSlice lu (agen 5 :: Matrix R)
, testSlice lu (agen 5 :: Matrix C)
, testSlice (luSolve (luPacked (agen 5 :: Matrix R))) (agen 5)
, testSlice (luSolve (luPacked (agen 5 :: Matrix C))) (agen 5)
, test_lus (agen 5 :: Matrix R)
, test_lus (agen 5 :: Matrix C)
, testSlice eig (agen 5 :: Matrix R)
, testSlice eig (agen 5 :: Matrix C)
, testSlice (eigSH . trustSym) (gen 5 :: Matrix R)
, testSlice (eigSH . trustSym) (gen 5 :: Matrix C)
, testSlice eigenvalues (agen 5 :: Matrix R)
, testSlice eigenvalues (agen 5 :: Matrix C)
, testSlice (eigenvaluesSH . trustSym) (gen 5 :: Matrix R)
, testSlice (eigenvaluesSH . trustSym) (gen 5 :: Matrix C)
, testSlice svd (rec :: Matrix R)
, testSlice thinSVD (rec :: Matrix R)
, testSlice compactSVD (rec :: Matrix R)
, testSlice leftSV (rec :: Matrix R)
, testSlice rightSV (rec :: Matrix R)
, testSlice singularValues (rec :: Matrix R)
, testSlice svd (rec :: Matrix C)
, testSlice thinSVD (rec :: Matrix C)
, testSlice compactSVD (rec :: Matrix C)
, testSlice leftSV (rec :: Matrix C)
, testSlice rightSV (rec :: Matrix C)
, testSlice singularValues (rec :: Matrix C)
, testSlice (linearSolve (agen 5:: Matrix R)) (agen 5)
, testSlice (flip linearSolve (agen 5:: Matrix R)) (agen 5)
, testSlice (linearSolve (agen 5:: Matrix C)) (agen 5)
, testSlice (flip linearSolve (agen 5:: Matrix C)) (agen 5)
, testSlice (linearSolveLS (ogen 5:: Matrix R)) (ogen 5)
, testSlice (flip linearSolveLS (ogen 5:: Matrix R)) (ogen 5)
, testSlice (linearSolveLS (ogen 5:: Matrix C)) (ogen 5)
, testSlice (flip linearSolveLS (ogen 5:: Matrix C)) (ogen 5)
, testSlice (linearSolveSVD (ogen 5:: Matrix R)) (ogen 5)
, testSlice (flip linearSolveSVD (ogen 5:: Matrix R)) (ogen 5)
, testSlice (linearSolveSVD (ogen 5:: Matrix C)) (ogen 5)
, testSlice (flip linearSolveSVD (ogen 5:: Matrix C)) (ogen 5)
, testSlice (linearSolveLS (ugen 5:: Matrix R)) (ugen 5)
, testSlice (flip linearSolveLS (ugen 5:: Matrix R)) (ugen 5)
, testSlice (linearSolveLS (ugen 5:: Matrix C)) (ugen 5)
, testSlice (flip linearSolveLS (ugen 5:: Matrix C)) (ugen 5)
, testSlice (linearSolveSVD (ugen 5:: Matrix R)) (ugen 5)
, testSlice (flip linearSolveSVD (ugen 5:: Matrix R)) (ugen 5)
, testSlice (linearSolveSVD (ugen 5:: Matrix C)) (ugen 5)
, testSlice (flip linearSolveSVD (ugen 5:: Matrix C)) (ugen 5)
, testSlice ((<>) (ogen 5:: Matrix R)) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix R)) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix C)) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix C)) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix Float)) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix Float)) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix (Complex Float))) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix (Complex Float))) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix I)) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix I)) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix Z)) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix Z)) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix (I ./. 7))) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix (I ./. 7))) (ogen 5)
, testSlice ((<>) (ogen 5:: Matrix (Z ./. 7))) (gen 5)
, testSlice (flip (<>) (gen 5:: Matrix (Z ./. 7))) (ogen 5)
, testSlice (flip cholSolve (agen 5:: Matrix R)) (chol $ trustSym $ gen 5)
, testSlice (flip cholSolve (agen 5:: Matrix C)) (chol $ trustSym $ gen 5)
, testSlice (cholSolve (chol $ trustSym $ gen 5:: Matrix R)) (agen 5)
, testSlice (cholSolve (chol $ trustSym $ gen 5:: Matrix C)) (agen 5)
, ok_qrgr (rec :: Matrix R)
, ok_qrgr (rec :: Matrix C)
, testSlice (test_qrgr 4 tau1) qrr1
, testSlice (test_qrgr 4 tau2) qrr2
]
where
QR qrr1 tau1 = qrRaw (rec :: Matrix R)
QR qrr2 tau2 = qrRaw (rec :: Matrix C)
test_qrgr n t x = qrgr n (QR x t)
ok_qrgr x = simeq 1E-15 q q'
where
(q,_) = qr x
atau = qrRaw x
q' = qrgr (rows q) atau
simeq eps a b = not $ magnit eps (norm_1 $ flatten (ab))
test_lus m = testSlice f lup
where
f x = luSolve (LU x p) m
(LU lup p) = luPacked m
gen :: Numeric t => Int -> Matrix t
gen n = diagRect 1 (konst 5 n) n n
agen :: (Numeric t, Num (Vector t))=> Int -> Matrix t
agen n = gen n + fromInt ((n><n)[0..])
ogen :: (Numeric t, Num (Vector t))=> Int -> Matrix t
ogen n = gen n === gen n
ugen :: (Numeric t, Num (Vector t))=> Int -> Matrix t
ugen n = takeRows 3 (gen n)
rec :: Numeric t => Matrix t
rec = subMatrix (0,0) (4,5) (gen 5)
testSlice f x@(size->sz@(r,c)) = all (==f x) (map f (g y1 ++ g y2))
where
subm = subMatrix
g y = [ subm (a*r,b*c) sz y | a <-[0..2], b <- [0..2]]
h z = fromBlocks (replicate 3 (replicate 3 z))
y1 = h x
y2 = (tr . h . tr) x
runTests :: Int
-> IO ()
runTests n = do
let test :: forall t . T.Testable t => t -> IO ()
test p = qCheck n p
putStrLn "------ index"
test( \m -> indexProp id flatten (single (m :: RM)) )
test( \v -> indexProp id id (single (v :: Vector Double)) )
test( \m -> indexProp id flatten (m :: RM) )
test( \v -> indexProp id id (v :: Vector Double) )
test( \m -> indexProp magnitude flatten (single (m :: CM)) )
test( \v -> indexProp magnitude id (single (v :: Vector (Complex Double))) )
test( \m -> indexProp magnitude flatten (m :: CM) )
test( \v -> indexProp magnitude id (v :: Vector (Complex Double)) )
putStrLn "------ mult Double"
test (multProp1 10 . rConsist)
test (multProp1 10 . cConsist)
test (multProp2 10 . rConsist)
test (multProp2 10 . cConsist)
putStrLn "------ sub-trans"
test (subProp . rM)
test (subProp . cM)
putStrLn "------ ctrans"
test (conjuTest . cM)
test (conjuTest . zM)
putStrLn "------ lu"
test (luProp . rM)
test (luProp . cM)
putStrLn "------ inv (linearSolve)"
test (invProp . rSqWC)
test (invProp . cSqWC)
putStrLn "------ luSolve"
test (linearSolveProp (luSolve.luPacked) . rSqWC)
test (linearSolveProp (luSolve.luPacked) . cSqWC)
putStrLn "------ ldlSolve"
test (linearSolvePropH (ldlSolve.ldlPacked) . rSymWC)
test (linearSolvePropH (ldlSolve.ldlPacked) . cSymWC)
putStrLn "------ cholSolve"
test (linearSolveProp (cholSolve.chol.trustSym) . rPosDef)
test (linearSolveProp (cholSolve.chol.trustSym) . cPosDef)
putStrLn "------ luSolveLS"
test (linearSolveProp linearSolveLS . rSqWC)
test (linearSolveProp linearSolveLS . cSqWC)
test (linearSolveProp2 linearSolveLS . rConsist)
test (linearSolveProp2 linearSolveLS . cConsist)
putStrLn "------ pinv (linearSolveSVD)"
test (pinvProp . rM)
test (pinvProp . cM)
putStrLn "------ det"
test (detProp . rSqWC)
test (detProp . cSqWC)
putStrLn "------ svd"
test (svdProp1 . rM)
test (svdProp1 . cM)
test (svdProp1a svd . rM)
test (svdProp1a svd . cM)
test (svdProp1b svd . rM)
test (svdProp1b svd . cM)
test (svdProp2 thinSVD . rM)
test (svdProp2 thinSVD . cM)
test (svdProp3 . rM)
test (svdProp3 . cM)
test (svdProp4 . rM)
test (svdProp4 . cM)
test (svdProp5a)
test (svdProp5b)
test (svdProp6a)
test (svdProp6b)
test (svdProp7 . rM)
test (svdProp7 . cM)
#ifdef NOZGESDD
#else
#endif
putStrLn "------ eig"
test (eigSHProp . rHer)
test (eigSHProp . cHer)
test (eigProp . rSq)
test (eigProp . cSq)
test (eigSHProp2 . rHer)
test (eigSHProp2 . cHer)
test (eigProp2 . rSq)
test (eigProp2 . cSq)
putStrLn "------ nullSpace"
test (nullspaceProp . rM)
test (nullspaceProp . cM)
putStrLn "------ qr"
test (qrProp . rM)
test (qrProp . cM)
test (rqProp . rM)
test (rqProp1 . cM)
test (rqProp2 . cM)
putStrLn "------ hess"
test (hessProp . rSq)
test (hessProp . cSq)
putStrLn "------ schur"
test (schurProp2 . rSq)
test (schurProp1 . cSq)
putStrLn "------ chol"
test (cholProp . rPosDef)
test (cholProp . cPosDef)
putStrLn "------ expm"
test (expmDiagProp . complex. rSqWC)
test (expmDiagProp . cSqWC)
putStrLn "------ vector operations - Double"
test (\u -> sin u ^ 2 + cos u ^ 2 |~| (1::RM))
test $ (\u -> sin u ^ 2 + cos u ^ 2 |~| (1::CM)) . liftMatrix makeUnitary
test (\u -> sin u ** 2 + cos u ** 2 |~| (1::RM))
test (\u -> cos u * tan u |~| sin (u::RM))
test $ (\u -> cos u * tan u |~| sin (u::CM)) . liftMatrix makeUnitary
putStrLn "------ read . show"
test (\m -> (m::RM) == read (show m))
test (\m -> (m::CM) == read (show m))
test (\m -> toRows (m::RM) == read (show (toRows m)))
test (\m -> toRows (m::CM) == read (show (toRows m)))
test (\m -> (m::FM) == read (show m))
test (\m -> (m::ZM) == read (show m))
test (\m -> toRows (m::FM) == read (show (toRows m)))
test (\m -> toRows (m::ZM) == read (show (toRows m)))
putStrLn "------ some unit tests"
c <- runTestTT $ TestList
[ utest "1E5 rots" rotTest
, utest "det1" detTest1
, utest "invlndet" detTest2
, utest "expm1" (expmTest1)
, utest "expm2" (expmTest2)
, utest "arith1" $ ((ones (100,100) * 5 + 2)/0.5 7)**2 |~| (49 :: RM)
, utest "arith2" $ ((scalar (1+iC) * ones (100,100) * 5 + 2)/0.5 7)**2 |~| ( scalar (140*iC51) :: CM)
, utest "arith3" $ exp (scalar iC * ones(10,10)*pi) + 1 |~| 0
, utest "<\\>" $ (3><2) [2,0,0,3,1,1::Double] <\> 3|>[4,9,5] |~| 2|>[2,3]
, utest "randomGaussian" randomTestGaussian
, utest "randomUniform" randomTestUniform
, utest "buildVector/Matrix" $
complex (10 |> [0::Double ..]) == build 10 id
&& ident 5 == build (5,5) (\r c -> if r==c then 1::Double else 0)
, utest "rank" $ rank ((2><3)[1,0,0,1,5*peps,0::Double]) == 1
&& rank ((2><3)[1,0,0,1,7*peps,0::Double]) == 2
, utest "block" $ fromBlocks [[ident 3,0],[0,ident 4]] == (ident 7 :: CM)
, mbCholTest
, utest "offset" offsetTest
, normsVTest
, normsMTest
, sumprodTest
, chainTest
, succTest
, findAssocTest
, condTest
, conformTest
, accumTest
, convolutionTest
, sparseTest
, staticTest
, intTest
, modularTest
, sliceTest
]
when (errors c + failures c > 0) exitFailure
return ()
makeUnitary v | realPart n > 1 = v / scalar n
| otherwise = v
where n = sqrt (v `dot` v)
binaryTests :: IO ()
binaryTests = do
let test :: forall t . T.Testable t => t -> IO ()
test = qCheck 100
test vectorBinaryRoundtripProp
test staticVectorBinaryRoundtripProp
qCheck 30 matrixBinaryRoundtripProp
qCheck 30 staticMatrixBinaryRoundtripProp
runBenchmarks :: IO ()
runBenchmarks = do
solveBench
subBench
mkVecBench
multBench
cholBench
luBench
luBench_2
svdBench
eigBench
putStrLn ""
time msg act = do
putStr (msg++" ")
t0 <- getCPUTime
act `seq` putStr " "
t1 <- getCPUTime
printf "%6.2f s CPU\n" $ (fromIntegral (t1 t0) / (10^12 :: Double)) :: IO ()
return ()
timeR msg act = do
putStr (msg++" ")
t0 <- getCPUTime
putStr (show act)
t1 <- getCPUTime
printf "%6.2f s CPU\n" $ (fromIntegral (t1 t0) / (10^12 :: Double)) :: IO ()
return ()
manymult n = foldl1' (<>) (map rot2 angles) where
angles = toList $ linspace n (0,1)
rot2 :: Double -> Matrix Double
rot2 a = (3><3) [ c,0,s
, 0,1,0
,s,0,c ]
where c = cos a
s = sin a
multb n = foldl1' (<>) (replicate (10^6) (ident n :: Matrix Double))
manyvec0 xs = sum $ map (\x -> x + x**2 + x**3) xs
manyvec1 xs = sumElements $ fromRows $ map (\x -> fromList [x,x**2,x**3]) xs
manyvec5 xs = sumElements $ fromRows $ map (\x -> vec3 x (x**2) (x**3)) xs
manyvec2 xs = sum $ map (\x -> sqrt(x^2 + (x**2)^2 +(x**3)^2)) xs
manyvec3 xs = sum $ map (norm_2 . (\x -> fromList [x,x**2,x**3])) xs
manyvec4 xs = sum $ map (norm_2 . (\x -> vec3 x (x**2) (x**3))) xs
vec3 :: Double -> Double -> Double -> Vector Double
vec3 a b c = runSTVector $ do
v <- newUndefinedVector 3
writeVector v 0 a
writeVector v 1 b
writeVector v 2 c
return v
mkVecBench = do
let n = 1000000
xs = toList $ linspace n (0,1::Double)
putStr "\neval data... "; print (sum xs)
timeR "listproc " $ manyvec0 xs
timeR "fromList matrix " $ manyvec1 xs
timeR "vec3 matrix " $ manyvec5 xs
timeR "listproc norm " $ manyvec2 xs
timeR "norm fromList " $ manyvec3 xs
timeR "norm vec3 " $ manyvec4 xs
subBench = do
putStrLn ""
let g = foldl1' (.) (replicate (10^5) (\v -> subVector 1 (size v 1) v))
time "0.1M subVector " (g (konst 1 (1+10^5) :: Vector Double) ! 0)
let f = foldl1' (.) (replicate (10^5) (fromRows.toRows))
time "subVector-join 3" (f (ident 3 :: Matrix Double) `atIndex` (0,0))
time "subVector-join 10" (f (ident 10 :: Matrix Double) `atIndex` (0,0))
multBench = do
let a = ident 1000 :: Matrix Double
let b = ident 2000 :: Matrix Double
a `seq` b `seq` putStrLn ""
time "product of 1M different 3x3 matrices" (manymult (10^6))
putStrLn ""
time "product of 1M constant 1x1 matrices" (multb 1)
time "product of 1M constant 3x3 matrices" (multb 3)
time "product of 1M const. 10x10 matrices" (multb 10)
time "product of 1M const. 20x20 matrices" (multb 20)
putStrLn ""
time "product (1000 x 1000)<>(1000 x 1000)" (a<>a)
time "product (2000 x 2000)<>(2000 x 2000)" (b<>b)
eigBench = do
let m = reshape 1000 (randomVector 777 Uniform (1000*1000))
s = m + tr m
m `seq` s `seq` putStrLn ""
time "eigenvalues symmetric 1000x1000" (eigenvaluesSH (trustSym m))
time "eigenvectors symmetric 1000x1000" (snd $ eigSH (trustSym m))
time "eigenvalues general 1000x1000" (eigenvalues m)
time "eigenvectors general 1000x1000" (snd $ eig m)
svdBench = do
let a = reshape 500 (randomVector 777 Uniform (3000*500))
b = reshape 1000 (randomVector 777 Uniform (1000*1000))
fv (_,_,v) = v `atIndex` (0,0)
a `seq` b `seq` putStrLn ""
time "singular values 3000x500" (singularValues a)
time "thin svd 3000x500" (fv $ thinSVD a)
time "full svd 3000x500" (fv $ svd a)
time "singular values 1000x1000" (singularValues b)
time "full svd 1000x1000" (fv $ svd b)
solveBenchN n = do
let x = uniformSample 777 (2*n) (replicate n (1,1))
a = tr x <> x
b = asColumn $ randomVector 666 Uniform n
a `seq` b `seq` putStrLn ""
time ("svd solve " ++ show n) (linearSolveSVD a b)
time (" ls solve " ++ show n) (linearSolveLS a b)
time (" solve " ++ show n) (linearSolve a b)
time ("LDL solve " ++ show n) (ldlSolve (ldlPacked (trustSym a)) b)
time ("cholSolve " ++ show n) (cholSolve (chol $ trustSym a) b)
solveBench = do
solveBenchN 500
solveBenchN 1000
solveBenchN 1500
cholBenchN n = do
let x = uniformSample 777 (2*n) (replicate n (1,1))
a = tr x <> x
a `seq` putStr ""
time ("chol " ++ show n) (chol $ trustSym a)
cholBench = do
putStrLn ""
cholBenchN 1200
cholBenchN 600
cholBenchN 300
luBenchN f n x msg = do
let m = diagRect 1 (fromList (replicate n x)) n n
m `seq` putStr ""
time (msg ++ " "++ show n) (rnf $ f m)
luBench = do
putStrLn ""
luBenchN luPacked 1000 (5::R) "luPacked Double "
luBenchN luPacked' 1000 (5::R) "luPacked' Double "
luBenchN luPacked' 1000 (5::Mod 9973 I) "luPacked' I mod 9973"
luBenchN luPacked' 1000 (5::Mod 9973 Z) "luPacked' Z mod 9973"
luBenchN_2 f g n x msg = do
let m = diagRect 1 (fromList (replicate n x)) n n
b = flipud m
m `seq` b `seq` putStr ""
time (msg ++ " "++ show n) (f (g m) b)
luBench_2 = do
putStrLn ""
luBenchN_2 luSolve luPacked 500 (5::R) "luSolve .luPacked Double "
luBenchN_2 luSolve' luPacked' 500 (5::R) "luSolve'.luPacked' Double "
luBenchN_2 luSolve' luPacked' 500 (5::Mod 9973 I) "luSolve'.luPacked' I mod 9973"
luBenchN_2 luSolve' luPacked' 500 (5::Mod 9973 Z) "luSolve'.luPacked' Z mod 9973"