-
Notifications
You must be signed in to change notification settings - Fork 1
/
Util.hs
108 lines (80 loc) · 2.68 KB
/
Util.hs
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
{-# LANGUAGE FlexibleInstances, BangPatterns #-}
module Util
where
import Data.List
import qualified Data.Map as M
import Data.Bits
import Data.MemoCombinators as Memo
import qualified Data.ByteString as B
import Data.Array.Unboxed
import Test.QuickCheck
cut :: Int -> [a] -> [[a]]
cut n xs = go xs
where go [] = []
go xs = take n xs : go (drop n xs)
--takeWhile (not.null) . map (take n) $ iterate (drop n) xs
count :: (a -> Bool) -> [a] -> Int
count f xs = length $ filter f xs
--(!) = V.index
ilog2 :: Int -> Int
ilog2 n = go 0 n
where go !acc 0 = acc
go !acc n = go (acc+1) (shiftR n 1)
bitify 0 = []
bitify n | even n = False : bitify (n`div`2)
| otherwise = True : bitify (n`div`2)
pad len xs = take len $ xs ++ repeat False
unbitify :: [Bool] -> Integer
unbitify xs = go 0 1 xs
where go acc _ [] = acc
go acc k (True :xs) = go (acc+k) (2*k) xs
go acc k (False:xs) = go acc (2*k) xs
prop_unbitify_bitify i = i>=0 ==> unbitify (bitify i) == i
prop_bitify_unbitify xs' =
let xs = xs'++[True] in bitify (unbitify xs) == xs
prop_bitify_ilog x = x>0 ==> length (bitify x) == ilog2 x
roundUpToPowerOf k x = go 1
where go acc | acc >= x = acc
| otherwise = go (k*acc)
roundUpToMultipleOf k x = k * (x `mydiv` k)
infixl 7 `mydiv`
mydiv a b = let (x,y) = quotRem a b in
if y==0 then x else x+1
a /// b = fromIntegral a / fromIntegral b
listArray' n xs = listArray (0,n-1) xs
binom_max = 100
binom :: Integer -> Integer -> Integer
binom = Memo.memo2
(Memo.unsafeArrayRange (0,binom_max))
(Memo.unsafeArrayRange (0,binom_max))
binom'
where binom' _ 0 = 1
binom' 0 _ = 0
binom' n k =
binom (n-1) k + binom (n-1) (k-1)
occurrences :: Eq a => a -> [a] -> Int
occurrences x xs = length $ filter (==x) xs
entropy :: Int -> String -> Double
entropy 0 xs =
sum [ let f_a = occurrences a xs /// n in negate $ f_a * logBase 2 f_a
| a <- alphabet]
where n = length xs
alphabet = nub xs
entropy k xs =
x / fromIntegral n
where n = length xs
-- all k-substrings of xs
subs = take n . map (take k) $ tails xs
chars = map (:[]) . take n . drop k $ xs
combine (xs,n) (xs',n') = (xs++xs',n+n')
m = M.fromListWith combine $ zip subs (zip chars $ repeat 1)
x = sum [ n_xs * entropy 0 xs | (xs,n_xs) <- M.elems m ]
bitsFromFile :: String -> IO [Bool]
bitsFromFile name = do
d <- B.readFile name
return $ concatMap (pad 8.bitify) (B.unpack d)
-------------
-- Test utils
-------------
chooseIndex :: [a] -> Gen Int
chooseIndex xs = choose (0,length xs - 1)