random-fu 0.2.1.1 → 0.2.2.0
raw patch · 2 files changed
+57/−35 lines, 2 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Data.Random.Distribution.Categorical: numEvents :: Categorical p a -> Int
+ Data.Random.Distribution.Categorical: totalWeight :: Num p => Categorical p a -> p
+ Data.Random.Distribution.Categorical: weightedCategorical :: (Fractional p, Eq p, Distribution (Categorical p) a) => [(p, a)] -> RVar a
+ Data.Random.Distribution.Categorical: weightedCategoricalT :: (Fractional p, Eq p, Distribution (Categorical p) a) => [(p, a)] -> RVarT m a
- Data.Random: class Distribution d t
+ Data.Random: class Distribution d t where rvar = rvarT rvarT d = lift (rvar d)
- Data.Random: class Monad m => MonadRandom m :: (* -> *)
+ Data.Random: class Monad m => MonadRandom (m :: * -> *)
- Data.Random: class Monad m => RandomSource m :: (* -> *) s
+ Data.Random: class Monad m => RandomSource (m :: * -> *) s
- Data.Random: data RVarT m :: (* -> *) a :: (* -> *) -> * -> *
+ Data.Random: data RVarT (m :: * -> *) a :: (* -> *) -> * -> *
- Data.Random.Distribution: class Distribution d t
+ Data.Random.Distribution: class Distribution d t where rvar = rvarT rvarT d = lift (rvar d)
- Data.Random.Distribution.Categorical: mapCategoricalPs :: (p -> q) -> Categorical p e -> Categorical q e
+ Data.Random.Distribution.Categorical: mapCategoricalPs :: (Num p, Num q) => (p -> q) -> Categorical p e -> Categorical q e
- Data.Random.RVar: data RVarT m :: (* -> *) a :: (* -> *) -> * -> *
+ Data.Random.RVar: data RVarT (m :: * -> *) a :: (* -> *) -> * -> *
Files
random-fu.cabal view
@@ -1,5 +1,5 @@ name: random-fu-version: 0.2.1.1+version: 0.2.2.0 stability: provisional cabal-version: >= 1.6@@ -28,6 +28,8 @@ comparable to other Haskell libraries, but still a fair bit slower than straight C implementations of the same algorithms.+ .+ Changes in 0.2.2.0: Bug fixes in Data.Random.Distribution.Categorical. . Changes in 0.2.1.1: Changed some one-field data types to newtypes, updated types for GHC 7.4's removal of Eq
src/Data/Random/Distribution/Categorical.hs view
@@ -6,7 +6,8 @@ module Data.Random.Distribution.Categorical ( Categorical , categorical, categoricalT- , fromList, toList+ , weightedCategorical, weightedCategoricalT+ , fromList, toList, totalWeight, numEvents , fromWeightedList, fromObservations , mapCategoricalPs, normalizeCategoricalPs , collectEvents, collectEventsBy@@ -39,6 +40,16 @@ categoricalT :: (Num p, Distribution (Categorical p) a) => [(p,a)] -> RVarT m a categoricalT = rvarT . fromList +-- |Construct a 'Categorical' random variable from a list of probabilities+-- and categories, where the probabilities all sum to 1.+weightedCategorical :: (Fractional p, Eq p, Distribution (Categorical p) a) => [(p,a)] -> RVar a+weightedCategorical = rvar . fromWeightedList++-- |Construct a 'Categorical' random process from a list of probabilities +-- and categories, where the probabilities all sum to 1.+weightedCategoricalT :: (Fractional p, Eq p, Distribution (Categorical p) a) => [(p,a)] -> RVarT m a+weightedCategoricalT = rvarT . fromWeightedList+ -- | Construct a 'Categorical' distribution from a list of weighted categories. {-# INLINE fromList #-} fromList :: (Num p) => [(p,a)] -> Categorical p a@@ -52,6 +63,14 @@ g x [] = [x] g x@(p0,_) ((p1, y):xs) = x : (p1-p0,y) : xs +totalWeight :: Num p => Categorical p a -> p+totalWeight (Categorical ds)+ | V.null ds = 0+ | otherwise = fst (V.last ds)++numEvents :: Categorical p a -> Int+numEvents (Categorical ds) = V.length ds+ -- |Construct a 'Categorical' distribution from a list of weighted categories, -- where the weights do not necessarily sum to 1. fromWeightedList :: (Fractional p, Eq p) => [(p,a)] -> Categorical p a@@ -165,44 +184,45 @@ (<*>) = ap -- |Like 'fmap', but for the probabilities of a categorical distribution.-mapCategoricalPs :: (p -> q) -> Categorical p e -> Categorical q e-mapCategoricalPs f (Categorical ds) = Categorical (V.map (first f) ds)+mapCategoricalPs :: (Num p, Num q) => (p -> q) -> Categorical p e -> Categorical q e+mapCategoricalPs f = fromList . map (first f) . toList -- |Adjust all the weights of a categorical distribution so that they -- sum to unity and remove all events whose probability is zero. normalizeCategoricalPs :: (Fractional p, Eq p) => Categorical p e -> Categorical p e-normalizeCategoricalPs orig@(Categorical ds) = - if V.null ds- then orig- else runST $ do- let n = V.length ds- lastP <- newSTRef 0- nDups <- newSTRef 0- normalized <- V.thaw ds- - let skip = modifySTRef' nDups (1+)- save i p x = do- d <- readSTRef nDups- MV.write normalized (i-d) (p, x)- - sequence_- [ do- let (p,x) = ds V.! i- p0 <- readSTRef lastP- if p == p0- then skip- else do- save i (p * scale) x- writeSTRef lastP $! p- | i <- [0..n-1]- ]- - -- force last element to 1- d <- readSTRef nDups- MV.write normalized (n-d-1) (1,lastX)- Categorical <$> V.unsafeFreeze (MV.unsafeSlice 0 (n-d) normalized)+normalizeCategoricalPs orig@(Categorical ds)+ | ps == 0 = Categorical V.empty+ | otherwise = runST $ do+ lastP <- newSTRef 0+ nDups <- newSTRef 0+ normalized <- V.thaw ds+ + let n = V.length ds+ skip = modifySTRef' nDups (1+)+ save i p x = do+ d <- readSTRef nDups+ MV.write normalized (i-d) (p, x)+ + sequence_+ [ do+ let (p,x) = ds V.! i+ p0 <- readSTRef lastP+ if p == p0+ then skip+ else do+ save i (p * scale) x+ writeSTRef lastP $! p+ | i <- [0..n-1]+ ]+ + -- force last element to 1+ d <- readSTRef nDups+ let n' = n-d+ (_,lastX) <- MV.read normalized (n'-1)+ MV.write normalized (n'-1) (1,lastX)+ Categorical <$> V.unsafeFreeze (MV.unsafeSlice 0 n' normalized) where- (ps, lastX) = V.last ds+ ps = totalWeight orig scale = recip ps -- |strict 'modifySTRef'