module System.Random.Random123.RandomGen (
mkCustomCBRNG32,
mkCustomCBRNG64,
restoreCustomCBRNG32,
restoreCustomCBRNG64,
mkCBRNG32,
mkCBRNG64,
restoreCBRNG32,
restoreCBRNG64,
CBRNG32,
CBRNG64,
CustomCBRNG32,
CustomCBRNG64,
CBRNGState,
SerializableCBRNG(..)
) where
import System.Random
import Data.Word
import System.Random.Random123.Types
import System.Random.Random123.Philox
data CustomCBRNG32 k c = CustomCBRNG32 (k -> c -> c) k c Int
data CustomCBRNG64 k c = CustomCBRNG64 (k -> c -> c) k c Int
data CBRNG32 = CBRNG32 (Array2 Word32) (Array4 Word32) Int deriving (Eq, Show, Read)
data CBRNG64 = CBRNG64 (Array2 Word64) (Array4 Word64) Int deriving (Eq, Show, Read)
next32 :: (Counter c, Word32Array c) => (c -> c) -> c -> Int -> (Int, c, Int)
next32 bijection ctr wctr = (fromIntegral w32, ctr', wctr') where
arr = bijection ctr
w32 = getWord32 wctr arr
(ctr', wctr') = if wctr + 1 < numWords32 arr
then (ctr, wctr + 1)
else (increment ctr, 0)
genRange32 :: (Int, Int)
genRange32 = (0, min maxBound (2^32 1))
next64 :: (Counter c, Word64Array c) => (c -> c) -> c -> Int -> (Int, c, Int)
next64 bijection ctr wctr = (fromIntegral w64, ctr', wctr') where
arr = bijection ctr
w64 = getWord64 wctr arr
(ctr', wctr') = if wctr + 1 < numWords64 arr
then (ctr, wctr + 1)
else (increment ctr, 0)
genRange64 :: (Int, Int)
genRange64 = (0, min maxBound (2^64 1))
instance (Counter c, Word32Array c) => RandomGen (CustomCBRNG32 k c) where
next (CustomCBRNG32 bijection key ctr wctr) = (res, new_gen) where
(res, ctr', wctr') = next32 (bijection key) ctr wctr
new_gen = CustomCBRNG32 bijection key ctr' wctr'
genRange _ = genRange32
split (CustomCBRNG32 bijection key ctr _) = (gen', gen'') where
ctr' = increment ctr
ctr'' = bijection key ctr'
gen' = CustomCBRNG32 bijection key ctr' 0
gen'' = CustomCBRNG32 bijection key ctr'' 0
instance (Counter c, Word64Array c) => RandomGen (CustomCBRNG64 k c) where
next (CustomCBRNG64 bijection key ctr wctr) = (res, new_gen) where
(res, ctr', wctr') = next64 (bijection key) ctr wctr
new_gen = CustomCBRNG64 bijection key ctr' wctr'
genRange _ = genRange64
split (CustomCBRNG64 bijection key ctr _) = (gen', gen'') where
ctr' = increment ctr
ctr'' = bijection key ctr'
gen' = CustomCBRNG64 bijection key ctr' 0
gen'' = CustomCBRNG64 bijection key ctr'' 0
instance RandomGen CBRNG32 where
next (CBRNG32 key ctr wctr) = (res, new_gen) where
(res, ctr', wctr') = next32 (philox4 key) ctr wctr
new_gen = CBRNG32 key ctr' wctr'
genRange _ = genRange32
split (CBRNG32 key ctr _) = (gen', gen'') where
ctr' = increment ctr
ctr'' = philox4 key ctr'
gen' = CBRNG32 key ctr' 0
gen'' = CBRNG32 key ctr'' 0
instance RandomGen CBRNG64 where
next (CBRNG64 key ctr wctr) = (res, new_gen) where
(res, ctr', wctr') = next64 (philox4 key) ctr wctr
new_gen = CBRNG64 key ctr' wctr'
genRange _ = genRange64
split (CBRNG64 key ctr _) = (gen', gen'') where
ctr' = increment ctr
ctr'' = philox4 key ctr'
gen' = CBRNG64 key ctr' 0
gen'' = CBRNG64 key ctr'' 0
data CBRNGState = CBRNGState Integer Integer Int deriving (Eq, Show, Read)
class SerializableCBRNG a where
getState :: a -> CBRNGState
instance SerializableCBRNG CBRNG32 where
getState (CBRNG32 key ctr wctr) = CBRNGState (liToInteger key) (liToInteger ctr) wctr
instance SerializableCBRNG CBRNG64 where
getState (CBRNG64 key ctr wctr) = CBRNGState (liToInteger key) (liToInteger ctr) wctr
instance (LimitedInteger k, LimitedInteger c) => SerializableCBRNG (CustomCBRNG32 k c) where
getState (CustomCBRNG32 _ key ctr wctr) =
CBRNGState (liToInteger key) (liToInteger ctr) wctr
instance (LimitedInteger k, LimitedInteger c) => SerializableCBRNG (CustomCBRNG64 k c) where
getState (CustomCBRNG64 _ key ctr wctr) =
CBRNGState (liToInteger key) (liToInteger ctr) wctr
mkCustomCBRNG32 :: LimitedInteger c => (k -> c -> c) -> k -> CustomCBRNG32 k c
mkCustomCBRNG32 bijection key = CustomCBRNG32 bijection key (liFromInteger 0) 0
restoreCustomCBRNG32 :: (LimitedInteger k, LimitedInteger c)
=> (k -> c -> c) -> CBRNGState -> CustomCBRNG32 k c
restoreCustomCBRNG32 bijection (CBRNGState key ctr wctr) =
CustomCBRNG32 bijection (liFromInteger key) (liFromInteger ctr) wctr
mkCustomCBRNG64 :: LimitedInteger c => (k -> c -> c) -> k -> CustomCBRNG64 k c
mkCustomCBRNG64 bijection key = CustomCBRNG64 bijection key (liFromInteger 0) 0
restoreCustomCBRNG64 :: (LimitedInteger k, LimitedInteger c)
=> (k -> c -> c) -> CBRNGState -> CustomCBRNG64 k c
restoreCustomCBRNG64 bijection (CBRNGState key ctr wctr) =
CustomCBRNG64 bijection (liFromInteger key) (liFromInteger ctr) wctr
mkCBRNG32 :: Integer -> CBRNG32
mkCBRNG32 key = CBRNG32 (liFromInteger key) (liFromInteger 0) 0
restoreCBRNG32 :: CBRNGState -> CBRNG32
restoreCBRNG32 (CBRNGState key ctr wctr) = CBRNG32 (liFromInteger key) (liFromInteger ctr) wctr
mkCBRNG64 :: Integer -> CBRNG64
mkCBRNG64 key = CBRNG64 (liFromInteger key) (liFromInteger 0) 0
restoreCBRNG64 :: CBRNGState -> CBRNG64
restoreCBRNG64 (CBRNGState key ctr wctr) = CBRNG64 (liFromInteger key) (liFromInteger ctr) wctr