-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Fast Splittable PRNG
--   
--   Pure Haskell implementation of SplitMix described in
--   
--   Guy L. Steele, Jr., Doug Lea, and Christine H. Flood. 2014. Fast
--   splittable pseudorandom number generators. In Proceedings of the 2014
--   ACM International Conference on Object Oriented Programming Systems
--   Languages &amp; Applications (OOPSLA '14). ACM, New York, NY, USA,
--   453-472. DOI: <a>https://doi.org/10.1145/2660193.2660195</a>
--   
--   The paper describes a new algorithm <i>SplitMix</i> for
--   <i>splittable</i> pseudorandom number generator that is quite fast: 9
--   64 bit arithmetic/logical operations per 64 bits generated.
--   
--   <i>SplitMix</i> is tested with two standard statistical test suites
--   (DieHarder and TestU01, this implementation only using the former) and
--   it appears to be adequate for "everyday" use, such as Monte Carlo
--   algorithms and randomized data structures where speed is important.
--   
--   In particular, it <b>should not be used for cryptographic or security
--   applications</b>, because generated sequences of pseudorandom values
--   are too predictable (the mixing functions are easily inverted, and two
--   successive outputs suffice to reconstruct the internal state).
@package splitmix
@version 0.0.4


-- | <i>SplitMix</i> is a splittable pseudorandom number generator (PRNG)
--   that is quite fast.
--   
--   Guy L. Steele, Jr., Doug Lea, and Christine H. Flood. 2014. Fast
--   splittable pseudorandom number generators. In Proceedings of the 2014
--   ACM International Conference on Object Oriented Programming Systems
--   Languages &amp; Applications (OOPSLA '14). ACM, New York, NY, USA,
--   453-472. DOI: <a>https://doi.org/10.1145/2660193.2660195</a>
--   
--   The paper describes a new algorithm <i>SplitMix</i> for
--   <i>splittable</i> pseudorandom number generator that is quite fast: 9
--   64 bit arithmetic/logical operations per 64 bits generated.
--   
--   <i>SplitMix</i> is tested with two standard statistical test suites
--   (DieHarder and TestU01, this implementation only using the former) and
--   it appears to be adequate for "everyday" use, such as Monte Carlo
--   algorithms and randomized data structures where speed is important.
--   
--   In particular, it <b>should not be used for cryptographic or security
--   applications</b>, because generated sequences of pseudorandom values
--   are too predictable (the mixing functions are easily inverted, and two
--   successive outputs suffice to reconstruct the internal state).
--   
--   Note: This module supports all GHCs since GHC-7.0.4, but GHC-7.0 and
--   GHC-7.2 have slow implementation, as there are no native
--   <a>popCount</a>.
module System.Random.SplitMix

-- | SplitMix generator state.
data SMGen

-- | Generate a <a>Word64</a>.
--   
--   <pre>
--   &gt;&gt;&gt; take 3 $ map (printf "%x") $ unfoldr (Just . nextWord64) (mkSMGen 1337) :: [String]
--   ["b5c19e300e8b07b3","d600e0e216c0ac76","c54efc3b3cc5af29"]
--   </pre>
nextWord64 :: SMGen -> (Word64, SMGen)

-- | Generate <a>Word32</a> by truncating <a>nextWord64</a>.
nextWord32 :: SMGen -> (Word32, SMGen)

-- | Generate two <a>Word32</a>.
nextTwoWord32 :: SMGen -> (Word32, Word32, SMGen)

-- | Generate an <a>Int</a>.
nextInt :: SMGen -> (Int, SMGen)

-- | Generate a <a>Double</a> in <tt>[0, 1)</tt> range.
--   
--   <pre>
--   &gt;&gt;&gt; take 8 $ map (printf "%0.3f") $ unfoldr (Just . nextDouble) (mkSMGen 1337) :: [String]
--   ["0.710","0.836","0.771","0.409","0.297","0.527","0.589","0.067"]
--   </pre>
nextDouble :: SMGen -> (Double, SMGen)

-- | Generate a <a>Float</a> in <tt>[0, 1)</tt> range.
--   
--   <pre>
--   &gt;&gt;&gt; take 8 $ map (printf "%0.3f") $ unfoldr (Just . nextFloat) (mkSMGen 1337) :: [String]
--   ["0.057","0.089","0.237","0.383","0.680","0.320","0.826","0.007"]
--   </pre>
nextFloat :: SMGen -> (Float, SMGen)

-- | Split a generator into a two uncorrelated generators.
splitSMGen :: SMGen -> (SMGen, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word32</a>.
bitmaskWithRejection32 :: Word32 -> SMGen -> (Word32, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word32</a>.
bitmaskWithRejection32' :: Word32 -> SMGen -> (Word32, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word64</a>.
--   
--   <tt>bitmaskWithRejection64 w64</tt> generates random numbers in
--   closed-open range of <tt>[0, w64)</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; take 20 $ unfoldr (Just . bitmaskWithRejection64 5) (mkSMGen 1337)
--   [3,1,4,1,2,3,1,1,0,3,4,2,3,0,2,3,3,4,1,0]
--   </pre>
bitmaskWithRejection64 :: Word64 -> SMGen -> (Word64, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word64</a>.
--   
--   <tt>bitmaskWithRejection64' w64</tt> generates random numbers in
--   closed-closed range of <tt>[0, w64]</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; take 20 $ unfoldr (Just . bitmaskWithRejection64' 5) (mkSMGen 1337)
--   [3,1,4,1,2,3,1,1,0,3,4,5,2,3,0,2,3,5,3,4]
--   </pre>
bitmaskWithRejection64' :: Word64 -> SMGen -> (Word64, SMGen)

-- | Preferred way to deterministically construct <a>SMGen</a>.
--   
--   <pre>
--   &gt;&gt;&gt; mkSMGen 42
--   SMGen 9297814886316923340 13679457532755275413
--   </pre>
mkSMGen :: Word64 -> SMGen

-- | Initialize <a>SMGen</a> using system time.
initSMGen :: IO SMGen

-- | Derive a new generator instance from the global <a>SMGen</a> using
--   <a>splitSMGen</a>.
newSMGen :: IO SMGen

-- | Create <a>SMGen</a> using seed and gamma.
--   
--   <pre>
--   &gt;&gt;&gt; seedSMGen 2 2
--   SMGen 2 3
--   </pre>
seedSMGen :: Word64 -> Word64 -> SMGen

-- | Like <a>seedSMGen</a> but takes a pair.
seedSMGen' :: (Word64, Word64) -> SMGen

-- | Extract current state of <a>SMGen</a>.
unseedSMGen :: SMGen -> (Word64, Word64)
instance GHC.Show.Show System.Random.SplitMix.SMGen
instance Control.DeepSeq.NFData System.Random.SplitMix.SMGen
instance GHC.Read.Read System.Random.SplitMix.SMGen
instance System.Random.RandomGen System.Random.SplitMix.SMGen


-- | <i>SplitMix</i> is a splittable pseudorandom number generator (PRNG)
--   that is quite fast.
--   
--   This is 32bit variant (original one is 32 bit).
--   
--   You <b>really don't want to use this one</b>.
--   
--   Note: This module supports all GHCs since GHC-7.0.4, but GHC-7.0 and
--   GHC-7.2 have slow implementation, as there are no native
--   <a>popCount</a>.
module System.Random.SplitMix32

-- | SplitMix generator state.
data SMGen

-- | Generate a <a>Word32</a>.
--   
--   <pre>
--   &gt;&gt;&gt; take 3 $ map (printf "%x") $ unfoldr (Just . nextWord32) (mkSMGen 1337) :: [String]
--   ["e0cfe722","a6ced0f0","c3a6d889"]
--   </pre>
nextWord32 :: SMGen -> (Word32, SMGen)

-- | Generate a <a>Word64</a>, by generating to <a>Word32</a>s.
nextWord64 :: SMGen -> (Word64, SMGen)

-- | Generate two <a>Word32</a>.
nextTwoWord32 :: SMGen -> (Word32, Word32, SMGen)

-- | Generate an <a>Int</a>.
nextInt :: SMGen -> (Int, SMGen)

-- | Generate a <a>Double</a> in <tt>[0, 1)</tt> range.
--   
--   <pre>
--   &gt;&gt;&gt; take 8 $ map (printf "%0.3f") $ unfoldr (Just . nextDouble) (mkSMGen 1337) :: [String]
--   ["0.878","0.764","0.063","0.845","0.262","0.490","0.176","0.544"]
--   </pre>
nextDouble :: SMGen -> (Double, SMGen)

-- | Generate a <a>Float</a> in <tt>[0, 1)</tt> range.
--   
--   <pre>
--   &gt;&gt;&gt; take 8 $ map (printf "%0.3f") $ unfoldr (Just . nextFloat) (mkSMGen 1337) :: [String]
--   ["0.878","0.652","0.764","0.631","0.063","0.180","0.845","0.645"]
--   </pre>
nextFloat :: SMGen -> (Float, SMGen)

-- | Split a generator into a two uncorrelated generators.
splitSMGen :: SMGen -> (SMGen, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word32</a>.
bitmaskWithRejection32 :: Word32 -> SMGen -> (Word32, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word32</a>.
bitmaskWithRejection32' :: Word32 -> SMGen -> (Word32, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word64</a>.
--   
--   <tt>bitmaskWithRejection64 w64</tt> generates random numbers in
--   closed-open range of <tt>[0, w64)</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; take 20 $ unfoldr (Just . bitmaskWithRejection64 5) (mkSMGen 1337)
--   [0,2,4,2,1,4,2,4,2,2,3,0,3,2,2,2,3,1,2,2]
--   </pre>
bitmaskWithRejection64 :: Word64 -> SMGen -> (Word64, SMGen)

-- | <i>Bitmask with rejection</i> method of generating subrange of
--   <a>Word64</a>.
--   
--   <tt>bitmaskWithRejection64' w64</tt> generates random numbers in
--   closed-closed range of <tt>[0, w64]</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; take 20 $ unfoldr (Just . bitmaskWithRejection64' 5) (mkSMGen 1337)
--   [0,2,4,2,1,4,2,4,5,5,2,2,5,3,5,0,3,2,2,2]
--   </pre>
bitmaskWithRejection64' :: Word64 -> SMGen -> (Word64, SMGen)

-- | Preferred way to deterministically construct <a>SMGen</a>.
--   
--   <pre>
--   &gt;&gt;&gt; mkSMGen 42
--   SMGen 142593372 1604540297
--   </pre>
mkSMGen :: Word32 -> SMGen

-- | Initialize <a>SMGen</a> using system time.
initSMGen :: IO SMGen

-- | Derive a new generator instance from the global <a>SMGen</a> using
--   <a>splitSMGen</a>.
newSMGen :: IO SMGen

-- | Create <a>SMGen</a> using seed and gamma.
--   
--   <pre>
--   &gt;&gt;&gt; seedSMGen 2 2
--   SMGen 2 3
--   </pre>
seedSMGen :: Word32 -> Word32 -> SMGen

-- | Like <a>seedSMGen</a> but takes a pair.
seedSMGen' :: (Word32, Word32) -> SMGen

-- | Extract current state of <a>SMGen</a>.
unseedSMGen :: SMGen -> (Word32, Word32)
instance GHC.Show.Show System.Random.SplitMix32.SMGen
instance Control.DeepSeq.NFData System.Random.SplitMix32.SMGen
instance GHC.Read.Read System.Random.SplitMix32.SMGen
instance System.Random.RandomGen System.Random.SplitMix32.SMGen
