File: Blocks.hs

package info (click to toggle)
haskell-vector-algorithms 0.9.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 232 kB
  • sloc: haskell: 2,399; ansic: 23; makefile: 3
file content (62 lines) | stat: -rw-r--r-- 1,653 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{-# LANGUAGE Rank2Types #-}

module Blocks where

import Control.Monad
import Control.Monad.ST

import Data.Vector.Unboxed.Mutable

import System.CPUTime

import System.Random.MWC (GenIO, Variate(..))

-- Some conveniences for doing evil stuff in the ST monad.
-- All the tests get run in IO, but uvector stuff happens
-- in ST, so we temporarily coerce.
clock :: IO Integer
clock = getCPUTime

-- Strategies for filling the initial arrays
rand :: Variate e => GenIO -> Int -> IO e
rand g _ = uniform g

ascend :: Num e => Int -> IO e
ascend = return . fromIntegral

descend :: Num e => e -> Int -> IO e
descend m n = return $ m - fromIntegral n

modulo :: Integral e => e -> Int -> IO e
modulo m n = return $ fromIntegral n `mod` m

-- This is the worst case for the median-of-three quicksort
-- used in the introsort implementation.
medianKiller :: Integral e => e -> Int -> IO e
medianKiller m n'
  | n < k     = return $ if even n then n + 1 else n + k
  | otherwise = return $ (n - k + 1) * 2
 where
 n = fromIntegral n'
 k = m `div` 2
{-# INLINE medianKiller #-}

initialize :: (Unbox e) => MVector RealWorld e -> Int -> (Int -> IO e) -> IO ()
initialize arr len fill = initial $ len - 1
 where initial n = fill n >>= unsafeWrite arr n >> when (n > 0) (initial $ n - 1)
{-# INLINE initialize #-}

speedTest :: (Unbox e) => MVector RealWorld e
                       -> Int
                       -> (Int -> IO e)
                       -> (MVector RealWorld e -> IO ())
                       -> IO Integer
speedTest arr n fill algo = do
  initialize arr n fill
  t0 <- clock
  algo arr
  t1 <- clock
  return $ t1 - t0
{-# INLINE speedTest #-}