summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryanOSullivan <>2009-09-19 20:07:27 (GMT)
committerLuite Stegeman <luite@luite.com>2009-09-19 20:07:27 (GMT)
commit16bffc0c348e80c50f3a8781635d1ddcc04c839c (patch)
tree9acfe234d3ee5dbc4ef6f4d9cbc7c802f5362bb3
parent911a3ea12c7145feb107285e77d6dd78db1455e1 (diff)
version 0.3.30.3.3
-rw-r--r--Statistics/RandomVariate.hs38
-rw-r--r--statistics.cabal2
2 files changed, 33 insertions, 7 deletions
diff --git a/Statistics/RandomVariate.hs b/Statistics/RandomVariate.hs
index f9aa4d1..e32328c 100644
--- a/Statistics/RandomVariate.hs
+++ b/Statistics/RandomVariate.hs
@@ -14,6 +14,7 @@ module Statistics.RandomVariate
(
-- * Types
Gen
+ , Seed
, Variate(..)
-- * Other distributions
, normal
@@ -21,6 +22,9 @@ module Statistics.RandomVariate
, create
, initialize
, withSystemRandom
+ -- * State management
+ , save
+ , restore
-- * Helper functions
, uniformArray
-- * References
@@ -74,6 +78,10 @@ class Variate a where
--
-- * The range of random 'Integer' variates is the same as for
-- 'Int'.
+ --
+ -- To generate a 'Float' variate with a range of [0,1), subtract
+ -- 2**(-33). To do the same with 'Double' variates, subtract
+ -- 2**(-53).
uniform :: Gen s -> ST s a
-- Thanks to Duncan Coutts for finding the pattern below for
@@ -171,20 +179,20 @@ wordToBool i = (i .&. 1) /= 0
{-# INLINE wordToBool #-}
wordToFloat :: Word32 -> Float
-wordToFloat x = (fromIntegral i * m_inv_32) + 0.5 + m_inv_33
+wordToFloat x = (fromIntegral i * m_inv_32) + 0.5 + m_inv_33
where m_inv_33 = 1.16415321826934814453125e-10
m_inv_32 = 2.3283064365386962890625e-10
- i = fromIntegral x :: Int32
+ i = fromIntegral x :: Int32
{-# INLINE wordToFloat #-}
wordsToDouble :: Word32 -> Word32 -> Double
-wordsToDouble x y = (fromIntegral a * m_inv_32 + (0.5 + m_inv_53) +
- fromIntegral (b .&. 0xFFFFF) * m_inv_52)
+wordsToDouble x y = (fromIntegral a * m_inv_32 + (0.5 + m_inv_53) +
+ fromIntegral (b .&. 0xFFFFF) * m_inv_52)
where m_inv_52 = 2.220446049250313080847263336181640625e-16
m_inv_53 = 1.1102230246251565404236316680908203125e-16
m_inv_32 = 2.3283064365386962890625e-10
- a = fromIntegral x :: Int32
- b = fromIntegral y :: Int32
+ a = fromIntegral x :: Int32
+ b = fromIntegral y :: Int32
{-# INLINE wordsToDouble #-}
-- | State of the pseudo-random number generator.
@@ -231,6 +239,24 @@ initialize seed = do
fini = lengthU seed
{-# INLINE initialize #-}
+-- | An immutable snapshot of the state of a 'Gen'.
+newtype Seed = Seed (UArr Word32)
+ deriving (Eq, Read, Show)
+
+-- | Save the state of a 'Gen', for later use by 'restore'.
+save :: Gen s -> ST s Seed
+save (Gen q) = Seed `fmap` unsafeFreezeAllMU q
+{-# INLINE save #-}
+
+-- | Create a new 'Gen' that mirrors the state of a saved 'Seed'.
+restore :: Seed -> ST s (Gen s)
+restore (Seed s) = newMU n >>= fill
+ where fill q = go 0 where
+ go !i | i >= n = return (Gen q)
+ | otherwise = writeMU q i (indexU s i) >> go (i+1)
+ n = lengthU s
+{-# INLINE restore #-}
+
-- | Using the current time as a seed, perform an action that uses a
-- random variate generator. This is a horrible fallback for Windows
-- systems.
diff --git a/statistics.cabal b/statistics.cabal
index 4354f1b..e038c54 100644
--- a/statistics.cabal
+++ b/statistics.cabal
@@ -1,5 +1,5 @@
name: statistics
-version: 0.3.2
+version: 0.3.3
synopsis: A library of statistical types, data, and functions
description:
This library provides a number of common functions and types useful