packages feed

splitmix-distributions 0.3.0.0 → 0.4.0.0

raw patch · 3 files changed

+80/−7 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ System.Random.SplitMix.Distributions: categorical :: (Monad m, Foldable t) => t Double -> GenT m (Maybe Int)
+ System.Random.SplitMix.Distributions: discrete :: (Monad m, Foldable t) => t (Double, b) -> GenT m (Maybe b)
+ System.Random.SplitMix.Distributions: samples :: Int -> Word64 -> Gen a -> [a]
+ System.Random.SplitMix.Distributions: samplesT :: Monad m => Int -> Word64 -> GenT m a -> m [a]
+ System.Random.SplitMix.Distributions: zipf :: (Monad m, Integral i) => Double -> GenT m i

Files

ChangeLog.md view
@@ -1,3 +1,7 @@+0.4 :++- add Discrete, Categorical, Zipf-Mandelbrot distributions+ 0.3 :  - type signatures of all generators are now parametrized over some Monad m rather than Identity. This allows for more flexibility on the use site.
splitmix-distributions.cabal view
@@ -1,5 +1,5 @@ name:           splitmix-distributions-version:        0.3.0.0+version:        0.4.0.0 description:    Random samplers for some common distributions, as well as a convenient interface for composing them, based on splitmix. Please see the README on GitHub at <https://github.com/ocramz/splitmix-distributions#readme> homepage:       https://github.com/ocramz/splitmix-distributions#readme bug-reports:    https://github.com/ocramz/splitmix-distributions/issues
src/System/Random/SplitMix/Distributions.hs view
@@ -45,11 +45,14 @@   -- ** Discrete   bernoulli, fairCoin,   multinomial,+  categorical,+  discrete,+  zipf,   -- * PRNG   -- ** Pure-  Gen, sample,+  Gen, sample, samples,   -- ** Monadic-  GenT, sampleT,+  GenT, sampleT, samplesT,   withGen                                             ) where @@ -80,18 +83,33 @@ -- | Pure random generation type Gen = GenT Identity --- | Monadic evaluation+-- | Sample in a monadic context sampleT :: Monad m =>-            Word64 -- ^ random seed-         -> GenT m a -> m a+           Word64 -- ^ random seed+        -> GenT m a+        -> m a sampleT seed gg = evalStateT (unGen gg) (mkSMGen seed) --- | Pure evaluation+-- | Sample a batch+samplesT :: Monad m =>+            Int -- ^ size of sample+         -> Word64 -- ^ random seed+         -> GenT m a+         -> m [a]+samplesT n seed gg = sampleT seed (replicateM n gg)++-- | Pure sampling sample :: Word64 -- ^ random seed         -> Gen a         -> a sample seed gg = evalState (unGen gg) (mkSMGen seed) +-- | Sample a batch+samples :: Int -- ^ sample size+        -> Word64 -- ^ random seed+        -> Gen a+        -> [a]+samples n seed gg = sample seed (replicateM n gg)  -- | Bernoulli trial bernoulli :: Monad m =>@@ -123,6 +141,57 @@     runningTotals xs = let adds = scanl1 (+) xs in (adds, sum xs) {-# INLINABLE multinomial #-} ++-- | Categorical distribution+--+-- Picks one index out of a discrete set with probability proportional to those supplied as input parameter vector+categorical :: (Monad m, Foldable t) =>+               t Double -- ^ probability vector \( p_i \gt 0 , \forall i \) (does not need to be normalized)+            -> GenT m (Maybe Int)+categorical ps = do+  xs <- multinomial 1 ps+  case xs of+    Just [x] -> pure $ Just x+    _ -> pure Nothing+++-- | The Zipf-Mandelbrot distribution.+--+--  Note that values of the parameter close to 1 are very computationally intensive.+--+--  >>> samples 10 1234 (zipf 1.1)+--  [3170051793,2,668775891,146169301649651,23,36,5,6586194257347,21,37911]+--+--  >>> samples 10 1234 (zipf 1.5)+--  [79,1,58,680,3,1,2,1,366,1]+zipf :: (Monad m, Integral i) =>+        Double -- ^ \( \alpha \gt 1 \)+     -> GenT m i+zipf a = do+  let+    b = 2 ** (a - 1)+    go = do+        u <- stdUniform+        v <- stdUniform+        let xInt = floor (u ** (- 1 / (a - 1)))+            x = fromIntegral xInt+            t = (1 + 1 / x) ** (a - 1)+        if v * x * (t - 1) / (b - 1) <= t / b+          then return xInt+          else go+  go+{-# INLINABLE zipf #-}++-- | Discrete distribution+--+-- Pick one item with probability proportional to those supplied as input parameter vector+discrete :: (Monad m, Foldable t) =>+            t (Double, b) -- ^ (probability, item) vector \( p_i \gt 0 , \forall i \) (does not need to be normalized)+         -> GenT m (Maybe b)+discrete d = do+  let (ps, xs) = unzip (toList d)+  midx <- categorical ps+  pure $ (xs !!) <$> midx  -- | Uniform between two values uniformR :: Monad m =>