module Statistics.Probability where
import Control.DeepSeq
import Control.Lens
import Data.Aeson
import Data.Char (chr)
import Data.Vector.Unboxed.Deriving
import Data.Vector.Unboxed (Unbox)
import GHC.Generics(Generic)
import Numeric.Log
import Algebra.Structure.Semiring
import Numeric.LogDomain
import Numeric.Limits
data IsNormalized = Normalized | NotNormalized
newtype Probability (n ∷ IsNormalized) x = Prob { Probability n x -> x
getProb ∷ x }
deriving (Probability n x -> Probability n x -> Bool
(Probability n x -> Probability n x -> Bool)
-> (Probability n x -> Probability n x -> Bool)
-> Eq (Probability n x)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (n :: IsNormalized) x.
Eq x =>
Probability n x -> Probability n x -> Bool
/= :: Probability n x -> Probability n x -> Bool
$c/= :: forall (n :: IsNormalized) x.
Eq x =>
Probability n x -> Probability n x -> Bool
== :: Probability n x -> Probability n x -> Bool
$c== :: forall (n :: IsNormalized) x.
Eq x =>
Probability n x -> Probability n x -> Bool
Eq,Eq (Probability n x)
Eq (Probability n x)
-> (Probability n x -> Probability n x -> Ordering)
-> (Probability n x -> Probability n x -> Bool)
-> (Probability n x -> Probability n x -> Bool)
-> (Probability n x -> Probability n x -> Bool)
-> (Probability n x -> Probability n x -> Bool)
-> (Probability n x -> Probability n x -> Probability n x)
-> (Probability n x -> Probability n x -> Probability n x)
-> Ord (Probability n x)
Probability n x -> Probability n x -> Bool
Probability n x -> Probability n x -> Ordering
Probability n x -> Probability n x -> Probability n x
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 (n :: IsNormalized) x. Ord x => Eq (Probability n x)
forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Bool
forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Ordering
forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Probability n x
min :: Probability n x -> Probability n x -> Probability n x
$cmin :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Probability n x
max :: Probability n x -> Probability n x -> Probability n x
$cmax :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Probability n x
>= :: Probability n x -> Probability n x -> Bool
$c>= :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Bool
> :: Probability n x -> Probability n x -> Bool
$c> :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Bool
<= :: Probability n x -> Probability n x -> Bool
$c<= :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Bool
< :: Probability n x -> Probability n x -> Bool
$c< :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Bool
compare :: Probability n x -> Probability n x -> Ordering
$ccompare :: forall (n :: IsNormalized) x.
Ord x =>
Probability n x -> Probability n x -> Ordering
$cp1Ord :: forall (n :: IsNormalized) x. Ord x => Eq (Probability n x)
Ord,Int -> Probability n x -> ShowS
[Probability n x] -> ShowS
Probability n x -> String
(Int -> Probability n x -> ShowS)
-> (Probability n x -> String)
-> ([Probability n x] -> ShowS)
-> Show (Probability n x)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (n :: IsNormalized) x.
Show x =>
Int -> Probability n x -> ShowS
forall (n :: IsNormalized) x. Show x => [Probability n x] -> ShowS
forall (n :: IsNormalized) x. Show x => Probability n x -> String
showList :: [Probability n x] -> ShowS
$cshowList :: forall (n :: IsNormalized) x. Show x => [Probability n x] -> ShowS
show :: Probability n x -> String
$cshow :: forall (n :: IsNormalized) x. Show x => Probability n x -> String
showsPrec :: Int -> Probability n x -> ShowS
$cshowsPrec :: forall (n :: IsNormalized) x.
Show x =>
Int -> Probability n x -> ShowS
Show,ReadPrec [Probability n x]
ReadPrec (Probability n x)
Int -> ReadS (Probability n x)
ReadS [Probability n x]
(Int -> ReadS (Probability n x))
-> ReadS [Probability n x]
-> ReadPrec (Probability n x)
-> ReadPrec [Probability n x]
-> Read (Probability n x)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall (n :: IsNormalized) x. Read x => ReadPrec [Probability n x]
forall (n :: IsNormalized) x. Read x => ReadPrec (Probability n x)
forall (n :: IsNormalized) x.
Read x =>
Int -> ReadS (Probability n x)
forall (n :: IsNormalized) x. Read x => ReadS [Probability n x]
readListPrec :: ReadPrec [Probability n x]
$creadListPrec :: forall (n :: IsNormalized) x. Read x => ReadPrec [Probability n x]
readPrec :: ReadPrec (Probability n x)
$creadPrec :: forall (n :: IsNormalized) x. Read x => ReadPrec (Probability n x)
readList :: ReadS [Probability n x]
$creadList :: forall (n :: IsNormalized) x. Read x => ReadS [Probability n x]
readsPrec :: Int -> ReadS (Probability n x)
$creadsPrec :: forall (n :: IsNormalized) x.
Read x =>
Int -> ReadS (Probability n x)
Read,(forall x. Probability n x -> Rep (Probability n x) x)
-> (forall x. Rep (Probability n x) x -> Probability n x)
-> Generic (Probability n x)
forall x. Rep (Probability n x) x -> Probability n x
forall x. Probability n x -> Rep (Probability n x) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (n :: IsNormalized) x x.
Rep (Probability n x) x -> Probability n x
forall (n :: IsNormalized) x x.
Probability n x -> Rep (Probability n x) x
$cto :: forall (n :: IsNormalized) x x.
Rep (Probability n x) x -> Probability n x
$cfrom :: forall (n :: IsNormalized) x x.
Probability n x -> Rep (Probability n x) x
Generic)
instance (NFData x) ⇒ NFData (Probability n x)
derivingUnbox "Probability"
[t| forall n x. Unbox x ⇒ Probability n x → x |] [| getProb |] [| Prob |]
deriving instance (Enum x) ⇒ Enum (Probability n x)
deriving instance (Num x) ⇒ Num (Probability n x)
deriving instance (Fractional x) ⇒ Fractional (Probability n x)
deriving instance (Floating x) ⇒ Floating (Probability n x)
deriving instance (Real x) ⇒ Real (Probability n x)
deriving instance (RealFrac x) ⇒ RealFrac (Probability n x)
deriving instance (RealFloat x) ⇒ RealFloat (Probability n x)
instance ToJSON x ⇒ ToJSON (Probability n x) where
toJSON :: Probability n x -> Value
toJSON = x -> Value
forall a. ToJSON a => a -> Value
toJSON (x -> Value) -> (Probability n x -> x) -> Probability n x -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Probability n x -> x
forall (n :: IsNormalized) x. Probability n x -> x
getProb
instance FromJSON x ⇒ FromJSON (Probability n x) where
parseJSON :: Value -> Parser (Probability n x)
parseJSON = (x -> Probability n x) -> Parser x -> Parser (Probability n x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap x -> Probability n x
forall (n :: IsNormalized) x. x -> Probability n x
Prob (Parser x -> Parser (Probability n x))
-> (Value -> Parser x) -> Value -> Parser (Probability n x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser x
forall a. FromJSON a => Value -> Parser a
parseJSON
instance (Num r) ⇒ Semiring (Probability n r) where
plus :: Probability n r -> Probability n r -> Probability n r
plus = Probability n r -> Probability n r -> Probability n r
forall a. Num a => a -> a -> a
(+)
times :: Probability n r -> Probability n r -> Probability n r
times = Probability n r -> Probability n r -> Probability n r
forall a. Num a => a -> a -> a
(*)
zero :: Probability n r
zero = Probability n r
0
one :: Probability n r
one = Probability n r
1
{-# Inline plus #-}
{-# Inline times #-}
{-# Inline zero #-}
{-# Inline one #-}
prob ∷ (Ord x, Num x, Show x) ⇒ x → Probability Normalized x
prob :: x -> Probability 'Normalized x
prob x
x
| x
x x -> x -> Bool
forall a. Ord a => a -> a -> Bool
>= x
0 Bool -> Bool -> Bool
&& x
x x -> x -> Bool
forall a. Ord a => a -> a -> Bool
<= x
1 = x -> Probability 'Normalized x
forall (n :: IsNormalized) x. x -> Probability n x
Prob x
x
| Bool
otherwise = String -> Probability 'Normalized x
forall a. HasCallStack => String -> a
error (String -> Probability 'Normalized x)
-> String -> Probability 'Normalized x
forall a b. (a -> b) -> a -> b
$ x -> String
forall a. Show a => a -> String
show x
x String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" not in range of [0,...,1]"
{-# Inline prob #-}
prob' ∷ (Ord x, Num x, Show x) ⇒ x → Probability NotNormalized x
prob' :: x -> Probability 'NotNormalized x
prob' = x -> Probability 'NotNormalized x
forall (n :: IsNormalized) x. x -> Probability n x
Prob
{-# Inline prob' #-}
probabilityToChar ∷ (Num k, RealFrac k) ⇒ Probability Normalized k → Char
probabilityToChar :: Probability 'Normalized k -> Char
probabilityToChar (Prob k
p')
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10 = Char
'*'
| Bool
otherwise = Int -> Char
chr (Int -> Char) -> Int -> Char
forall a b. (a -> b) -> a -> b
$ Int
48 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i
where p :: k
p = k -> k -> k
forall a. Ord a => a -> a -> a
max k
0.0 (k -> k) -> k -> k
forall a b. (a -> b) -> a -> b
$ k -> k -> k
forall a. Ord a => a -> a -> a
min k
p' k
1.0
i :: Int
i = k -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (k -> Int) -> k -> Int
forall a b. (a -> b) -> a -> b
$ k
p k -> k -> k
forall a. Num a => a -> a -> a
* k
10