cdar-mBound-0.1.0.0: bench/bench.hs
import Control.Concurrent
import Control.Monad ()
import Criterion.Main
import Data.Bits
import Data.Ratio
import Data.CDAR
logMap :: (Fractional a) => Rational -> a -> a
logMap c x = (fromRational c)*x*(1-x)
logMap2 :: Approx -> Approx
logMap2 Bottom = Bottom
logMap2 (Approx mb m e s) =
let one = bit (-s)
t = abs (bit (-s-1) - m)
in boundErrorTerm $
if t >= e
then approxMB mb (m*(one-m)-e^2) (e * abs (one-2*m)) (2*s)
else approxMB mb (bit (-2*s - 2)) ((t + e)^2) (2*s)
orbit :: Fractional a => Rational -> [a]
orbit c = iterate (logMap c) (fromRational (1%8))
orbit2 :: Rational -> [CR]
orbit2 c = iterate (((fromRational c)*) . CR . fmap logMap2 . unCR) (fromRational (1%8))
suite :: [Benchmark]
suite = [
bgroup "Logistic 4" [
bench "Double" $ nf (!! 10000) (orbit 4 :: [Double])
, bench "CR" $ nf (require 10 . (!! 10000)) (orbit 4 :: [CR])
, bench "CR (2)" $ nf (require 10 . (!! 10000)) (orbit2 4 :: [CR])
],
bgroup "Logistic 3.5" [
bench "Double" $ nf (!! 10000) (orbit (7%2) :: [Double])
, bench "CR" $ nf (require 10 . (!! 10000)) (orbit (7%2) :: [CR])
, bench "CR (2)" $ nf (require 10 . (!! 10000)) (orbit2 (7%2) :: [CR])
],
bgroup "Logistic 3" [
bench "Double" $ nf (!! 10000) (orbit 3 :: [Double])
, bench "CR" $ nf (require 10 . (!! 10000)) (orbit 3 :: [CR])
, bench "CR (2)" $ nf (require 10 . (!! 10000)) (orbit2 3 :: [CR])
]
]
newSuite :: [Benchmark]
newSuite =
[ bgroup "expappr"
[ bench "double" $ nf exp (1 :: Double)
, bench "B40" $ nf (expBinarySplittingA 40) 1
, bench "T40" $ nf (expTaylorA 40) 1
, bench "T'40" $ nf expTaylorA' (setMB 40 1)
, bench "CR40" $ nf (require 40 . expCR) 1
, bench "B400" $ nf (expBinarySplittingA 400) 1
, bench "T400" $ nf (expTaylorA 400) 1
, bench "T'400" $ nf expTaylorA' (setMB 400 1)
, bench "CR400" $ nf (require 400 . expCR) 1
, bench "B4000" $ nf (expBinarySplittingA 4000) 1
, bench "T4000" $ nf (expTaylorA 4000) 1
, bench "T'4000" $ nf (expTaylorA') (setMB 4000 1)
, bench "CR4000" $ nf (require 4000 . expCR) 1
]
, bgroup "logappr"
[ bench "doubleLog" $ nf log (1.5 :: Double)
, bench "40B" $ nf (logBinarySplittingA 40) (Approx 10 3 0 (-1))
, bench "40T" $ nf (logTaylorA 40) (Approx 10 3 0 (-1))
-- , bench "40agm" $ nf (logAgmA (-40)) (Approx 10 3 0 (-1))
, bench "400B" $ nf (logBinarySplittingA 400) (Approx 10 3 0 (-1))
, bench "400T" $ nf (logTaylorA 400) (Approx 10 3 0 (-1))
-- , bench "400agm" $ nf (logAgmA (-400)) (Approx 10 3 0 (-1))
, bench "4000B" $ nf (logBinarySplittingA 4000) (Approx 10 3 0 (-1))
, bench "4000T" $ nf (logTaylorA 4000) (Approx 10 3 0 (-1))
-- , bench "4000agm" $ nf (logAgmA (-4000)) (Approx 10 3 0 (-1))
]
, bgroup "exp"
[ bench "double" $ nf exp (1 :: Double)
, bench "40" $ nf (require 40 . exp) 1
, bench "400" $ nf (require 400 . exp) 1
]
, bgroup "log"
[ bench "double" $ nf log (2 :: Double)
, bench "40" $ nf (require 40 . log) 2
, bench "400" $ nf (require 400 . log) 2
]
, bgroup "sin"
[ bench "double" $ nf sin (1 :: Double)
, bench "40" $ nf (require 40 . sin) 1
, bench "40T" $ nf sinTaylorA (setMB 40 1)
, bench "40CR" $ nf (require 40 . sinCR) 1
, bench "400" $ nf (require 400 . sin) 1
, bench "400T" $ nf sinTaylorA (setMB 400 1)
, bench "400CR" $ nf (require 400 . sinCR) 1
-- , bench "4000" $ nf (require 4000 . sin) 1
, bench "4000T" $ nf sinTaylorA (setMB 4000 1)
, bench "4000CR" $ nf (require 4000 . sinCR) 1
]
, bgroup "cos"
[ bench "double" $ nf cos (1 :: Double)
, bench "40" $ nf (require 40 . cos) 1
, bench "400" $ nf (require 400 . cos) 1
]
, bgroup "atan"
[ bench "double" $ nf atan (1 :: Double)
, bench "40" $ nf (require 40 . atan) 1
, bench "400" $ nf (require 400 . atan) 1
]
, bgroup "pi"
[ bench "double" $ nf (\_ -> pi :: Double) (1 :: Double)
, bench "40" $ nf (\_ -> require 40 $ pi) 1
, bench "400" $ nf (\_ -> require 400 $ pi) 1
]
, env setupEnvPi $ \ ~(pi40,pi400,pi4000) ->
bgroup "ccc2015"
[ bench "pi D" $ nf (\_ -> pi :: Double) (1 :: Double)
, bench "pi 40" $ nf (\_ -> require 40 $ pi) 1
, bench "pi 400" $ nf (\_ -> require 400 $ pi) 1
, bench "pi 4000" $ nf (\_ -> require 4000 $ pi) 1
, bench "+ D" $ nf (\x -> x+x) (pi :: Double)
, bench "+ 40" $ nf (\x -> x+x) pi40
, bench "+ 400" $ nf (\x -> x+x) pi400
, bench "+ 4000" $ nf (\x -> x+x) pi4000
, bench "* D" $ nf (\x -> x*x) (pi :: Double)
, bench "* 40" $ nf (\x -> x*x) pi40
, bench "* 400" $ nf (\x -> x*x) pi400
, bench "* 4000" $ nf (\x -> x*x) pi4000
, bench "* D" $ nf (1/) (pi :: Double)
, bench "* 40" $ nf (1/) pi40
, bench "* 400" $ nf (1/) pi400
, bench "* 4000" $ nf (1/) pi4000
, bench "exp D" $ nf exp (1 :: Double)
, bench "exp 40" $ nf (require 40 . exp) 1
, bench "exp 400" $ nf (require 400 . exp) 1
, bench "exp 4000" $ nf (require 4000 . exp) 1
, bench "log D" $ nf log (2 :: Double)
, bench "log 40" $ nf (require 40 . log) 2
, bench "log 400" $ nf (require 400 . log) 2
, bench "log 4000" $ nf (require 4000 . log) 2
, bench "sin D" $ nf sin (1 :: Double)
, bench "sin 40" $ nf (require 40 . sinCR) 1
, bench "sin 400" $ nf (require 400 . sinCR) 1
, bench "sin 4000" $ nf (require 4000 . sinCR) 1
, bench "cos D" $ nf cos (1 :: Double)
, bench "cos 40" $ nf (require 40 . cosCR) 1
, bench "cos 400" $ nf (require 400 . cosCR) 1
, bench "cos 4000" $ nf (require 4000 . cosCR) 1
, bench "atan D" $ nf atan (1 :: Double)
, bench "atan 40" $ nf (require 40 . atanCR) 1
, bench "atan 400" $ nf (require 400 . atanCR) 1
, bench "atan 4000" $ nf (require 4000 . atanCR) 1
]
, env setupEnv $ \ ~(pi1,pi2) ->
bgroup "elementary Approx"
[ bench "+ double" $ nf (\x -> x+x) (pi :: Double)
, bench "* double" $ nf (\x -> x*x) (pi :: Double)
, bench "rec double" $ nf (1/) (pi :: Double)
, bench "sqrt double" $ nf (sqrt) (pi :: Double)
, bench "+ 50" $ nf (\x -> x+x) pi1
, bench "* 50" $ nf (\x -> x*x) pi1
, bench "rec 50" $ nf recipA (setMB 50 pi1)
, bench "sqrt 50" $ nf sqrtA (setMB 50 pi1)
, bench "log 50" $ nf (logA) (setMB 50 pi1)
, bench "+ 1000" $ nf (\x -> x+x) pi2
, bench "* 1000" $ nf (\x -> x*x) pi2
, bench "rec 1000" $ nf recipA (setMB 1000 pi2)
, bench "sqrt 1000" $ nf sqrtA (setMB 1000 pi2)
, bench "sqrtRec 1000" $ nf (sqrtRecA 1000) pi2
, bench "log 1000" $ nf logA (setMB 1000 pi2)
]
]
setupEnv :: IO (Approx, Approx)
setupEnv = return . (\a -> (limitAndBound 50 a, a)) . limitAndBound 1000 . require 1000 $ pi
setupEnvPi :: IO (Approx, Approx, Approx)
setupEnvPi = return . (\a -> (limitAndBound 40 a, limitAndBound 400 a, limitAndBound 4000 a)) . require 4000 $ pi
threadSuite :: MVar Approx -> MVar Approx -> [Benchmark]
threadSuite u v =
[ bgroup "thread"
[ bench "communicate" $ nfIO (do putMVar u (Approx 30 145324626 123 (-30)); a <- takeMVar v; return a)
]
]
main :: IO ()
main = defaultMain $ newSuite -- ++ suite
{- Are threads making criterion confused, times seem ok, but reported as unreliable.
threadSuite :: MVar Approx -> MVar Approx -> [Benchmark]
threadSuite u v =
[ bgroup "thread"
[ bench "communicate" $ nfIO (do putMVar u pi2; a <- takeMVar v; return a)
]
]
main :: IO ()
main = do
u <- newEmptyMVar
v <- newEmptyMVar
forkIO $ server u v
defaultMain $ threadSuite u v
where server u v = forever $ do
a <- takeMVar u
putMVar v (a + 1)
-}