module Numeric.Probability.Transition where
import qualified Numeric.Probability.Distribution as Dist
import qualified Data.List as List
import Prelude hiding (map, maybe, id, )
type Change a = a -> a
type T prob a = a -> Dist.T prob a
id :: (Num prob) => T prob a
id = Dist.certainly
map :: (Num prob, Ord a) =>
Change a -> T prob a -> T prob a
map f t = Dist.map f . t
unfold :: (Num prob, Ord a) =>
Dist.T prob (T prob a) -> T prob a
unfold d x = Dist.unfold (fmap ($x) d)
compose :: (Num prob, Ord a) =>
[T prob a] -> T prob a
compose = foldl (\acc x v -> Dist.norm (acc v >>= x)) return
type SpreadC prob a = [Change a] -> T prob a
apply :: (Num prob) =>
Change a -> T prob a
apply f = id . f
maybe :: (Num prob) => prob -> Change a -> T prob a
maybe p f x = Dist.choose p (f x) x
lift :: Dist.Spread prob a -> SpreadC prob a
lift s cs x = s $ List.map ($ x) cs
uniform :: (Fractional prob) => SpreadC prob a
uniform = lift Dist.uniform
linear :: (Fractional prob) => SpreadC prob a
linear = lift Dist.linear
normal :: (Floating prob) => SpreadC prob a
normal = lift Dist.normal
enum :: (RealFloat prob) => [Int] -> SpreadC prob a
enum xs = lift (Dist.enum xs)
relative :: (RealFloat prob) => [prob] -> SpreadC prob a
relative xs = lift (Dist.relative xs)
type SpreadT prob a = [T prob a] -> T prob a
liftT :: (Num prob, Ord a) =>
Dist.Spread prob (T prob a) -> SpreadT prob a
liftT s = unfold . s
uniformT :: (Fractional prob, Ord a) => SpreadT prob a
uniformT = liftT Dist.uniform
linearT :: (Fractional prob, Ord a) => SpreadT prob a
linearT = liftT Dist.linear
normalT :: (Floating prob, Ord a) => SpreadT prob a
normalT = liftT Dist.normal
enumT :: (RealFloat prob, Ord a) => [Int] -> SpreadT prob a
enumT xs = liftT (Dist.enum xs)
relativeT :: (RealFloat prob, Ord a) => [prob] -> SpreadT prob a
relativeT xs = liftT (Dist.relative xs)