-
Notifications
You must be signed in to change notification settings - Fork 0
/
ShowDist.curry
60 lines (46 loc) · 1.87 KB
/
ShowDist.curry
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
{-# OPTIONS_CYMAKE -X TypeClassExtensions #-}
module ShowDist
-- (showWithRescale, showLight, showWithFunction, scale)
where
import PFLP
import Distributions (scale')
import Float (i2f,round)
import Function (on)
import List (sort,sortBy, maximum, groupBy,sum)
import SetFunctions (foldValues, mapValues, set0)
showLight :: (Ord a, Show a) => Dist a -> String
showLight = showWithFunction (map sumDists)
showWithRescale :: (Ord a, Show a) => Dist a -> String
showWithRescale = showWithFunction (\xss -> scale (map sumDists xss))
showWithFunction :: (Ord a, Show a) => ([[(a,Probability)]] -> [(a,Probability)]) -> Dist a -> String
showWithFunction f dist =
concatMap (\(x,p) -> showR w x ++ ' ' : show p ++ "\n")
(sortP (f (norm dList)))
where
dList = distToList dist
w = maximum (map (length . show . fst) dList)
showR n x = let s = show x
in replicate (n-length s) ' ' ++ s
sumDists :: [(a,Probability)] -> (a,Probability)
sumDists [] = error "sumDists: No values in distribution"
sumDists xs@((x,_):_) = (x,sum (map snd xs))
scale :: [(a,Probability)] -> [(a,Probability)]
scale = map (onSnd Prob) . scale' . map (onSnd unP)
onSnd :: (a -> b) -> (c,a) -> (c,b)
onSnd f (x,y) = (x, f y)
sortP :: [(a,Probability)] -> [(a,Probability)]
sortP = sortBy (\x y -> snd y <= snd x)
distToList :: Dist a -> [(a,Probability)]
distToList dist =
foldValues (\xs ys -> xs ++ ys) []
$ mapValues (\(Dist v p) -> [(v,p)]) (set0 dist)
norm :: (Ord a, Eq a) => [(a,Probability)] -> [[(a,Probability)]]
norm = groupBy (\x y -> fst y == fst x) . sort
-- accumBy :: Num b => (a -> a -> Bool) -> [(a,b)] -> [(a,b)]
-- accumBy _ [] = []
-- accumBy _ [x] = [x]
-- accumBy f ((x,p):(y,q):xs)
-- | f x y = accumBy f ((x,p+q):xs)
-- | otherwise = (x,p) : accumBy f ((y,q):xs)
instance Show Probability where
show (Prob p) = show (i2f (round (p * 10000)) / 100) ++ "%"