diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2015-07-30 16:07:50 +0200 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2015-07-30 16:07:50 +0200 |
| commit | dec32e1516a05db805ff75a9e016e8bea04d1d8e (patch) | |
| tree | 1087efc189d5ca533ac01fec6746347212d66202 | |
| parent | added readme (diff) | |
| download | SyncRNG-dec32e1516a05db805ff75a9e016e8bea04d1d8e.tar.gz SyncRNG-dec32e1516a05db805ff75a9e016e8bea04d1d8e.zip | |
name change to SyncRNG and documentation in the .c file
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | README.md | 16 | ||||
| -rw-r--r-- | SyncRNG.R (renamed from Tausworthe.R) | 24 | ||||
| -rw-r--r-- | SyncRNG.py | 21 | ||||
| -rw-r--r-- | Tausworthe.py | 16 | ||||
| -rw-r--r-- | setup.py | 12 | ||||
| -rw-r--r-- | syncrng.c (renamed from taus.c) | 62 |
8 files changed, 99 insertions, 64 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed61eb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.so +*.o @@ -1,4 +1,6 @@ PYTHON=python2 +RLIB=RSyncRNG.so +CFILE=syncrng.c .PHONY: all clean @@ -8,10 +10,9 @@ python: $(PYTHON) setup.py build_ext --inplace R: - R CMD SHLIB -o tausR.so taus.c + R CMD SHLIB -o $(RLIB) $(CFILE) clean: rm -rf build - rm -f taus.so - rm -f tausR.so - rm -f taus.o + rm -f *.so *.o + rm *.pyc @@ -25,7 +25,7 @@ build both shared libraries using: make Then, in a Python script located in the same directory as `syncrng.so` and -`pysyncrng.py`, you can do: +`SyncRNG.py`, you can do: from pysyncrng import SyncRNG @@ -33,10 +33,10 @@ Then, in a Python script located in the same directory as `syncrng.so` and for i in range(10): print(s.randi()) -Similarly, in an R script located in the same directory as `Rsyncrng.so` and -`Rsyncrng.R`, you can do: +Similarly, in an R script located in the same directory as `RSyncRNG.so` and +`SyncRNG.R`, you can do: - source('./Rsyncrng.R') + source('./SyncRNG.R') s = SyncRNG(seed=123456) for (i in 1:10) { @@ -55,3 +55,11 @@ random numbers are no longer uniformly distributed on `[0, 2^32 -1]`. For the intended use of SyncRNG this is not a problem, but it is a compromise worth considering when using SyncRNG. SyncRNG should definitely not be used for any cryptographic purposes. + + +TODO +---- + +Future versions may include a random number generator that does not need +capping, and is uniform. It may also provide easier system-wide installation +through an R package and a Python module. @@ -1,8 +1,8 @@ library(methods) -dyn.load('tausR.so') +dyn.load('RSyncRNG.so') -TauswortheRNG <- setRefClass('TauswortheRNG', +SyncRNG <- setRefClass('SyncRNG', fields=list( seed='numeric', state='numeric' @@ -10,13 +10,13 @@ TauswortheRNG <- setRefClass('TauswortheRNG', methods=list( initialize=function(..., seed=0) { seed <<- seed - tmp <- .Call('R_tausworthe_seed', + tmp <- .Call('R_syncrng_seed', as.integer(seed)) state <<- tmp[1:4] callSuper(...) }, randi=function() { - tmp <- .Call('R_tausworthe_rand', + tmp <- .Call('R_syncrng_rand', as.integer(state)) state <<- tmp[1:4] return(tmp[5]) @@ -27,19 +27,3 @@ TauswortheRNG <- setRefClass('TauswortheRNG', } ) ) - -taus.seed <- function(seed=0) -{ - t <- TauswortheRNG(seed=seed) - return(t) -} - -taus.rand <- function(t) -{ - return(t$rand()) -} - -taus.randi <- function(t) -{ - return(t$randi()) -} diff --git a/SyncRNG.py b/SyncRNG.py new file mode 100644 index 0000000..7137439 --- /dev/null +++ b/SyncRNG.py @@ -0,0 +1,21 @@ +""" +Simple interface to SyncRNG. This file defines a SyncRNG object which can be +used to seed and pull numbers from the RNG. + +""" + +import syncrng + +class SyncRNG(object): + + def __init__(self, seed=0): + self.seed = seed + self.state = syncrng.seed(seed) + + def randi(self): + tmp = syncrng.rand(self.state) + self.state = tmp[:-1] + return(tmp[-1]) + + def rand(self): + return self.randi() * 2.3283064365387e-10 diff --git a/Tausworthe.py b/Tausworthe.py deleted file mode 100644 index 303f358..0000000 --- a/Tausworthe.py +++ /dev/null @@ -1,16 +0,0 @@ - -import taus - -class TauswortheRNG(object): - - def __init__(self, seed=0): - self.seed = seed - self.state = taus.seed(seed) - - def randi(self): - tmp = taus.rand(self.state) - self.state = tmp[:-1] - return(tmp[-1]) - - def rand(self): - return self.randi() * 2.3283064365387e-10 @@ -2,18 +2,18 @@ from distutils.core import setup, Extension """ -module1 = Extension('taus', +module1 = Extension('syncrng', define_macros = [('TARGETPYTHON', '1')], - sources=['taus.c']) + sources=['syncrng.c']) -setup (name = 'Tausworthe RNG', +setup (name = 'SyncRNG', version = '0.1', - description='The Tausworthe RNG for Python and R', + description='A synchronized Tausworthe RNG for Python and R', ext_modules = [module1]) """ setup( - ext_modules=[Extension("taus", + ext_modules=[Extension("syncrng", define_macros=[('TARGETPYTHON', '1')], - sources=["taus.c"])], + sources=["syncrng.c"])], ) @@ -10,6 +10,30 @@ #include <Rinternals.h> #endif +/** + * @brief Generate a single random number using the capped Tausworthe RNG + * + * @details + * This generates random numbers according to the process described in [1]. As + * an additional step, the state variables are capped to 0x7FFFFFFF using a + * bitwise and. This is to overcome limitations of R. On return, the state + * variables are updated. + * + * [1]: @article{l1996maximally, + * title={Maximally equidistributed combined Tausworthe generators}, + * author={L’ecuyer, Pierre}, + * journal={Mathematics of Computation of the American Mathematical + * Society}, + * volume={65}, + * number={213}, + * pages={203--213}, + * year={1996} + * } + * + * @param[in,out] state pointer to current state array + * + * @return a generated random number + */ int lfsr113(int **state) { unsigned long z1, z2, z3, z4, b; @@ -42,6 +66,18 @@ int lfsr113(int **state) return(b); } +/** + * @brief Seed the Tausworthe RNG using a seed value + * + * @details + * This function seeds the state array using a supplied seed value. As noted + * in [1] (see lfsr113()), the values of z1, z2, z3, and z4 should be larger + * than 1, 7, 15, and 127 respectively. Here too the state variables are + * capped at 0x7FFFFFF. + * + * @param[in] seed user supplied seed value for the RNG + * @param[out] state state of the RNG + */ void lfsr113_seed(unsigned long seed, int **state) { unsigned long z1 = 2, @@ -71,10 +107,7 @@ void lfsr113_seed(unsigned long seed, int **state) * */ -static char module_docstring[] = -"This module provides the Tausworthe RNG for R and Python simultaneously"; - -static PyObject *taus_seed(PyObject *self, PyObject *args) +static PyObject *syncrng_seed(PyObject *self, PyObject *args) { int seed, *state = NULL; @@ -88,7 +121,7 @@ static PyObject *taus_seed(PyObject *self, PyObject *args) return pystate; } -static PyObject *taus_rand(PyObject *self, PyObject *args) +static PyObject *syncrng_rand(PyObject *self, PyObject *args) { int i, value, numints, *localstate; @@ -117,17 +150,18 @@ static PyObject *taus_rand(PyObject *self, PyObject *args) return pystate; } -static PyMethodDef TausMethods[] = { - {"seed", taus_seed, METH_VARARGS, - "Seed the Tausworthe RNG."}, - {"rand", taus_rand, METH_VARARGS, - "Generate a single random integer."}, +static PyMethodDef SyncRNGMethods[] = { + {"seed", syncrng_seed, METH_VARARGS, + "Seed the RNG."}, + {"rand", syncrng_rand, METH_VARARGS, + "Generate a single random integer using SyncRNG."}, {NULL, NULL, 0, NULL} }; -PyMODINIT_FUNC inittaus(void) +PyMODINIT_FUNC initsyncrng(void) { - PyObject *m = Py_InitModule3("taus", TausMethods, module_docstring); + PyObject *m = Py_InitModule3("syncrng", SyncRNGMethods, + "Python interface to SyncRNG"); if (m == NULL) return; } @@ -139,7 +173,7 @@ PyMODINIT_FUNC inittaus(void) * Start of R code * */ -SEXP R_tausworthe_seed(SEXP seed) +SEXP R_syncrng_seed(SEXP seed) { int i, *pstate = NULL, *state = NULL; int *pseed = INTEGER(seed); @@ -159,7 +193,7 @@ SEXP R_tausworthe_seed(SEXP seed) return Rstate; } -SEXP R_tausworthe_rand(SEXP state) +SEXP R_syncrng_rand(SEXP state) { int *localstate = malloc(sizeof(int)*4); int *pstate = INTEGER(state); |
