packages feed

splitmix-distributions 1.0.0 → 1.1.0

raw patch · 4 files changed

+45/−7 lines, 4 files

Files

ChangeLog.md view
@@ -1,3 +1,9 @@+1.1++- add sampleRunT and samplesRunT: both return the final state of the PRNG as a tuple of Word64+- add unit test that asserts that sample runs are deterministic given the same starting PRNG state+- + 1.0  - add MonadReader r (GenT m) instance
README.md view
@@ -1,5 +1,7 @@ # splitmix-distributions +[![Haskell CI](https://github.com/ocramz/splitmix-distributions/actions/workflows/ci.yaml/badge.svg)](https://github.com/ocramz/splitmix-distributions/actions/workflows/ci.yaml)+ Random samplers for some common distributions, as well as a convenient interface for composing them, based on `splitmix`.  
splitmix-distributions.cabal view
@@ -1,5 +1,5 @@ name:           splitmix-distributions-version:        1.0.0+version:        1.1.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@@ -12,7 +12,7 @@ license-file:   LICENSE build-type:     Simple cabal-version:  >= 1.10-tested-with:    GHC == 8.6.5, GHC == 8.10.4+tested-with:    GHC == 8.6.5, GHC == 8.10.4, GHC == 9.6.6 extra-source-files:     README.md     ChangeLog.md@@ -35,6 +35,7 @@                   , splitmix                   , transformers   default-language: Haskell2010+  ghc-options: -Wall  test-suite test   type: exitcode-stdio-1.0@@ -44,10 +45,6 @@   ghc-options: -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5-    , erf     , hspec-    , mtl-    , splitmix     , splitmix-distributions-    , transformers   default-language: Haskell2010
src/System/Random/SplitMix/Distributions.hs view
@@ -58,10 +58,14 @@   zipf,   crp,   -- * PRNG+  SMGenState,   -- ** Pure   Gen, sample, samples,   -- ** Monadic   GenT, sampleT, samplesT,+  -- *** Return final PRNG state+  sampleRunT,+  samplesRunT,   -- ** IO-based   sampleIO, samplesIO,   -- ** splitmix utilities@@ -70,6 +74,7 @@  import Control.Monad (replicateM) import Control.Monad.IO.Class (MonadIO(..))+import Data.Bifunctor (second) import Data.Foldable (toList) import Data.Functor.Identity (Identity(..)) import Data.List (findIndex)@@ -87,7 +92,7 @@ import Control.Monad.Reader (MonadReader(..)) import Control.Monad.State (MonadState(..), modify) -- splitmix-import System.Random.SplitMix (SMGen, mkSMGen, initSMGen, unseedSMGen, splitSMGen, nextDouble)+import System.Random.SplitMix (SMGen, mkSMGen, seedSMGen', initSMGen, unseedSMGen, splitSMGen, nextDouble) -- transformers import Control.Monad.Trans.Reader (ReaderT(..)) import Control.Monad.Trans.State (StateT(..), runStateT, evalStateT, State, runState, evalState)@@ -115,6 +120,16 @@         -> m a sampleT seed gg = evalStateT (unGen gg) (mkSMGen seed) +-- | Sample in a monadic context, returning the final PRNG state as well+--+-- This makes it possible to have deterministic chains of invocations, for reproducible results+sampleRunT :: (Functor m) =>+              SMGenState -- ^ random seed+           -> GenT m a+           -> m (a, SMGenState) -- ^ (result, final PRNG state)+sampleRunT seed gg = second unseedSMGen <$> runStateT (unGen gg) (seedSMGen' seed)++ -- | Initialize a splitmix random generator from system entropy (current time etc.) and sample from the PRNG. sampleIO :: MonadIO m => GenT m b -> m b sampleIO gg = do@@ -128,6 +143,24 @@          -> GenT m a          -> m [a] samplesT n seed gg = sampleT seed (replicateM n gg)++-- | Sample a batch in a monadic context, returning the final PRNG state as well+--+-- Same as @n@ repeated invocations of `sampleRunT`, while threading the PRNG state.+samplesRunT :: Monad m =>+               Int -- ^ size of sample+            -> SMGenState -- ^ random seed+            -> GenT m a+            -> m ([a], SMGenState) -- ^ (result, final PRNG state)+samplesRunT n seed gg = second unseedSMGen <$> runStateT (replicateM n $ unGen gg) (seedSMGen' seed)++-- | Internal state of the splitmix PRNG.+--+-- This representation has the benefit of being serializable (e.g. can be passed back and forth between API calls)+type SMGenState = (Word64, Word64)++-- getSeed :: SMGen -> Word64+-- getSeed = fst . unseedSMGen  -- | Initialize a splitmix random generator from system entropy (current time etc.) and sample n times from the PRNG. samplesIO :: MonadIO m => Int -> GenT m a -> m [a]