packages feed

xorshift 1 → 2

raw patch · 4 files changed

+187/−112 lines, 4 filesdep +basedep +randomdep +time

Dependencies added: base, random, time

Files

src/Random/Xorshift.hs view
@@ -11,144 +11,60 @@ -- | Xorshift random generators. The generators are implemented according to --   the paper <http://www.jstatsoft.org/v08/i14/paper> by George Marsaglia. --   You can use the 'RandomGen' instances to generate random numbers easily.+--   This module only exports the Random generator that matches your word size,+--   if you want to use a specific length, try "Random.Xorshift.Int32" and+--   "Random.Xorshift.Int64" instead. -----------------------------------------------------------------------------  {-# LANGUAGE GeneralizedNewtypeDeriving, CPP #-} --- Use the C-header file to generate a platform depend Xorshift type--- This is handy as I can use the __Xorshift macro as a data-constructor.-#include "MachDeps.h"-#if WORD_SIZE_IN_BITS == 32-#define __Xorshift Xorshift32-#else-#define __Xorshift Xorshift64-#endif- module Random.Xorshift (-    Xorshift32 (..),-    Xorshift64 (..),     Xorshift,-    newXorshift32,-    newXorshift64,     newXorshift,-    makeXorshift32,-    makeXorshift64,     makeXorshift,-    getInt64,-    getInt32,     module System.Random   ) where -import Data.Int  (Int32,Int64)-import Data.Bits (xor,shiftL,shiftR) import System.Random import Data.Time --- | Xorshift generator with 32 bits.---   This Xorshift generator uses first a left shift, then a right shift and---   again a left shift. It uses the parameters 13, 17 and 5. See the paper for---   more details on how the parameters affect the generation of random numbers.------   The generator has a periode of 2^32-1, please notice that the---   generator has to be initialized with a value different from 0, elseway all---   future values will be zero as well.-newtype Xorshift32 = Xorshift32 Int32-  deriving (Eq,Show,Enum,Bounded)---- | Xorshift generator with 64 bits.---   This Xorshift generator uses first a left shift, then a right shift and---   again a left shift. It uses the parameters 13, 7 and 17. See the paper for---   more details on how the parameters affect the generation of random numbers.------   The generator has a periode of 2^64-1, please notice that the---   generator has to be initialized with a value different from 0, elseway all---   future values will be zero as well.-newtype Xorshift64 = Xorshift64 Int64-  deriving (Eq,Show,Enum,Bounded)---- | Generates a new Xorshift32 from the current time.-newXorshift32 :: IO Xorshift32-newXorshift32 = getRandomValue >>= return . makeXorshift32---- | Generates a new Xorshift32 from the current time.-newXorshift64 :: IO Xorshift64-newXorshift64 = getRandomValue >>= return . makeXorshift64+-- Use the C-header file to generate a platform depend Xorshift type+-- This is handy as I can use the __Xorshift macro as a data-constructor.+#include "MachDeps.h"+#if WORD_SIZE_IN_BITS == 32+#define __Xorshift Xorshift32+import Random.Xorshift.Int32+import Random.Xorshift.Int64 ()+#else+#define __Xorshift Xorshift64+import Random.Xorshift.Int32 ()+import Random.Xorshift.Int64+#endif  -- | Generates a new Xorshift from the current time. This is either a synonym --   for 'newXorshift32' or 'newXorshift64'. newXorshift :: IO Xorshift newXorshift = getRandomValue >>= return . makeXorshift --- | Generate a new 'Xorshift32' generator. This is essentially a wrapper around---   the constructor.-makeXorshift32 :: Integral a => a -> Xorshift32-makeXorshift32 = Xorshift32 . fromIntegral---- | Generate a new 'Xorshift64' generator. This is essentially a wrapper around---   the constructor.-makeXorshift64 :: Integral a => a -> Xorshift64-makeXorshift64 = Xorshift64 . fromIntegral- -- | Generate a new 'Xorshift' generator, regardless of whatever it's bytesize --   is on your platform. makeXorshift :: Integral a => a -> Xorshift makeXorshift = __Xorshift . fromIntegral --- | Get the raw contents of the random generator. This function is preferable---   over direct usage of the constructor itself, as the internal representation---   of the random generator may change in future releases.------   The 'getInt32' function works for 'Xorshift32' and the 'getInt64' function---   works for 'Xorshift64'. If you're using the 'Xorshift' type, use an 'Int'---   type in combination with the 'random' methof of "System.Random".-getInt32 :: Xorshift32 -> Int32-getInt32 (Xorshift32 a) = a--getInt64 :: Xorshift32 -> Int32-getInt64 (Xorshift32 a) = a--instance RandomGen Xorshift32 where-  next a = (fromIntegral c, b) where-    b@(Xorshift32 c) = step32 a-  split  = error "Splitting of an Xorshift random generator is not implemented."-  genRange a = (fromEnum (minBound `asTypeOf` a),-                fromEnum (maxBound `asTypeOf` a))--instance RandomGen Xorshift64 where-  next a = (fromIntegral c, b) where-    b@(Xorshift64 c) = step64 a-  split  = error "Splitting of an Xorshift random generator is not implemented."-  genRange a = (fromEnum (minBound `asTypeOf` a),-                fromEnum (maxBound `asTypeOf` a))---- | The type Xorshift is a wrapper around either 'Xorshift32' or 'Xorshift64',---   depending on the bit size of your system. The idea behind this is, that you---   may want to use this package as an uncomplicated, fast random generator,---   but repeated conversion between different word sizes are an absolute---   performance killer.+-- | The type Xorshift is a wrapper around either Xorshift32 or Xorshift64,+--   depending on the bit size of your system. The idea behind this is, that+--   you may want to use this package as an uncomplicated, fast random+--   generator, but repeated conversion between different word sizes are an+--   absolute performance killer. -- --   Thus, if you don't really care about the period of your random generator or --   how long the result is, use the 'Xorshift' synonym, whenever possible. type Xorshift = __Xorshift --- Iterates the random generator for 32 bits-step32 :: Xorshift32 -> Xorshift32-step32 (Xorshift32 a) = Xorshift32 d where-  b = a `xor` (shiftL a 13)-  c = b `xor` (shiftR b 17)-  d = c `xor` (shiftL c  5)---- Iterates the random generator for 64 bits-step64 :: Xorshift64 -> Xorshift64-step64 (Xorshift64 a) = Xorshift64 d where-  b = a `xor` (shiftL a 13)-  c = b `xor` (shiftR b  7)-  d = c `xor` (shiftL c 17)- -- Generates a random value from current time. We try to archieve a good result -- by summing all information of time. getRandomValue :: IO Integer getRandomValue = do UTCTime (ModifiedJulianDay day) time <- getCurrentTime-                    let picosecs = truncate $ toRational time * 10^12-                        dayInPs  = day * 86400 * 10^12+                    let picosecs = truncate $ toRational time * 10^(12 :: Int)+                        dayInPs  = day * 86400 * 10^(12 :: Int)                     return $! picosecs + dayInPs
+ src/Random/Xorshift/Int32.hs view
@@ -0,0 +1,78 @@+-----------------------------------------------------------------------------+--+-- Module      :  Random.Xorshift.Int32+-- Copyright   :+-- License     :  LGPL 2.0 or higher+--+-- Maintainer  :+-- Stability   :+-- Portability :+--+-- | This module contains a 32 bit Xorshift random generator. Use this if you+--   need a 32 bit random generator, usually 'Xorshift' itself is a good choice+--   for your platform. This generator has a period of 2^32-1 bits if+--   initialized with a value different from 0. +-----------------------------------------------------------------------------+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module Random.Xorshift.Int32 (+    Xorshift32 (..),+    newXorshift32,+    makeXorshift32,+    getInt32+  ) where++import Data.Int  (Int32)+import Data.Bits+import System.Random+import Data.Time++-- | Xorshift generator with 32 bits.+--   This Xorshift generator uses first a left shift, then a right shift and+--   again a left shift. It uses the parameters 13, 17 and 5. See the paper for+--   more details on how the parameters affect the generation of random numbers.+--+--   The generator has a periode of 2^32-1, please notice that the+--   generator has to be initialized with a value different from 0, elseway all+--   future values will be zero as well.+--+--   Please notice, that the function 'split' is not implemented and will result+--   in a runtime error.+newtype Xorshift32 = Xorshift32 Int32+  deriving (Eq,Show,Enum,Bounded)++instance RandomGen Xorshift32 where+  next a = (fromIntegral c, b) where+    b@(Xorshift32 c) = step32 a+  split  = error "Splitting of an Xorshift random generator is not implemented."+  genRange a = (fromEnum (minBound `asTypeOf` a),+                fromEnum (maxBound `asTypeOf` a))++-- | Generates a new Xorshift32 from the current time.+newXorshift32 :: IO Xorshift32+newXorshift32 = getRandomValue >>= return . makeXorshift32++-- | Generate a new 'Xorshift32' generator. This is essentially a wrapper around+--   the constructor.+makeXorshift32 :: Integral a => a -> Xorshift32+makeXorshift32 = Xorshift32 . fromIntegral++-- | Get the raw contents of the random generator. This function is preferable+--   over direct usage of the constructor itself, as the internal representation+--   of the random generator may change in future releases.+getInt32 :: Xorshift32 -> Int32+getInt32 (Xorshift32 a) = a++-- Generates a random value from current time. We try to archieve a good result+-- by summing all information of time.+getRandomValue :: IO Integer+getRandomValue = do UTCTime (ModifiedJulianDay day) time <- getCurrentTime+                    let picosecs = truncate $ toRational time * 10^(12 :: Int)+                        dayInPs  = day * 86400 * 10^(12 :: Int)+                    return $! picosecs + dayInPs++-- Iterates the random generator for 32 bits+step32 :: Xorshift32 -> Xorshift32+step32 (Xorshift32 a) = Xorshift32 d where+  b = a `xor` (shiftL a 13)+  c = b `xor` (shiftR b 17)+  d = c `xor` (shiftL c  5)
+ src/Random/Xorshift/Int64.hs view
@@ -0,0 +1,78 @@+-----------------------------------------------------------------------------+--+-- Module      :  Random.Xorshift.Int64+-- Copyright   :+-- License     :  LGPL 2.0 or higher+--+-- Maintainer  :+-- Stability   :+-- Portability :+--+-- | This module contains a 64 bit Xorshift random generator. Use this if you+--   need a 64 bit random generator, usually 'Xorshift' itself is a good choice+--   for your platform. This generator has a period of 2^64-1 bits if+--   initialized with a value different from 0. +-----------------------------------------------------------------------------+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+module Random.Xorshift.Int64 (+    Xorshift64 (..),+    newXorshift64,+    makeXorshift64,+    getInt64+  ) where++import Data.Int  (Int64)+import Data.Bits+import System.Random+import Data.Time++-- | Xorshift generator with 64 bits.+--   This Xorshift generator uses first a left shift, then a right shift and+--   again a left shift. It uses the parameters 13, 7 and 17. See the paper for+--   more details on how the parameters affect the generation of random numbers.+--+--   The generator has a periode of 2^64-1, please notice that the+--   generator has to be initialized with a value different from 0, elseway all+--   future values will be zero as well.+--+--   Please notice, that the function 'split' is not implemented and will result+--   in a runtime error.+newtype Xorshift64 = Xorshift64 Int64+  deriving (Eq,Show,Enum,Bounded)++instance RandomGen Xorshift64 where+  next a = (fromIntegral c, b) where+    b@(Xorshift64 c) = step64 a+  split  = error "Splitting of an Xorshift random generator is not implemented."+  genRange a = (fromEnum (minBound `asTypeOf` a),+                fromEnum (maxBound `asTypeOf` a))++-- | Generates a new Xorshift64 from the current time.+newXorshift64 :: IO Xorshift64+newXorshift64 = getRandomValue >>= return . makeXorshift64++-- | Generate a new 'Xorshift64' generator. This is essentially a wrapper around+--   the constructor.+makeXorshift64 :: Integral a => a -> Xorshift64+makeXorshift64 = Xorshift64 . fromIntegral++-- | Get the raw contents of the random generator. This function is preferable+--   over direct usage of the constructor itself, as the internal representation+--   of the random generator may change in future releases.+getInt64 :: Xorshift64 -> Int64+getInt64 (Xorshift64 a) = a++-- Generates a random value from current time. We try to archieve a good result+-- by summing all information of time.+getRandomValue :: IO Integer+getRandomValue = do UTCTime (ModifiedJulianDay day) time <- getCurrentTime+                    let picosecs = truncate $ toRational time * 10^(12 :: Int)+                        dayInPs  = day * 86400 * 10^(12 :: Int)+                    return $! picosecs + dayInPs++-- Iterates the random generator for 64 bits+step64 :: Xorshift64 -> Xorshift64+step64 (Xorshift64 a) = Xorshift64 d where+  b = a `xor` (shiftL a 13)+  c = b `xor` (shiftR b  7)+  d = c `xor` (shiftL c 17)
xorshift.cabal view
@@ -1,5 +1,5 @@ name: xorshift-version: 1+version: 2 Cabal-Version: >= 1.6 build-type: Simple @@ -8,10 +8,10 @@ license-file: "COPYING"  author: Robert Clausecker  <fuzxxl@gmail.com>-bug-reports: http://https://github.com/fuzxxl/Xorshift/issues+bug-reports: https://github.com/fuzxxl/Xorshift/issues maintainer: Robert Clausecker+homepage: https://github.com/fuzxxl/Xorshift -build-depends: base -any, random -any, time -any stability: homepage: package-url:@@ -19,14 +19,17 @@ description: The Xorshift random generator is a very fast generator that uses     only XOR and bitshifting operations. This package contains a basic version     with a periode of 2^32-1 for 32-bit numbers and a version with a periode of-    2^64-1 for 64-bit numbers. The author didn't tested the random generator,+    2^64-1 for 64-bit numbers.+    .+    Although the author didn't tested the random generator,     but according to it's specification the resulting numbers are of good     quality.  category: Math  library-  exposed-modules: Random.Xorshift+  build-depends: base >= 3 && < 5, random -any, time -any+  exposed-modules: Random.Xorshift Random.Xorshift.Int32 Random.Xorshift.Int64   exposed: True   extensions: CPP, GeneralizedNewtypeDeriving   hs-source-dirs: src@@ -39,4 +42,4 @@ source-repository this   type:     git   location: git://github.com/fuzxxl/Xorshift.git-  tag:      release-1+  tag:      release-2