{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
module LAoP.Dist.Internal
(
Dist(..),
Prob,
Countable,
CountableN,
CountableDimensionsN,
FromListsN,
Liftable,
TrivialP,
fmapD,
unitD,
multD,
selectD,
branchD,
ifD,
returnD,
bindD,
(??),
choose,
shape,
linear,
uniform,
negExp,
normal,
toValues,
prettyDist,
prettyPrintDist
)
where
import LAoP.Matrix.Type hiding (TrivialP, Countable, CountableDimensions, CountableN, CountableDimensionsN, Liftable, FromListsN)
import qualified LAoP.Matrix.Internal as I
import LAoP.Utils
import GHC.TypeLits
import Data.Proxy
import Data.List (sortBy)
import Control.DeepSeq
import Data.Bool
type Prob = Double
newtype Dist a = D (Matrix Prob () a)
deriving (Int -> Dist a -> ShowS
[Dist a] -> ShowS
Dist a -> String
(Int -> Dist a -> ShowS)
-> (Dist a -> String) -> ([Dist a] -> ShowS) -> Show (Dist a)
forall a. Int -> Dist a -> ShowS
forall a. [Dist a] -> ShowS
forall a. Dist a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Dist a] -> ShowS
$cshowList :: forall a. [Dist a] -> ShowS
show :: Dist a -> String
$cshow :: forall a. Dist a -> String
showsPrec :: Int -> Dist a -> ShowS
$cshowsPrec :: forall a. Int -> Dist a -> ShowS
Show, Integer -> Dist a
Dist a -> Dist a
Dist a -> Dist a -> Dist a
(Dist a -> Dist a -> Dist a)
-> (Dist a -> Dist a -> Dist a)
-> (Dist a -> Dist a -> Dist a)
-> (Dist a -> Dist a)
-> (Dist a -> Dist a)
-> (Dist a -> Dist a)
-> (Integer -> Dist a)
-> Num (Dist a)
forall a. Integer -> Dist a
forall a. Dist a -> Dist a
forall a. Dist a -> Dist a -> Dist a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Dist a
$cfromInteger :: forall a. Integer -> Dist a
signum :: Dist a -> Dist a
$csignum :: forall a. Dist a -> Dist a
abs :: Dist a -> Dist a
$cabs :: forall a. Dist a -> Dist a
negate :: Dist a -> Dist a
$cnegate :: forall a. Dist a -> Dist a
* :: Dist a -> Dist a -> Dist a
$c* :: forall a. Dist a -> Dist a -> Dist a
- :: Dist a -> Dist a -> Dist a
$c- :: forall a. Dist a -> Dist a -> Dist a
+ :: Dist a -> Dist a -> Dist a
$c+ :: forall a. Dist a -> Dist a -> Dist a
Num, Dist a -> Dist a -> Bool
(Dist a -> Dist a -> Bool)
-> (Dist a -> Dist a -> Bool) -> Eq (Dist a)
forall a. Dist a -> Dist a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Dist a -> Dist a -> Bool
$c/= :: forall a. Dist a -> Dist a -> Bool
== :: Dist a -> Dist a -> Bool
$c== :: forall a. Dist a -> Dist a -> Bool
Eq, Eq (Dist a)
Eq (Dist a) =>
(Dist a -> Dist a -> Ordering)
-> (Dist a -> Dist a -> Bool)
-> (Dist a -> Dist a -> Bool)
-> (Dist a -> Dist a -> Bool)
-> (Dist a -> Dist a -> Bool)
-> (Dist a -> Dist a -> Dist a)
-> (Dist a -> Dist a -> Dist a)
-> Ord (Dist a)
Dist a -> Dist a -> Bool
Dist a -> Dist a -> Ordering
Dist a -> Dist a -> Dist a
forall a. Eq (Dist a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Dist a -> Dist a -> Bool
forall a. Dist a -> Dist a -> Ordering
forall a. Dist a -> Dist a -> Dist a
min :: Dist a -> Dist a -> Dist a
$cmin :: forall a. Dist a -> Dist a -> Dist a
max :: Dist a -> Dist a -> Dist a
$cmax :: forall a. Dist a -> Dist a -> Dist a
>= :: Dist a -> Dist a -> Bool
$c>= :: forall a. Dist a -> Dist a -> Bool
> :: Dist a -> Dist a -> Bool
$c> :: forall a. Dist a -> Dist a -> Bool
<= :: Dist a -> Dist a -> Bool
$c<= :: forall a. Dist a -> Dist a -> Bool
< :: Dist a -> Dist a -> Bool
$c< :: forall a. Dist a -> Dist a -> Bool
compare :: Dist a -> Dist a -> Ordering
$ccompare :: forall a. Dist a -> Dist a -> Ordering
$cp1Ord :: forall a. Eq (Dist a)
Ord, Dist a -> ()
(Dist a -> ()) -> NFData (Dist a)
forall a. Dist a -> ()
forall a. (a -> ()) -> NFData a
rnf :: Dist a -> ()
$crnf :: forall a. Dist a -> ()
NFData) via (Matrix Prob () a)
type Countable a = KnownNat (I.Count a)
type CountableN a = KnownNat (I.Count (I.Normalize a))
type CountableDimensionsN a b = (CountableN a, CountableN b)
type FromListsN a b = I.FromLists Prob (I.Normalize a) (I.Normalize b)
type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Prob, Ord Prob)
type TrivialP a b = Normalize (a, b) ~ Normalize (Normalize a, Normalize b)
fmapD ::
( Liftable a b,
CountableDimensionsN a b,
FromListsN b a
)
=>
(a -> b) -> Dist a -> Dist b
fmapD :: (a -> b) -> Dist a -> Dist b
fmapD f :: a -> b
f (D m :: Matrix Prob () a
m) = Matrix Prob () b -> Dist b
forall a. Matrix Prob () a -> Dist a
D ((a -> b) -> Matrix Prob a b
forall e a b.
(Liftable e a b, CountableDimensionsN a b, FromListsN e b a) =>
(a -> b) -> Matrix e a b
fromF' a -> b
f Matrix Prob a b -> Matrix Prob () a -> Matrix Prob () b
forall e cr rows cols.
Num e =>
Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
`comp` Matrix Prob () a
m)
unitD :: Dist ()
unitD :: Dist ()
unitD = Matrix Prob () () -> Dist ()
forall a. Matrix Prob () a -> Dist a
D (Prob -> Matrix Prob () ()
forall e. e -> Matrix e () ()
one 1)
multD ::
( CountableDimensionsN a b,
CountableN (a, b),
FromListsN (a, b) a,
FromListsN (a, b) b,
TrivialP a b
) => Dist a -> Dist b -> Dist (a, b)
multD :: Dist a -> Dist b -> Dist (a, b)
multD (D a :: Matrix Prob () a
a) (D b :: Matrix Prob () b
b) = Matrix Prob () (a, b) -> Dist (a, b)
forall a. Matrix Prob () a -> Dist a
D (Matrix Prob () a -> Matrix Prob () b -> Matrix Prob () (a, b)
forall e cols a b.
(Num e, CountableDimensionsN a b, CountableN (a, b),
FromListsN e (a, b) a, FromListsN e (a, b) b, TrivialP a b) =>
Matrix e cols a -> Matrix e cols b -> Matrix e cols (a, b)
khatri Matrix Prob () a
a Matrix Prob () b
b)
selectD ::
( FromListsN b b,
CountableN b
) => Dist (Either a b) -> Matrix Prob a b -> Dist b
selectD :: Dist (Either a b) -> Matrix Prob a b -> Dist b
selectD (D d :: Matrix Prob () (Either a b)
d) m :: Matrix Prob a b
m = Matrix Prob () b -> Dist b
forall a. Matrix Prob () a -> Dist a
D (Matrix Prob () (Either a b) -> Matrix Prob a b -> Matrix Prob () b
forall e b cols a.
(Num e, FromListsN e b b, CountableN b) =>
Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
selectM Matrix Prob () (Either a b)
d Matrix Prob a b
m)
branchD ::
( Num e,
CountableDimensionsN a b,
CountableDimensionsN c (Either b c),
FromListsN c b,
FromListsN a b,
FromListsN a a,
FromListsN b b,
FromListsN c c,
FromListsN b a,
FromListsN b c,
FromListsN (Either b c) b,
FromListsN (Either b c) c
)
=> Dist (Either a b) -> Matrix Prob a c -> Matrix Prob b c -> Dist c
branchD :: Dist (Either a b) -> Matrix Prob a c -> Matrix Prob b c -> Dist c
branchD x :: Dist (Either a b)
x l :: Matrix Prob a c
l r :: Matrix Prob b c
r = Dist (Either a b) -> Dist (Either a (Either b c))
forall n a n.
(KnownNat (Count (Normalize n)), KnownNat (Count (Normalize a)),
KnownNat (Count (Normalize n)),
FromLists Prob (Normalize n) (Normalize n),
FromLists Prob (Normalize n) (Normalize a),
FromLists Prob (Normalize n) (Normalize n),
FromLists Prob (Normalize a) (Normalize a),
FromLists Prob (Normalize a) (Normalize n)) =>
Dist (Either a n) -> Dist (Either a (Either n n))
f Dist (Either a b)
x Dist (Either a (Either b c))
-> Matrix Prob a (Either b c) -> Dist (Either b c)
forall b a.
(FromListsN b b, CountableN b) =>
Dist (Either a b) -> Matrix Prob a b -> Dist b
`selectD` Matrix Prob a c -> Matrix Prob a (Either b c)
forall e cr m cols.
(Num e, KnownNat (Count (Normalize cr)),
KnownNat (Count (Normalize m)),
FromLists e (Normalize m) (Normalize cr),
FromLists e (Normalize cr) (Normalize cr)) =>
Matrix e cols cr -> Matrix e cols (Either m cr)
g Matrix Prob a c
l Dist (Either b c) -> Matrix Prob b c -> Dist c
forall b a.
(FromListsN b b, CountableN b) =>
Dist (Either a b) -> Matrix Prob a b -> Dist b
`selectD` Matrix Prob b c
r
where
f :: Dist (Either a n) -> Dist (Either a (Either n n))
f (D m :: Matrix Prob () (Either a n)
m) = Matrix Prob () (Either a (Either n n))
-> Dist (Either a (Either n n))
forall a. Matrix Prob () a -> Dist a
D (Matrix Prob (Either a n) a
-> Matrix Prob (Either a n) (Either n n)
-> Matrix Prob (Either a n) (Either a (Either n n))
forall e cols a b.
Matrix e cols a -> Matrix e cols b -> Matrix e cols (Either a b)
split (Matrix Prob a (Either a n) -> Matrix Prob (Either a n) a
forall e cols rows. Matrix e cols rows -> Matrix e rows cols
tr Matrix Prob a (Either a n)
forall e n m.
(Num e, CountableDimensionsN n m, FromListsN e n m,
FromListsN e m m) =>
Matrix e m (Either m n)
i1) (Matrix Prob n (Either n n)
forall e n m.
(Num e, CountableDimensionsN n m, FromListsN e n m,
FromListsN e m m) =>
Matrix e m (Either m n)
i1 Matrix Prob n (Either n n)
-> Matrix Prob (Either a n) n
-> Matrix Prob (Either a n) (Either n n)
forall e cr rows cols.
Num e =>
Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
`comp` Matrix Prob n (Either a n) -> Matrix Prob (Either a n) n
forall e cols rows. Matrix e cols rows -> Matrix e rows cols
tr Matrix Prob n (Either a n)
forall e n m.
(Num e, CountableDimensionsN n m, FromListsN e m n,
FromListsN e n n) =>
Matrix e n (Either m n)
i2) Matrix Prob (Either a n) (Either a (Either n n))
-> Matrix Prob () (Either a n)
-> Matrix Prob () (Either a (Either n n))
forall e cr rows cols.
Num e =>
Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
`comp` Matrix Prob () (Either a n)
m)
g :: Matrix e cols cr -> Matrix e cols (Either m cr)
g m :: Matrix e cols cr
m = Matrix e cr (Either m cr)
forall e n m.
(Num e, CountableDimensionsN n m, FromListsN e m n,
FromListsN e n n) =>
Matrix e n (Either m n)
i2 Matrix e cr (Either m cr)
-> Matrix e cols cr -> Matrix e cols (Either m cr)
forall e cr rows cols.
Num e =>
Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
`comp` Matrix e cols cr
m
ifD ::
( CountableDimensionsN a (Either () a),
FromListsN a a,
FromListsN a (),
FromListsN () a,
FromListsN (Either () a) a
)
=> Dist Bool -> Dist a -> Dist a -> Dist a
ifD :: Dist Bool -> Dist a -> Dist a -> Dist a
ifD x :: Dist Bool
x (D t :: Matrix Prob () a
t) (D e :: Matrix Prob () a
e) = Dist (Either () ())
-> Matrix Prob () a -> Matrix Prob () a -> Dist a
forall e a b c.
(Num e, CountableDimensionsN a b,
CountableDimensionsN c (Either b c), FromListsN c b,
FromListsN a b, FromListsN a a, FromListsN b b, FromListsN c c,
FromListsN b a, FromListsN b c, FromListsN (Either b c) b,
FromListsN (Either b c) c) =>
Dist (Either a b) -> Matrix Prob a c -> Matrix Prob b c -> Dist c
branchD Dist (Either () ())
x' Matrix Prob () a
t Matrix Prob () a
e
where
x' :: Dist (Either () ())
x' = Either () () -> Either () () -> Bool -> Either () ()
forall a. a -> a -> Bool -> a
bool (() -> Either () ()
forall a b. b -> Either a b
Right ()) (() -> Either () ()
forall a b. a -> Either a b
Left ()) (Bool -> Either () ()) -> Dist Bool -> Dist (Either () ())
forall a b.
(Liftable a b, CountableDimensionsN a b, FromListsN b a) =>
(a -> b) -> Dist a -> Dist b
`fmapD` Dist Bool
x
returnD :: forall a . (Enum a, FromListsN () a, Countable a) => a -> Dist a
returnD :: a -> Dist a
returnD a :: a
a = Matrix Prob () a -> Dist a
forall a. Matrix Prob () a -> Dist a
D ([Prob] -> Matrix Prob () a
forall e rows. FromListsN e () rows => [e] -> Matrix e () rows
col [Prob]
l)
where
i :: Int
i = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy (Count a) -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy (Count a)
forall k (t :: k). Proxy t
Proxy :: Proxy (Count a))
x :: Int
x = a -> Int
forall a. Enum a => a -> Int
fromEnum a
a
l :: [Prob]
l = Int -> [Prob] -> [Prob]
forall a. Int -> [a] -> [a]
take Int
x [0,0..] [Prob] -> [Prob] -> [Prob]
forall a. [a] -> [a] -> [a]
++ [1] [Prob] -> [Prob] -> [Prob]
forall a. [a] -> [a] -> [a]
++ Int -> [Prob] -> [Prob]
forall a. Int -> [a] -> [a]
take (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) [0,0..]
bindD :: Dist a -> Matrix Prob a b -> Dist b
bindD :: Dist a -> Matrix Prob a b -> Dist b
bindD (D d :: Matrix Prob () a
d) m :: Matrix Prob a b
m = Matrix Prob () b -> Dist b
forall a. Matrix Prob () a -> Dist a
D (Matrix Prob a b
m Matrix Prob a b -> Matrix Prob () a -> Matrix Prob () b
forall e cr rows cols.
Num e =>
Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
`comp` Matrix Prob () a
d)
(??) ::
( Enum a,
Countable a,
FromListsN () a
) => (a -> Bool) -> Dist a -> Prob
?? :: (a -> Bool) -> Dist a -> Prob
(??) p :: a -> Bool
p d :: Dist a
d =
let l :: [(a, Prob)]
l = Dist a -> [(a, Prob)]
forall a.
(Enum a, Countable a, FromListsN () a) =>
Dist a -> [(a, Prob)]
toValues Dist a
d
x :: [(a, Prob)]
x = ((a, Prob) -> Bool) -> [(a, Prob)] -> [(a, Prob)]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> Bool
p (a -> Bool) -> ((a, Prob) -> a) -> (a, Prob) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, Prob) -> a
forall a b. (a, b) -> a
fst) [(a, Prob)]
l
in [Prob] -> Prob
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Prob] -> Prob) -> ([(a, Prob)] -> [Prob]) -> [(a, Prob)] -> Prob
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, Prob) -> Prob) -> [(a, Prob)] -> [Prob]
forall a b. (a -> b) -> [a] -> [b]
map (a, Prob) -> Prob
forall a b. (a, b) -> b
snd ([(a, Prob)] -> Prob) -> [(a, Prob)] -> Prob
forall a b. (a -> b) -> a -> b
$ [(a, Prob)]
x
choose :: (FromListsN () a) => Prob -> Dist a
choose :: Prob -> Dist a
choose prob :: Prob
prob = Matrix Prob () a -> Dist a
forall a. Matrix Prob () a -> Dist a
D ([Prob] -> Matrix Prob () a
forall e rows. FromListsN e () rows => [e] -> Matrix e () rows
col [Prob
prob, 1 Prob -> Prob -> Prob
forall a. Num a => a -> a -> a
- Prob
prob])
shape :: (FromListsN () a) => (Prob -> Prob) -> [a] -> Dist a
shape :: (Prob -> Prob) -> [a] -> Dist a
shape _ [] = String -> Dist a
forall a. HasCallStack => String -> a
error "Probability.shape: empty list"
shape f :: Prob -> Prob
f xs :: [a]
xs =
let incr :: Prob
incr = 1 Prob -> Prob -> Prob
forall a. Fractional a => a -> a -> a
/ Int -> Prob
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)
ps :: [Prob]
ps = (Prob -> Prob) -> [Prob] -> [Prob]
forall a b. (a -> b) -> [a] -> [b]
map Prob -> Prob
f ((Prob -> Prob) -> Prob -> [Prob]
forall a. (a -> a) -> a -> [a]
iterate (Prob -> Prob -> Prob
forall a. Num a => a -> a -> a
+Prob
incr) 0)
in [(a, Prob)] -> Dist a
forall a. FromListsN () a => [(a, Prob)] -> Dist a
fromFreqs ([a] -> [Prob] -> [(a, Prob)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs [Prob]
ps)
linear :: (FromListsN () a) => [a] -> Dist a
linear :: [a] -> Dist a
linear = (Prob -> Prob) -> [a] -> Dist a
forall a. FromListsN () a => (Prob -> Prob) -> [a] -> Dist a
shape Prob -> Prob
forall a. a -> a
id
uniform :: (FromListsN () a) => [a] -> Dist a
uniform :: [a] -> Dist a
uniform = (Prob -> Prob) -> [a] -> Dist a
forall a. FromListsN () a => (Prob -> Prob) -> [a] -> Dist a
shape (Prob -> Prob -> Prob
forall a b. a -> b -> a
const 1)
negExp :: (FromListsN () a) => [a] -> Dist a
negExp :: [a] -> Dist a
negExp = (Prob -> Prob) -> [a] -> Dist a
forall a. FromListsN () a => (Prob -> Prob) -> [a] -> Dist a
shape (\x :: Prob
x -> Prob -> Prob
forall a. Floating a => a -> a
exp (-Prob
x))
normal :: (FromListsN () a) => [a] -> Dist a
normal :: [a] -> Dist a
normal = (Prob -> Prob) -> [a] -> Dist a
forall a. FromListsN () a => (Prob -> Prob) -> [a] -> Dist a
shape (Prob -> Prob -> Prob -> Prob
normalCurve 0.5 0.5)
toValues :: forall a . (Enum a, Countable a, FromListsN () a) => Dist a -> [(a, Prob)]
toValues :: Dist a -> [(a, Prob)]
toValues (D d :: Matrix Prob () a
d) =
let rows :: Int
rows = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy (Count a) -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy (Count a)
forall k (t :: k). Proxy t
Proxy :: Proxy (Count a)))
probs :: [Prob]
probs = Matrix Prob () a -> [Prob]
forall e cols rows. Matrix e cols rows -> [e]
toList Matrix Prob () a
d
res :: [(a, Prob)]
res = [a] -> [Prob] -> [(a, Prob)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> a
forall a. Enum a => Int -> a
toEnum [0..Int
rows]) [Prob]
probs
in [(a, Prob)]
res
prettyDist :: forall a. (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> String
prettyDist :: Dist a -> String
prettyDist d :: Dist a
d =
let values :: [(a, Prob)]
values = ((a, Prob) -> (a, Prob) -> Ordering) -> [(a, Prob)] -> [(a, Prob)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (\(a :: a
a, p1 :: Prob
p1) (b :: a
b, p2 :: Prob
p2) -> Prob -> Prob -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Prob
p2 Prob
p1) (Dist a -> [(a, Prob)]
forall a.
(Enum a, Countable a, FromListsN () a) =>
Dist a -> [(a, Prob)]
toValues @a Dist a
d)
w :: Int
w = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (((a, Prob) -> Int) -> [(a, Prob)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> Int) -> ((a, Prob) -> String) -> (a, Prob) -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show (a -> String) -> ((a, Prob) -> a) -> (a, Prob) -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, Prob) -> a
forall a b. (a, b) -> a
fst) [(a, Prob)]
values)
in ((a, Prob) -> String) -> [(a, Prob)] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
(\(x :: a
x,p :: Prob
p) -> Int -> a -> String
forall a p. Show a => p -> a -> String
showR Int
w a
x String -> ShowS
forall a. [a] -> [a] -> [a]
++ ' 'Char -> ShowS
forall a. a -> [a] -> [a]
: Prob -> String
forall a. (Show a, Num a) => a -> String
showProb Prob
p String -> ShowS
forall a. [a] -> [a] -> [a]
++ "\n")
[(a, Prob)]
values
where
showProb :: a -> String
showProb p :: a
p = a -> String
forall a. Show a => a -> String
show (a
p a -> a -> a
forall a. Num a => a -> a -> a
* 100) String -> ShowS
forall a. [a] -> [a] -> [a]
++ "%"
showR :: p -> a -> String
showR n :: p
n x :: a
x = a -> String
forall a. Show a => a -> String
show a
x String -> ShowS
forall a. [a] -> [a] -> [a]
++ " "
prettyPrintDist :: forall a . (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> IO ()
prettyPrintDist :: Dist a -> IO ()
prettyPrintDist = String -> IO ()
putStrLn (String -> IO ()) -> (Dist a -> String) -> Dist a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> String
forall a.
(Show a, Enum a, Countable a, FromListsN () a) =>
Dist a -> String
prettyDist @a
fromFreqs :: (FromListsN () a) => [(a,Prob)] -> Dist a
fromFreqs :: [(a, Prob)] -> Dist a
fromFreqs xs :: [(a, Prob)]
xs = Matrix Prob () a -> Dist a
forall a. Matrix Prob () a -> Dist a
D ([Prob] -> Matrix Prob () a
forall e rows. FromListsN e () rows => [e] -> Matrix e () rows
col (((a, Prob) -> Prob) -> [(a, Prob)] -> [Prob]
forall a b. (a -> b) -> [a] -> [b]
map (\(x :: a
x,p :: Prob
p) -> Prob
pProb -> Prob -> Prob
forall a. Fractional a => a -> a -> a
/Prob
q) [(a, Prob)]
xs))
where q :: Prob
q = [Prob] -> Prob
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Prob] -> Prob) -> [Prob] -> Prob
forall a b. (a -> b) -> a -> b
$ ((a, Prob) -> Prob) -> [(a, Prob)] -> [Prob]
forall a b. (a -> b) -> [a] -> [b]
map (a, Prob) -> Prob
forall a b. (a, b) -> b
snd [(a, Prob)]
xs
normalCurve :: Prob -> Prob -> Prob -> Prob
normalCurve :: Prob -> Prob -> Prob -> Prob
normalCurve mean :: Prob
mean dev :: Prob
dev x :: Prob
x =
let u :: Prob
u = (Prob
x Prob -> Prob -> Prob
forall a. Num a => a -> a -> a
- Prob
mean) Prob -> Prob -> Prob
forall a. Fractional a => a -> a -> a
/ Prob
dev
in Prob -> Prob
forall a. Floating a => a -> a
exp (-1Prob -> Prob -> Prob
forall a. Fractional a => a -> a -> a
/2 Prob -> Prob -> Prob
forall a. Num a => a -> a -> a
* Prob
uProb -> Int -> Prob
forall a b. (Num a, Integral b) => a -> b -> a
^(2::Int)) Prob -> Prob -> Prob
forall a. Fractional a => a -> a -> a
/ Prob -> Prob
forall a. Floating a => a -> a
sqrt (2 Prob -> Prob -> Prob
forall a. Num a => a -> a -> a
* Prob
forall a. Floating a => a
pi)