-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Probabilistic Functional Programming -- -- The Library allows exact computation with discrete random variables in -- terms of their distributions by using a monad. The monad is similar to -- the List monad for non-deterministic computations, but extends the -- List monad by a measure of probability. Small interface to R plotting. @package probability @version 0.2.1 -- | Collection of some shapes of distribution. module Numeric.Probability.Shape -- | A shape is a mapping from the interval [0,1] to non-negative -- numbers. They need not to be normalized (sum up to 1) because this is -- done by subsequent steps. (It would also be impossible to normalize -- the function in a way that each discretization is normalized as well.) type T prob = prob -> prob linear :: (Fractional prob) => T prob uniform :: (Fractional prob) => T prob negExp :: (Floating prob) => T prob normal :: (Floating prob) => T prob normalCurve :: (Floating prob) => prob -> prob -> prob -> prob -- | Deterministic and probabilistic values module Numeric.Probability.Distribution type Event a = a -> Bool oneOf :: (Eq a) => [a] -> Event a just :: (Eq a) => a -> Event a -- | Probability disribution -- -- The underlying data structure is a list. Unfortunately we cannot use a -- more efficient data structure because the key type must be of class -- Ord, but the Monad class does not allow constraints for -- result types. The Monad instance is particularly useful because many -- generic monad functions make sense here, monad transformers can be -- used and the monadic design allows to simulate probabilistic games in -- an elegant manner. -- -- We have the same problem like making Data.Set an instance of -- Monad, see -- http://www.randomhacks.net/articles/2007/03/15/data-set-monad-haskell-macros -- -- If you need efficiency, you should remove redundant elements by -- norm. norm converts to Data.Map and back -- internally and you can hope that the compiler fuses the lists with the -- intermediate Map structure. newtype T prob a Cons :: [(a, prob)] -> T prob a decons :: T prob a -> [(a, prob)] certainly :: (Num prob) => a -> T prob a errorMargin :: (RealFloat prob) => prob -- | Check whether two distributions are equal when neglecting rounding -- errors. We do not want to put this into an Eq instance, since -- it is not exact equivalence and it seems to be too easy to mix it up -- with liftM2 (==) x y. approx :: (RealFloat prob, Ord a) => T prob a -> T prob a -> Bool lift :: (Num prob) => ([(a, prob)] -> [(a, prob)]) -> T prob a -> T prob a size :: T prob a -> Int check :: (RealFloat prob) => T prob a -> T prob a -- | can fail because of rounding errors, better use fromFreqs cons :: (RealFloat prob) => [(a, prob)] -> T prob a sumP :: (Num prob) => [(a, prob)] -> prob sortP :: (Ord prob) => [(a, prob)] -> [(a, prob)] sortElem :: (Ord a) => [(a, prob)] -> [(a, prob)] norm :: (Num prob, Ord a) => T prob a -> T prob a norm' :: (Num prob, Ord a) => [(a, prob)] -> [(a, prob)] norm'' :: (Num prob, Ord a) => [(a, prob)] -> [(a, prob)] -- | pretty printing pretty :: (Ord a, Show a, Num prob, Ord prob) => (prob -> String) -> T prob a -> String (//%) :: (Ord a, Show a) => T Rational a -> () -> IO () -- | distribution generators type Spread prob a = [a] -> T prob a choose :: (Num prob) => prob -> a -> a -> T prob a enum :: (Fractional prob) => [Int] -> Spread prob a -- | Give a list of frequencies, they do not need to sum up to 1. relative :: (Fractional prob) => [prob] -> Spread prob a shape :: (Fractional prob) => (prob -> prob) -> Spread prob a linear :: (Fractional prob) => Spread prob a uniform :: (Fractional prob) => Spread prob a negExp :: (Floating prob) => Spread prob a normal :: (Floating prob) => Spread prob a -- | extracting and mapping the domain of a distribution extract :: T prob a -> [a] -- | fmap with normalization map :: (Num prob, Ord b) => (a -> b) -> T prob a -> T prob b -- | unfold a distribution of distributions into one distribution, this is -- join with normalization. unfold :: (Num prob, Ord a) => T prob (T prob a) -> T prob a -- | conditional distribution cond :: (Num prob) => T prob Bool -> T prob a -> T prob a -> T prob a truth :: (Num prob) => T prob Bool -> prob -- | conditional probability, identical to Dist.filter (?=<<) :: (Fractional prob) => (a -> Bool) -> T prob a -> T prob a -- | Dist.filter in infix form. Can be considered an additional -- monadic combinator, which can be used where you would want -- Control.Monad.guard otherwise. (>>=?) :: (Fractional prob) => T prob a -> (a -> Bool) -> T prob a -- | filtering distributions data Select a Case :: a -> Select a Other :: Select a above :: (Num prob, Ord prob, Ord a) => prob -> T prob a -> T prob (Select a) fromFreqs :: (Fractional prob) => [(a, prob)] -> T prob a filter :: (Fractional prob) => (a -> Bool) -> T prob a -> T prob a -- | selecting from distributions selectP :: (Num prob, Ord prob) => T prob a -> prob -> a scanP :: (Num prob, Ord prob) => prob -> [(a, prob)] -> a (??) :: (Num prob) => Event a -> T prob a -> prob -- | expectation value expected :: (Num a) => T a a -> a -- | statistical analyses variance :: (Num a) => T a a -> a stdDev :: (Floating a) => T a a -> a instance (Eq a) => Eq (Select a) instance (Ord a) => Ord (Select a) instance (Show a) => Show (Select a) instance (Num prob, Ord prob, Ord a, Fractional a) => Fractional (T prob a) instance (Num prob, Ord prob, Ord a, Num a) => Num (T prob a) instance Eq (T prob a) instance (Num prob, Ord prob, Ord a, Show a) => Show (T prob a) instance Functor (T prob) instance (Num prob) => Monad (T prob) -- | Deterministic and probabilistic generators module Numeric.Probability.Transition -- | deterministic generator type Change a = a -> a -- | probabilistic generator type T prob a = a -> T prob a id :: (Num prob) => T prob a -- | map maps a change function to the result of a transformation -- (map is somehow a lifted form of map) The restricted -- type of f results from the fact that the argument to -- t cannot be changed to b in the result T -- type. map :: (Num prob, Ord a) => Change a -> T prob a -> T prob a -- | unfold a distribution of transitions into one transition -- -- NOTE: The argument transitions must be independent unfold :: (Num prob, Ord a) => T prob (T prob a) -> T prob a -- | Composition of transitions similar to -- Numeric.Probability.Monad.compose but with intermediate -- duplicate elimination. compose :: (Num prob, Ord a) => [T prob a] -> T prob a -- | functions to convert a list of changes into a transition type SpreadC prob a = [Change a] -> T prob a apply :: (Num prob) => Change a -> T prob a maybe :: (Num prob) => prob -> Change a -> T prob a lift :: Spread prob a -> SpreadC prob a uniform :: (Fractional prob) => SpreadC prob a linear :: (Fractional prob) => SpreadC prob a normal :: (Floating prob) => SpreadC prob a enum :: (RealFloat prob) => [Int] -> SpreadC prob a relative :: (RealFloat prob) => [prob] -> SpreadC prob a -- | functions to convert a list of transitions into a transition type SpreadT prob a = [T prob a] -> T prob a liftT :: (Num prob, Ord a) => Spread prob (T prob a) -> SpreadT prob a uniformT :: (Fractional prob, Ord a) => SpreadT prob a linearT :: (Fractional prob, Ord a) => SpreadT prob a normalT :: (Floating prob, Ord a) => SpreadT prob a enumT :: (RealFloat prob, Ord a) => [Int] -> SpreadT prob a relativeT :: (RealFloat prob, Ord a) => [prob] -> SpreadT prob a module Numeric.Probability.Example.Alarm type Probability = Rational type Dist a = T Probability a type PBool = T Probability Bool flp :: Probability -> PBool -- | prior burglary 1% b :: PBool -- | prior earthquake 0.1% e :: PBool -- | conditional probability of alarm given burglary and earthquake a :: Bool -> Bool -> PBool -- | conditional probability of john calling given alarm j :: Bool -> PBool -- | conditional probability of mary calling given alarm m :: Bool -> PBool -- | calculate the full joint distribution data Burglary B :: Bool -> Bool -> Bool -> Bool -> Bool -> Burglary burglary :: Burglary -> Bool earthquake :: Burglary -> Bool alarm :: Burglary -> Bool john :: Burglary -> Bool mary :: Burglary -> Bool bJoint :: Dist Burglary -- | what is the probability that mary calls given that john calls? pmj :: Probability instance Eq Burglary instance Ord Burglary instance Show Burglary -- | Approach: model a node with k predecessors as a function with k -- parameters module Numeric.Probability.Example.Bayesian type Probability = Rational type Dist a = T Probability a type State a = [a] type PState a = Dist (State a) type STrans a = State a -> PState a type SPred a = a -> State a -> Bool event :: Probability -> a -> STrans a happens :: (Eq a) => SPred a network :: [STrans a] -> PState a source :: Probability -> a -> STrans a bin :: (Eq a) => a -> a -> Probability -> Probability -> Probability -> Probability -> a -> STrans a -- | Two possible causes for one effect data Nodes A :: Nodes B :: Nodes E :: Nodes g :: PState Nodes aE :: Probability bE :: Probability e :: Probability instance Eq Nodes instance Ord Nodes instance Show Nodes -- | Consider a family of two children. Given that there is a boy in the -- family, what is the probability that there are two boys in the family? module Numeric.Probability.Example.Boys type Probability = Rational type Dist a = T Probability a data Child Boy :: Child Girl :: Child type Family = (Child, Child) birth :: Dist Child family :: Dist Family allBoys :: Event Family existsBoy :: Event Family familyWithBoy :: Dist Family twoBoys :: Probability countBoy :: Child -> Int countBoys :: Family -> Int numBoys :: Dist Int instance Eq Child instance Ord Child instance Show Child -- | You take part in a screening test for a disease that you have with a -- probability pDisease. The test can fail in two ways: If you are -- ill, the test says with probability pFalseNegative that you are -- healthy. If you are healthy, it says with probability -- pFalsePositive that you are ill. -- -- Now consider the test is positive - what is the probability that you -- are indeed ill? module Numeric.Probability.Example.Diagnosis type Probability = Rational type Dist a = T Probability a data State Healthy :: State Ill :: State data Finding Negative :: Finding Positive :: Finding pFalseNegative :: Probability pFalsePositive :: Probability pDisease :: Probability dist :: Dist (State, Finding) -- | Alternative way for computing the distribution. It is usually more -- efficient because we do not need to switch on the healthy state. distAlt :: Dist (State, Finding) p :: Probability instance Eq Finding instance Ord Finding instance Show Finding instance Enum Finding instance Eq State instance Ord State instance Show State instance Enum State module Numeric.Probability.Example.Dice type Die = Int type Probability = Rational type Dist = T Probability die :: Dist Die -- | product of independent distributions twoDice :: Dist (Die, Die) dice :: Int -> Dist [Die] twoSixes :: Probability -- | sixes p n computes the probability of getting p sixes -- (>1, ==2, ...) when rolling n dice sixes :: (Int -> Bool) -> Int -> Probability droll :: Dist Die g3 :: Probability addTwo :: Dist Die -- | Ceneralization of Numeric.Probability.Example.Boys -- -- Consider a family of n children. Given that there are k boys in the -- family, what is the probability that there are m boys in the family? module Numeric.Probability.Example.NBoys type Family = [Child] family :: Int -> Dist Family countBoys :: Family -> Int boys :: Int -> Event Family nBoys :: Int -> Int -> Int -> Probability numBoys :: Int -> Int -> Dist Int -- | only boys in a family that has one boy onlyBoys1 :: Int -> Probability -- | Randomized values module Numeric.Probability.Random -- | Random values newtype T a Cons :: State StdGen a -> T a decons :: T a -> State StdGen a randomR :: (Random a) => (a, a) -> T a -- | Run random action in IO monad. run :: T a -> IO a -- | Run random action without IO using a seed. runSeed :: StdGen -> T a -> a print :: (Show a) => T a -> IO () pick :: (Num prob, Ord prob, Random prob) => T prob a -> T a -- | Randomized distribution type Distribution prob a = T (T prob a) above :: (Num prob, Ord prob, Ord a) => prob -> Distribution prob a -> Distribution prob (Select a) -- | dist converts a list of randomly generated values into a -- distribution by taking equal weights for all values dist :: (Fractional prob, Ord a) => [T a] -> Distribution prob a -- | random change type Change a = a -> T a change :: (Num prob, Ord prob, Random prob) => T prob a -> Change a -- | random transition type Transition prob a = a -> Distribution prob a type ApproxDist a = T [a] instance Functor T instance Monad T -- | Tracing module Numeric.Probability.Trace type Trace a = [a] type Walk a = a -> Trace a type Space prob a = Trace (T prob a) type Expand prob a = a -> Space prob a -- | walk is a bounded version of the predefined function iterate walk :: Int -> Change a -> Walk a type RTrace a = T (Trace a) type RWalk a = a -> RTrace a type RSpace prob a = T (Space prob a) type RExpand prob a = a -> RSpace prob a -- | merge converts a list of RTraces into a list of -- randomized distributions, i.e., an RSpace, by creating a -- randomized distribution for each list position across all traces merge :: (Fractional prob, Ord a) => [RTrace a] -> RSpace prob a zipListWith :: ([a] -> b) -> [[a]] -> [b] -- | Number type based on Float with formatting in percents. module Numeric.Probability.Percentage newtype T Cons :: Float -> T percent :: Float -> T showPfix :: (RealFrac prob) => Int -> prob -> String roundRel :: (RealFrac a) => Int -> a -> a -- | Print distribution as table with configurable precision. (//) :: (Ord a, Show a) => Dist a -> Int -> IO () liftP :: (Float -> Float) -> T -> T liftP2 :: (Float -> Float -> Float) -> T -> T -> T type Dist a = T T a type Spread a = [a] -> Dist a type RDist a = T (Dist a) type Trans a = a -> Dist a type Space a = Trace (Dist a) type Expand a = a -> Space a type RTrans a = a -> RDist a type RSpace a = T (Space a) type RExpand a = a -> RSpace a instance Eq T instance Ord T instance Random T instance Floating T instance Fractional T instance Num T instance Show T module Numeric.Probability.Expectation class ToFloat a toFloat :: (ToFloat a) => a -> Float class FromFloat a fromFloat :: (FromFloat a) => Float -> a class Expected a expected :: (Expected a) => a -> Float floatDist :: (ToFloat prob, Expected a) => T prob a -> T Float Float -- | statistical analyses variance :: (Expected a) => Dist a -> Float stdDev :: (Expected a) => Dist a -> Float instance (ToFloat prob, Expected a) => Expected (T prob a) instance (Expected a) => Expected [a] instance Expected Integer instance Expected Int instance Expected Float instance FromFloat Integer instance FromFloat Int instance FromFloat Float instance ToFloat T instance ToFloat Integer instance ToFloat Int instance ToFloat Float -- | Simulation module Numeric.Probability.Simulation -- | Simulation means to repeat a Rnd.change change many times and to -- accumulate all results into a distribution. Therefore, simulation can -- be regarded as an approximation of distributions through -- randomization. -- -- The Sim class allows the overloading of simulation for different kinds -- of generators, namely transitions and Rnd.change changes: -- --
Trans a = a -> Dist a ==> c = Dist
RChange a = a -> Rnd.T a ==> c = Rnd.T = IO