packages feed

buffon-machines 1.1.0.0 → 1.1.1.0

raw patch · 2 files changed

+34/−35 lines, 2 filesdep +mtlPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: mtl

API changes (from Hackage documentation)

- Data.Buffon.Machine: BuffonMachine :: (Rand g -> (a, Rand g)) -> BuffonMachine g a
- Data.Buffon.Machine: [runR] :: BuffonMachine g a -> Rand g -> (a, Rand g)
- Data.Buffon.Machine: instance GHC.Base.Applicative (Data.Buffon.Machine.BuffonMachine g)
- Data.Buffon.Machine: instance GHC.Base.Functor (Data.Buffon.Machine.BuffonMachine g)
- Data.Buffon.Machine: instance GHC.Base.Monad (Data.Buffon.Machine.BuffonMachine g)
- Data.Buffon.Machine: newtype BuffonMachine g a
+ Data.Buffon.Machine: type BuffonMachine g a = State (Rand g) a

Files

Data/Buffon/Machine.hs view
@@ -34,22 +34,22 @@  References: - [1] Ph. Flajolet, M. Pelletier, M. Soria : “On Buffon Machines and Numbers”,-     SODA'11 - ACM/SIAM Symposium on Discrete Algorithms, San Francisco, USA,-     pp. 172-183, (Society for Industrial and Applied Mathematics) (2011)+[1] Ph. Flajolet, M. Pelletier, M. Soria : “On Buffon Machines and Numbers”,+    SODA'11 - ACM/SIAM Symposium on Discrete Algorithms, San Francisco, USA,+    pp. 172-183, (Society for Industrial and Applied Mathematics) (2011) - [2] J. Lumbroso : "Optimal Discrete Uniform Generation-     from Coin Flips, and Applications".+[2] J. Lumbroso : "Optimal Discrete Uniform Generation+    from Coin Flips, and Applications". - [3] D. Knuth, A. Yao : "The complexity of nonuniform random number generation",-     in Algorithms and Complexity: New Directions and Recent Results,-     Academic Press, (1976)+[3] D. Knuth, A. Yao : "The complexity of nonuniform random number generation",+    in Algorithms and Complexity: New Directions and Recent Results,+    Academic Press, (1976)  -} {-# LANGUAGE BangPatterns, DeriveLift #-} module Data.Buffon.Machine     ( -- * Buffon machines and related utilities.       Rand(..), empty, init-    , BuffonMachine(..), runRIO+    , BuffonMachine, runRIO     , histogram, histogramIO     , samples, samplesIO, samplesIO' @@ -89,6 +89,7 @@ import qualified Prelude as P  import Control.Monad+import Control.Monad.State.Strict  import Data.Bits import Data.Word (Word32)@@ -114,6 +115,7 @@ --   In other words, if a buffer refill is required. empty :: Rand g -> Bool empty rng = counter rng == 32+{-# INLINE empty #-}  -- | A fresh RBG. init :: RandomGen g => g -> Rand g@@ -121,31 +123,17 @@           (x, g') -> Rand { buffer  = x                           , counter = 0                           , oracle  = g' }+{-# INLINE init #-}  -- | Computations consuming random bits using RBGs. --   Note that the implementation is essentially a State monad, --   passing RNG throughout its computations.-newtype BuffonMachine g a =-    BuffonMachine { runR :: Rand g -> (a, Rand g) }--instance Functor (BuffonMachine g) where-    fmap = liftM--instance Applicative (BuffonMachine g) where-    pure  = return-    (<*>) = ap--instance Monad (BuffonMachine g) where-    return x = BuffonMachine $ \ !rng -> (x, rng)-    (BuffonMachine f) >>= h =-        BuffonMachine $ \ !rng ->-            case f rng of-              (x, !rng') -> runR (h x) rng'+type BuffonMachine g a = State (Rand g) a  -- | Runs the given Buffon machine within the IO monad --    using StdGen as its random bit oracle. runRIO :: BuffonMachine StdGen a -> IO a-runRIO m = fst . runR m . init <$> getStdGen+runRIO m = evalState m . init <$> getStdGen  samples' :: RandomGen g         => BuffonMachine g a -> Int -> [a]@@ -202,11 +190,6 @@ histogramIO :: BuffonMachine StdGen Int -> Int ->  IO () histogramIO m n = runRIO (histogram m n) >>= print -mkFlip :: Rand g -> (Bool, Rand g)-mkFlip !rng =-    (testBit (buffer rng) (counter rng), -- test the respective bit.-        rng { counter = succ (counter rng) })- -- | Bernoulli variables. type Bern g = BuffonMachine g Bool @@ -220,12 +203,21 @@     return $ if b then 1                   else 0 +oracle' :: RandomGen g => Rand g -> Rand g+oracle' rng+    | empty rng = init (oracle rng)+    | otherwise = rng+{-# INLINE oracle' #-}+ -- | Random coin flip. Note that the implementation --   handles the regeneration of the RBG, see 'Rand'. flip :: RandomGen g => Bern g-flip = BuffonMachine $ \ !rng ->-    mkFlip $ if empty rng then init (oracle rng)-                          else rng+flip = do+    modify' oracle'+    rng <- get+    put $ rng { counter = succ (counter rng) }+    return $ testBit (buffer rng) (counter rng) -- test respective bit.+{-# INLINE flip #-}  -- | Fair variant of flip. Implements the following, standard trick. --   Use 'flip' twice and continue if and only if both coin@@ -633,6 +625,9 @@     heads <- flip     choice' heads x +{-# SPECIALISE choice ::+        DecisionTree Int -> BuffonMachine StdGen Int #-}+ choice' :: RandomGen g         =>  Bool -> DecisionTree a -> BuffonMachine g a @@ -644,3 +639,6 @@ choice' False (Toss lt _) = do     heads <- flip     choice' heads lt++{-# SPECIALISE choice' ::+        Bool -> DecisionTree Int -> BuffonMachine StdGen Int #-}
buffon-machines.cabal view
@@ -1,5 +1,5 @@ name:           buffon-machines-version:        1.1.0.0+version:        1.1.1.0 synopsis:       Perfect simulation of discrete random variables description:    Monadic implementation of Buffon machines meant for perfect simulation of discrete random variables homepage:       https://github.com/maciej-bendkowski/buffon-machines#readme@@ -17,6 +17,7 @@   exposed-modules: Data.Buffon.Machine   build-depends:   random >= 1.1                  , multiset >= 0.3.3+                 , mtl >= 2.2.1                  , template-haskell >= 2.11.1.0                  , base >=4.7 && <5   ghc-options:   -O2