-- 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.4 -- | 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 Map and back internally -- and you can hope that the compiler fuses the lists with the -- intermediate Map structure. -- -- The defined monad is equivalent to WriterT (Product prob) [] -- a. See -- http://www.randomhacks.net/articles/2007/02/21/refactoring-probability-distributions. 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, Show prob) => T prob a -> T prob a -- | can fail because of rounding errors, better use fromFreqs cons :: (RealFloat prob, Show 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 () equal :: (Num prob, Eq prob, Ord a) => T prob a -> T prob a -> Bool -- | 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 filter (?=<<) :: Fractional prob => (a -> Bool) -> T prob a -> T prob a -- | filter in infix form. Can be considered an additional monadic -- combinator, which can be used where you would want 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 mapMaybe :: Fractional prob => (a -> Maybe b) -> T prob a -> T prob b -- | 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, Show prob, Ord a, Show a) => Show (T prob a) instance Functor (T prob) instance Num prob => Applicative (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 compose but with -- intermediate duplicate elimination. compose :: (Num prob, Ord a) => [T prob a] -> T prob a untilLeft :: (Num prob, Ord a, Ord b) => (a -> T prob (Either b a)) -> T prob a -> T prob b -- | In fix $ go a -> do ...; go xy any action after a -- go is ignored. fix :: (Num prob, Ord a, Ord b) => ((a -> EitherT a (T prob) b) -> (a -> EitherT a (T prob) b)) -> T prob a -> T prob b -- | 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 e, bE, aE :: 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 pDisease, pFalsePositive, pFalseNegative :: 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 State instance Ord State instance Show State instance Enum State instance Eq Finding instance Ord Finding instance Show Finding instance Enum Finding 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 -- | The newspaper Sueddeutsche asked their readers what professions -- 16 persons have, by only showing the photographies of them and three -- choices. -- -- Their statistics was: 22% readers had 0 to 5 correct answers (category -- 0) 75% readers had 6 to 11 correct answers (category 1) 3% readers had -- 12 to 16 correct answers (category 2) -- -- Can this statistics be explained with random guessing, or is there -- some information in the photographies that the readers could utilize? -- -- I got 6 correct answers. module Numeric.Probability.Example.Profession type Probability = Double type Dist a = T Probability a correctAnswers :: Dist Int categories :: Dist Int -- | 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. Thus dist -- (replicate n rnd) simulates rnd n times and -- returns an estimation of the distribution represented by rnd. 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 Applicative T 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, Show 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 () (//*) :: (Ord a, Show a) => Dist a -> (Int, 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