diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2021-01-14 17:30:12 +0000 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2021-01-14 17:30:12 +0000 |
| commit | 201e19975461c6fb04d4487346e2a0b68d2359dc (patch) | |
| tree | 0cf71b412b17670bf7e2c12b8e26c1dada051b5a /new_R | |
| parent | Merge branch 'python' (diff) | |
| download | SyncRNG-201e19975461c6fb04d4487346e2a0b68d2359dc.tar.gz SyncRNG-201e19975461c6fb04d4487346e2a0b68d2359dc.zip | |
Rename directories, remove extra test dir
Diffstat (limited to 'new_R')
| -rw-r--r-- | new_R/DESCRIPTION | 15 | ||||
| -rw-r--r-- | new_R/NAMESPACE | 7 | ||||
| -rw-r--r-- | new_R/NEWS.md | 4 | ||||
| -rw-r--r-- | new_R/R/SyncRNG.R | 76 | ||||
| -rw-r--r-- | new_R/R/syncrng-package.R | 50 | ||||
| -rw-r--r-- | new_R/cran-comments.md | 17 | ||||
| -rw-r--r-- | new_R/man/SyncRNG-class.Rd | 39 | ||||
| -rw-r--r-- | new_R/man/syncrng-package.Rd | 52 | ||||
| -rw-r--r-- | new_R/src/_syncrng.c | 381 | ||||
| -rw-r--r-- | new_R/src/syncrng.c | 407 | ||||
| -rw-r--r-- | new_R/tests/testthat.R | 4 | ||||
| -rw-r--r-- | new_R/tests/testthat/first_1000_seed_0.txt | 1000 | ||||
| -rw-r--r-- | new_R/tests/testthat/tests.R | 63 |
13 files changed, 0 insertions, 2115 deletions
diff --git a/new_R/DESCRIPTION b/new_R/DESCRIPTION deleted file mode 100644 index 141743a..0000000 --- a/new_R/DESCRIPTION +++ /dev/null @@ -1,15 +0,0 @@ -Package: SyncRNG -Version: 1.3.0 -Date: 2017-12-15 -Title: A Synchronized Tausworthe RNG for R and Python -Author: Gertjan van den Burg <gertjanvandenburg@gmail.com> -Maintainer: Gertjan van den Burg <gertjanvandenburg@gmail.com> -Depends: - R (>= 3.0.0) -Description: Random number generation designed for cross-language usage. -License: GPL-2 -Imports: - methods -Suggests: - testthat -RoxygenNote: 7.1.1 diff --git a/new_R/NAMESPACE b/new_R/NAMESPACE deleted file mode 100644 index 052e9e8..0000000 --- a/new_R/NAMESPACE +++ /dev/null @@ -1,7 +0,0 @@ -# Generated by roxygen2: do not edit by hand - -export(SyncRNG) -exportClasses(SyncRNG) -import(methods) -importFrom(methods,new) -useDynLib(SyncRNG, .registration = TRUE) diff --git a/new_R/NEWS.md b/new_R/NEWS.md deleted file mode 100644 index 8b038d8..0000000 --- a/new_R/NEWS.md +++ /dev/null @@ -1,4 +0,0 @@ -# SyncRNG 1.3.0 - -* Allows using SyncRNG as a user-supplied random number generator in R. This - enables using the functions ``runif`` and ``rnorm``. diff --git a/new_R/R/SyncRNG.R b/new_R/R/SyncRNG.R deleted file mode 100644 index e7176b4..0000000 --- a/new_R/R/SyncRNG.R +++ /dev/null @@ -1,76 +0,0 @@ -library(methods) - -#' A Reference Class for SyncRNG -#' -#' See \link{syncrng-package} for package documentation. -#' -#' @field seed The seed for the random number generator -#' @field state The current state of the RNG, should not be modified by the -#' user -#' -#' @useDynLib SyncRNG, .registration = TRUE -#' @export SyncRNG -#' @exportClass SyncRNG -#' @importFrom methods new -#' -#' @examples -#' s <- SyncRNG(seed=123456) -#' for (i in 1:10) -#' cat(s$randi(), '\n') -#' -SyncRNG <- setRefClass('SyncRNG', - fields=list( - seed='numeric', - state='numeric' - ), - methods=list( - initialize=function(..., seed=0) { - "Initialize the RNG using the C function R_syncrng_seed" - seed <<- seed - tmp <- .Call('R_syncrng_seed', - as.numeric(seed)) - state <<- tmp[1:4] - callSuper(...) - }, - randi=function() { - "Generate a single random 32-bit integer" - tmp <- .Call('R_syncrng_rand', - as.numeric(state)) - state <<- tmp[1:4] - return(tmp[5]) - }, - rand=function() { - "Generate a single random float in the range [0, 1)" - r <- randi() - return (r * 2.3283064365387e-10) - }, - randbelow=function(n) { - "Generate a random integer below a given number" - maxsize <- 2^32 - if (n >= maxsize) { - warning(paste("Underlying random generator ", - "does not supply\n enough bits ", - "to choose from a population ", - "range this large.\n")) - return(round(rand() * n)) - } - rem <- maxsize %% n - limit <- (maxsize - rem) / maxsize - r <- rand() - while (r >= limit) - r <- rand() - return(round(r*maxsize) %% n) - }, - shuffle=function(x) { - "Randomly shuffle a provided array of values" - y <- x - for (i in rev(1:(length(y)-1))) { - j <- randbelow(i+1) - tmp <- y[i+1] - y[i+1] <- y[j+1] - y[j+1] <- tmp - } - return(y) - } - ) - ) diff --git a/new_R/R/syncrng-package.R b/new_R/R/syncrng-package.R deleted file mode 100644 index 949401d..0000000 --- a/new_R/R/syncrng-package.R +++ /dev/null @@ -1,50 +0,0 @@ -#' @title SyncRNG - Synchronized Random Numbers in R and Python -#' -#' @description -#' The SyncRNG package provides a random number generator implemented in C and -#' linked to both R and Python. This way, you can generate the same random -#' number sequence in both languages by using the same seed. -#' -#' The package implements a Tausworthe LSFR RNG (more details at -#' \url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast -#' pseudo-random number generator. -#' -#' @section Usage: -#' There are two ways to use this package in R. It can be used as a reference -#' class, where a SyncRNG object is used to keep the state of the generator and -#' numbers are generated using the object methods. It can also be used as a -#' user-defined random number generator using the strategy outlined in -#' .Random.user. See the examples section below. -#' -#' @author -#' Gerrit J.J. van den Burg\cr -#' Maintainer: Gerrit J.J. van den Burg <gertjanvandenburg@gmail.com> -#' -#' @references -#' URL: \url{https://github.com/GjjvdBurg/SyncRNG} -#' -#' @examples -#' library(SyncRNG) -#' -#' # As user defined RNG: -#' -#' set.seed(0, 'user', 'user') -#' runif(2) -#' # [1] 3.666952e-04 6.257184e-05 -#' set.seed(0, 'user', 'user') -#' rnorm(2) -#' # [1] 0.01006027 0.42889422 -#' -#' # As class: -#' -#' s <- SyncRNG(seed=0) -#' s$rand() -#' # [1] 0.0003666952 -#' s$rand() -#' # [1] 6.257184e-05 -#' -#' @name syncrng-package -#' @docType package -#' @import methods -NULL -#>NULL diff --git a/new_R/cran-comments.md b/new_R/cran-comments.md deleted file mode 100644 index 4f984f0..0000000 --- a/new_R/cran-comments.md +++ /dev/null @@ -1,17 +0,0 @@ -## Test environments -* local Arch Linux install, R 3.4.3 -* win-builder (devel and release) - -## R CMD check results -There were no ERRORs or WARNINGs. - -There was 1 NOTE: - -* checking CRAN incoming feasibility ... NOTE -Maintainer: 'Gertjan van den Burg <gertjanvandenburg@gmail.com>' - -Possibly mis-spelled words in DESCRIPTION: - RNG (4:34) - Tausworthe (4:23) - - RNG is a common abbreviation and Tausworthe is a name. diff --git a/new_R/man/SyncRNG-class.Rd b/new_R/man/SyncRNG-class.Rd deleted file mode 100644 index 92316da..0000000 --- a/new_R/man/SyncRNG-class.Rd +++ /dev/null @@ -1,39 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/SyncRNG.R -\docType{class} -\name{SyncRNG-class} -\alias{SyncRNG-class} -\alias{SyncRNG} -\title{A Reference Class for SyncRNG} -\description{ -See \link{syncrng-package} for package documentation. -} -\section{Fields}{ - -\describe{ -\item{\code{seed}}{The seed for the random number generator} - -\item{\code{state}}{The current state of the RNG, should not be modified by the -user} -}} - -\section{Methods}{ - -\describe{ -\item{\code{initialize(..., seed = 0)}}{Initialize the RNG using the C function R_syncrng_seed} - -\item{\code{rand()}}{Generate a single random float in the range [0, 1)} - -\item{\code{randbelow(n)}}{Generate a random integer below a given number} - -\item{\code{randi()}}{Generate a single random 32-bit integer} - -\item{\code{shuffle(x)}}{Randomly shuffle a provided array of values} -}} - -\examples{ -s <- SyncRNG(seed=123456) -for (i in 1:10) - cat(s$randi(), '\n') - -} diff --git a/new_R/man/syncrng-package.Rd b/new_R/man/syncrng-package.Rd deleted file mode 100644 index f8cfe02..0000000 --- a/new_R/man/syncrng-package.Rd +++ /dev/null @@ -1,52 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/syncrng-package.R -\docType{package} -\name{syncrng-package} -\alias{syncrng-package} -\title{SyncRNG - Synchronized Random Numbers in R and Python} -\description{ -The SyncRNG package provides a random number generator implemented in C and -linked to both R and Python. This way, you can generate the same random -number sequence in both languages by using the same seed. - -The package implements a Tausworthe LSFR RNG (more details at -\url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast -pseudo-random number generator. -} -\section{Usage}{ - -There are two ways to use this package in R. It can be used as a reference -class, where a SyncRNG object is used to keep the state of the generator and -numbers are generated using the object methods. It can also be used as a -user-defined random number generator using the strategy outlined in -.Random.user. See the examples section below. -} - -\examples{ -library(SyncRNG) - -# As user defined RNG: - -set.seed(0, 'user', 'user') -runif(2) -# [1] 3.666952e-04 6.257184e-05 -set.seed(0, 'user', 'user') -rnorm(2) -# [1] 0.01006027 0.42889422 - -# As class: - -s <- SyncRNG(seed=0) -s$rand() -# [1] 0.0003666952 -s$rand() -# [1] 6.257184e-05 - -} -\references{ -URL: \url{https://github.com/GjjvdBurg/SyncRNG} -} -\author{ -Gerrit J.J. van den Burg\cr -Maintainer: Gerrit J.J. van den Burg <gertjanvandenburg@gmail.com> -} diff --git a/new_R/src/_syncrng.c b/new_R/src/_syncrng.c deleted file mode 100644 index bd1612a..0000000 --- a/new_R/src/_syncrng.c +++ /dev/null @@ -1,381 +0,0 @@ -#ifdef TARGETPYTHON -#include "Python.h" -#include <stdint.h> -#endif - -#ifndef TARGETPYTHON -#define STRICT_R_HEADERS -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <R.h> -#include <Rinternals.h> -#include <R_ext/Random.h> -#include <R_ext/Rdynload.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 resulting random number is capped to 0xFFFFFFFF - * using a bitwise and. This is done to yield the range [0, 2^32-1]. 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 - */ -uint32_t lfsr113(uint64_t **state) -{ - uint64_t z1, z2, z3, z4; - uint64_t b; - - z1 = (*state)[0]; - z2 = (*state)[1]; - z3 = (*state)[2]; - z4 = (*state)[3]; - - b = (((z1 << 6) ^ z1) >> 13); - z1 = (((z1 & 4294967294) << 18) ^ b); - - b = (((z2 << 2) ^ z2) >> 27); - z2 = (((z2 & 4294967288) << 2) ^ b); - - b = (((z3 << 13) ^ z3) >> 21); - z3 = (((z3 & 4294967280) << 7) ^ b); - - b = (((z4 << 3) ^ z4) >> 12); - z4 = (((z4 & 4294967168) << 13) ^ b); - - b = (z1 ^ z2 ^ z3 ^ z4); - - (*state)[0] = z1; - (*state)[1] = z2; - (*state)[2] = z3; - (*state)[3] = z4; - - b = b & 0xFFFFFFFF; - - return((uint32_t) 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. - * - * @param[in] seed user supplied seed value for the RNG - * @param[out] state state of the RNG - */ -void lfsr113_seed(uint32_t seed, uint64_t **state) -{ - uint64_t z1 = 2, - z2 = 8, - z3 = 16, - z4 = 128; - - z1 = (z1 * (seed + 1)); - z2 = (z2 * (seed + 1)); - z3 = (z3 * (seed + 1)); - z4 = (z4 * (seed + 1)); - - z1 = (z1 > 1) ? z1 : z1 + 1; - z2 = (z2 > 7) ? z2 : z2 + 7; - z3 = (z3 > 15) ? z3 : z3 + 15; - z4 = (z4 > 127) ? z4 : z4 + 127; - - if (*state == NULL) { - (*state) = malloc(sizeof(uint64_t)*4); - } - - (*state)[0] = z1; - (*state)[1] = z2; - (*state)[2] = z3; - (*state)[3] = z4; -} - -#ifdef TARGETPYTHON -/* - * - * Start of Python code - * - */ - -static PyObject *_syncrng_seed(PyObject *self, PyObject *args) -{ - uint32_t seed; - uint64_t *state = NULL; - - PyObject *dblObj; - - if (!PyArg_ParseTuple(args, "O", &dblObj)) - return NULL; - - seed = (uint32_t) PyLong_AsLong(dblObj); - lfsr113_seed(seed, &state); - - PyObject *pystate = Py_BuildValue("[d, d, d, d, d]", - (double) state[0], - (double) state[1], - (double) state[2], - (double) state[3], - -1.0); - free(state); - return pystate; -} - -static PyObject *_syncrng_rand(PyObject *self, PyObject *args) -{ - int i; - uint32_t rand; - uint64_t *localstate = malloc(sizeof(uint64_t) * 4); - - PyObject *listObj; - PyObject *dblObj; - - if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &listObj)) - return NULL; - - for (i=0; i<4; i++) { - dblObj = PyList_GetItem(listObj, i); - localstate[i] = (uint64_t) PyFloat_AS_DOUBLE(dblObj); - } - - rand = lfsr113(&localstate); - - PyObject *pystate = Py_BuildValue("[d, d, d, d, d]", - (double) localstate[0], - (double) localstate[1], - (double) localstate[2], - (double) localstate[3], - (double) rand); - free(localstate); - return pystate; -} - -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} -}; - -#if PY_MAJOR_VERSION >= 3 - static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_syncrng", - "Python interface to SyncRNG", - -1, - SyncRNGMethods, - NULL, - NULL, - NULL, - NULL - }; -#endif - - -static PyObject * -moduleinit(void) -{ - PyObject *m; - - #if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); - #else - m = Py_InitModule3("_syncrng", SyncRNGMethods, - "Python interface to SyncRNG"); - #endif - - return m; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC -PyInit__syncrng(void) -{ - return moduleinit(); -} -#else -PyMODINIT_FUNC -init_syncrng(void) -{ - moduleinit(); -} -#endif -#endif - -#ifndef TARGETPYTHON - -/* - * - * Start of R code - * - */ - -SEXP R_syncrng_seed(SEXP seed); -SEXP R_syncrng_rand(SEXP state); - -R_CallMethodDef callMethods[] = { - {"R_syncrng_seed", (DL_FUNC) &R_syncrng_seed, 1}, - {"R_syncrng_rand", (DL_FUNC) &R_syncrng_seed, 1}, - {NULL, NULL, 0} -}; -R_CMethodDef cMethods[] = { - {NULL, NULL, 0} -}; - -void R_init_myLib(DllInfo *info) -{ - R_registerRoutines(info, cMethods, callMethods, NULL, NULL); - R_useDynamicSymbols(info, TRUE); -} - -// Set the seed for the generator from the reference class -SEXP R_syncrng_seed(SEXP seed) -{ - int i; - double *pseed = REAL(seed), - *pstate = NULL; - uint32_t useed = (uint32_t) *pseed; - uint64_t *state = NULL; - - lfsr113_seed(useed, &state); - - SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); - pstate = REAL(Rstate); - for (i=0; i<4; i++) { - pstate[i] = (double) state[i]; - } - pstate[4] = -1.0; - free(state); - - UNPROTECT(1); - return Rstate; -} - -// get a random number from the reference class -SEXP R_syncrng_rand(SEXP state) -{ - uint64_t *localstate = malloc(sizeof(uint64_t)*4); - double *pstate = REAL(state); - int i; - for (i=0; i<4; i++) { - localstate[i] = (uint64_t) pstate[i]; - } - - uint32_t rand = lfsr113(&localstate); - - SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); - pstate = REAL(Rstate); - - for (i=0; i<4; i++) { - pstate[i] = (double) localstate[i]; - } - pstate[4] = (double) rand; - UNPROTECT(1); - - free(localstate); - - return Rstate; -} - -/* - * The following code is used to make SyncRNG a real "user-defined" RNG - * follwing .Random.user documentation. - * - */ - -static uint32_t global_R_seed; -static uint32_t global_R_nseed = 1; -static double global_R_result_uniform; -static double global_R_result_normal; -static uint64_t *global_R_state = NULL; - -double *user_unif_rand() -{ - if (global_R_state == NULL) { - // if it's not seeded yet we seed it with 0 - global_R_seed = 0; - lfsr113_seed(global_R_seed, &global_R_state); - } - - uint32_t rand = lfsr113(&global_R_state); - global_R_result_uniform = rand * 2.3283064365387e-10; - return &global_R_result_uniform; -} - -// see: https://stackoverflow.com/q/47824450/1154005 -Int32 _unscramble(Int32 scram) -{ - int j; - for (j=0; j<50; j++) { - scram = ((scram - 1) * 2783094533); - } - return scram; -} - -// note that Int32 is "unsigned int" which is not necessarily 32 bit -void user_unif_init(Int32 seed_in) -{ - global_R_seed = seed_in; - uint32_t useed = _unscramble(seed_in); - - // destroy the previous state, we're reseeding the RNG - if (global_R_state != NULL) { - free(global_R_state); - global_R_state = NULL; - } - lfsr113_seed(useed, &global_R_state); -} - -int *user_unif_nseed() -{ - return &global_R_nseed; -} - -int *user_unif_seedloc() -{ - return (int *) &global_R_seed; -} - -double *user_norm_rand() -{ - double u, v, z, x; - do { - u = *user_unif_rand(); - v = 0.857764 * (2. * (*user_unif_rand()) - 1); - x = v/u; - z = 0.25 * x * x; - if (z < 1. - u) - break; - if (z > 0.259/u + 0.35) - continue; - } while (z > -log(u)); - global_R_result_normal = x; - return &global_R_result_normal; -} - -/* - * - * End of R code - * - */ -#endif diff --git a/new_R/src/syncrng.c b/new_R/src/syncrng.c deleted file mode 100644 index 3a8cf68..0000000 --- a/new_R/src/syncrng.c +++ /dev/null @@ -1,407 +0,0 @@ -#ifdef TARGETPYTHON -#include "Python.h" -#include <stdint.h> -#endif - -#ifndef TARGETPYTHON -#define STRICT_R_HEADERS -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <R.h> -#include <Rinternals.h> -#include <R_ext/Random.h> -#include <R_ext/Rdynload.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 resulting random number is capped to 0xFFFFFFFF - * using a bitwise and. This is done to yield the range [0, 2^32-1]. 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 - */ -uint32_t lfsr113(uint64_t **state) -{ - uint64_t z1, z2, z3, z4; - uint64_t b; - - z1 = (*state)[0]; - z2 = (*state)[1]; - z3 = (*state)[2]; - z4 = (*state)[3]; - - b = (((z1 << 6) ^ z1) >> 13); - z1 = (((z1 & 4294967294) << 18) ^ b); - - b = (((z2 << 2) ^ z2) >> 27); - z2 = (((z2 & 4294967288) << 2) ^ b); - - b = (((z3 << 13) ^ z3) >> 21); - z3 = (((z3 & 4294967280) << 7) ^ b); - - b = (((z4 << 3) ^ z4) >> 12); - z4 = (((z4 & 4294967168) << 13) ^ b); - - b = (z1 ^ z2 ^ z3 ^ z4); - - (*state)[0] = z1; - (*state)[1] = z2; - (*state)[2] = z3; - (*state)[3] = z4; - - b = b & 0xFFFFFFFF; - - return((uint32_t) 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. - * - * @param[in] seed user supplied seed value for the RNG - * @param[out] state state of the RNG - */ -void lfsr113_seed(uint32_t seed, uint64_t **state) -{ - uint64_t z1 = 2, - z2 = 8, - z3 = 16, - z4 = 128; - - z1 = (z1 * (seed + 1)); - z2 = (z2 * (seed + 1)); - z3 = (z3 * (seed + 1)); - z4 = (z4 * (seed + 1)); - - z1 = (z1 > 1) ? z1 : z1 + 1; - z2 = (z2 > 7) ? z2 : z2 + 7; - z3 = (z3 > 15) ? z3 : z3 + 15; - z4 = (z4 > 127) ? z4 : z4 + 127; - - if (*state == NULL) { - (*state) = malloc(sizeof(uint64_t)*4); - } - - (*state)[0] = z1; - (*state)[1] = z2; - (*state)[2] = z3; - (*state)[3] = z4; -} - -#ifdef TARGETPYTHON -/* - * - * Start of Python code - * - */ - -static PyObject *_syncrng_seed(PyObject *self, PyObject *args) -{ - uint32_t seed; - uint64_t *state = NULL; -<<<<<<< HEAD:new_R/src/syncrng.c -======= - - PyObject *dblObj; ->>>>>>> python:new_python/src/_syncrng.c - - if (!PyArg_ParseTuple(args, "O", &dblObj)) - return NULL; - - seed = (uint32_t) PyLong_AsLong(dblObj); - lfsr113_seed(seed, &state); - - PyObject *pystate = Py_BuildValue("[d, d, d, d, d]", - (double) state[0], - (double) state[1], - (double) state[2], - (double) state[3], - -1.0); - free(state); - return pystate; -} - -static PyObject *_syncrng_rand(PyObject *self, PyObject *args) -{ -<<<<<<< HEAD:new_R/src/syncrng.c - uint32_t i, value, numints; - uint64_t *localstate; -======= - int i; - uint32_t rand; - uint64_t *localstate = malloc(sizeof(uint64_t) * 4); ->>>>>>> python:new_python/src/_syncrng.c - - PyObject *listObj; - PyObject *dblObj; - - if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &listObj)) - return NULL; - -<<<<<<< HEAD:new_R/src/syncrng.c - // we're just assuming you would never pass more than 4 values - localstate = malloc(sizeof(uint32_t)*5); - numints = PyList_Size(listObj); - for (i=0; i<numints; i++) { - intObj = PyList_GetItem(listObj, i); - value = (uint32_t) PyLong_AsLong(intObj); - localstate[i] = value; - } - - uint32_t rand = lfsr113(&localstate); - localstate[4] = rand; -======= - for (i=0; i<4; i++) { - dblObj = PyList_GetItem(listObj, i); - localstate[i] = (uint64_t) PyFloat_AS_DOUBLE(dblObj); - } - - rand = lfsr113(&localstate); ->>>>>>> python:new_python/src/_syncrng.c - - PyObject *pystate = Py_BuildValue("[d, d, d, d, d]", - (double) localstate[0], - (double) localstate[1], - (double) localstate[2], - (double) localstate[3], - (double) rand); - free(localstate); - return pystate; -} - -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} -}; - -#if PY_MAJOR_VERSION >= 3 - static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_syncrng", - "Python interface to SyncRNG", - -1, - SyncRNGMethods, - NULL, - NULL, - NULL, - NULL - }; -#endif - - -static PyObject * -moduleinit(void) -{ - PyObject *m; - - #if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); - #else - m = Py_InitModule3("_syncrng", SyncRNGMethods, - "Python interface to SyncRNG"); - #endif - - return m; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC -PyInit__syncrng(void) -{ - return moduleinit(); -} -#else -PyMODINIT_FUNC -init_syncrng(void) -{ - moduleinit(); -} -#endif -#endif - -#ifndef TARGETPYTHON - -/* - * - * Start of R code - * - */ - -SEXP R_syncrng_seed(SEXP seed); -SEXP R_syncrng_rand(SEXP state); - -R_CallMethodDef callMethods[] = { - {"R_syncrng_seed", (DL_FUNC) &R_syncrng_seed, 1}, - {"R_syncrng_rand", (DL_FUNC) &R_syncrng_seed, 1}, - {NULL, NULL, 0} -}; -R_CMethodDef cMethods[] = { - {NULL, NULL, 0} -}; - -void R_init_myLib(DllInfo *info) -{ - R_registerRoutines(info, cMethods, callMethods, NULL, NULL); - R_useDynamicSymbols(info, TRUE); -} - -// Set the seed for the generator from the reference class -SEXP R_syncrng_seed(SEXP seed) -{ - int i; - double *pseed = REAL(seed), - *pstate = NULL; - uint32_t useed = (uint32_t) *pseed; - uint64_t *state = NULL; - - lfsr113_seed(useed, &state); - - SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); - pstate = REAL(Rstate); - for (i=0; i<4; i++) { - pstate[i] = (double) state[i]; - } - pstate[4] = -1.0; - free(state); - - UNPROTECT(1); - return Rstate; -} - -// get a random number from the reference class -SEXP R_syncrng_rand(SEXP state) -{ - uint64_t *localstate = malloc(sizeof(uint64_t)*4); - double *pstate = REAL(state); - int i; - for (i=0; i<4; i++) { - localstate[i] = (uint64_t) pstate[i]; - } - - uint32_t rand = lfsr113(&localstate); - - SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); - pstate = REAL(Rstate); - - for (i=0; i<4; i++) { - pstate[i] = (double) localstate[i]; - } - pstate[4] = (double) rand; - UNPROTECT(1); - - free(localstate); - - return Rstate; -} - -/* - * The following code is used to make SyncRNG a real "user-defined" RNG - * follwing .Random.user documentation. - * - */ - -static uint32_t global_R_seed; -<<<<<<< HEAD:new_R/src/syncrng.c -static int global_R_nseed = 1; -======= -static uint32_t global_R_nseed = 1; ->>>>>>> python:new_python/src/_syncrng.c -static double global_R_result_uniform; -static double global_R_result_normal; -static uint64_t *global_R_state = NULL; - -double *user_unif_rand() -{ - if (global_R_state == NULL) { - // if it's not seeded yet we seed it with 0 - global_R_seed = 0; - lfsr113_seed(global_R_seed, &global_R_state); - } - - uint32_t rand = lfsr113(&global_R_state); - global_R_result_uniform = rand * 2.3283064365387e-10; - return &global_R_result_uniform; -} - -// see: https://stackoverflow.com/q/47824450/1154005 -Int32 _unscramble(Int32 scram) -{ - int j; - for (j=0; j<50; j++) { - scram = ((scram - 1) * 2783094533); - } - return scram; -} - -// note that Int32 is "unsigned int" which is not necessarily 32 bit -void user_unif_init(Int32 seed_in) -{ - global_R_seed = seed_in; - uint32_t useed = _unscramble(seed_in); - - // destroy the previous state, we're reseeding the RNG - if (global_R_state != NULL) { - free(global_R_state); - global_R_state = NULL; - } - lfsr113_seed(useed, &global_R_state); -} - -int *user_unif_nseed() -{ - return &global_R_nseed; -} - -int *user_unif_seedloc() -{ - return (int *) &global_R_seed; -} - -double *user_norm_rand() -{ - double u, v, z, x; - do { - u = *user_unif_rand(); - v = 0.857764 * (2. * (*user_unif_rand()) - 1); - x = v/u; - z = 0.25 * x * x; - if (z < 1. - u) - break; - if (z > 0.259/u + 0.35) - continue; - } while (z > -log(u)); - global_R_result_normal = x; - return &global_R_result_normal; -} - -/* - * - * End of R code - * - */ -#endif diff --git a/new_R/tests/testthat.R b/new_R/tests/testthat.R deleted file mode 100644 index b1f5cc8..0000000 --- a/new_R/tests/testthat.R +++ /dev/null @@ -1,4 +0,0 @@ -library(testthat) -library(SyncRNG) - -test_check("SyncRNG") diff --git a/new_R/tests/testthat/first_1000_seed_0.txt b/new_R/tests/testthat/first_1000_seed_0.txt deleted file mode 100644 index 50aef45..0000000 --- a/new_R/tests/testthat/first_1000_seed_0.txt +++ /dev/null @@ -1,1000 +0,0 @@ -1574944 -268744 -33556004 -8390676 -16851968 -2147582472 -134350084 -1074315269 -2097666 -2693283843 -50598144 -402792448 -536872117 -2281705500 -2097216 -67127296 -1192 -4097 -413712 -68096 -537198610 -9502976 -1077936653 -23069188 -256 -271065282 -1375735819 -1075056808 -137344 -537396752 -71370760 -134520872 -3196164 -24836 -2164785857 -2183397387 -269344 -41977872 -943785105 -2195975 -2283815708 -3170454 -68182051 -2281710785 -34344960 -1074024480 -460824 -839122944 -7438364 -155238412 -2166440334 -67126401 -3489693830 -1124336267 -537284650 -8392144 -805381657 -2165408 -29452 -2146516 -33704323 -2148282537 -19138624 -1619267616 -33754640 -671155715 -549519625 -3422584857 -7889684 -12289 -3223323809 -302387200 -1334448 -12654616 -940410368 -69321472 -205808168 -2167956679 -422150 -3506449091 -3263561808 -1350900792 -6425240 -809550976 -543263112 -203481359 -2146694 -1196512 -3355967617 -61734977 -8853552 -46403088 -704741917 -540082961 -2365612954 -2149671132 -117458370 -2147925124 -59121344 -1342640170 -4362072 -805610753 -5308846 -37785610 -20730196 -28992 -2952790235 -1082458123 -466480 -10487956 -1006651158 -11135872 -1241543311 -3229405863 -84162883 -2687116417 -308610137 -1217697952 -34756884 -940057617 -2757853260 -2281750584 -2117046 -8536213 -2432762497 -2200211979 -143004704 -9555090 -541402267 -2688090691 -140792396 -18901124 -34619827 -2281975939 -1126991882 -1611028540 -1510426 -570433665 -4261976 -201367560 -2151409932 -159745 -2416476396 -36078209 -545545526 -47188314 -570525328 -540398565 -2231400988 -2688182423 -359426 -3489672937 -10915924 -1409751076 -8104090 -805697154 -1089569002 -1296220170 -23228310 -71304648 -3357573835 -1402388746 -68628924 -2161655515 -571323533 -1144329024 -226905022 -807660740 -123848654 -3507419777 -2206633420 -1879528495 -39521946 -675329344 -4260201 -2342551838 -4160788 -1080928 -2952791293 -42848321 -350126 -2159872543 -1023504852 -4190932 -171990682 -1631541431 -19363907 -3758286790 -1113949782 -1845794863 -948310 -536886913 -3764488345 -17297420 -2279406 -81939869 -2349451169 -18637697 -243556660 -3263987441 -705043609 -3232571140 -3385285445 -946061980 -106022815 -2149881281 -2466519302 -1645367474 -918576 -546053696 -877659196 -216334888 -154739468 -70398851 -3707790308 -1107714240 -41949434 -3234631865 -960994496 -271830786 -205637392 -2285371587 -68563108 -3355977792 -2192441361 -1367412784 -40143408 -981517841 -543196563 -2367734299 -2283872410 -1344 -2181071879 -2206859904 -553846898 -549654344 -805609997 -2163104 -71332746 -86007956 -117991874 -3490064554 -25562218 -1879511088 -4425864 -541165322 -146901518 -1242620175 -75297540 -2148145409 -2687242416 -1386547200 -1515192 -312547844 -879347469 -606675077 -2315539260 -3292288180 -84170823 -2701271680 -3259307090 -1208409120 -1231108 -805578376 -2691760719 -141869068 -86001956 -76571121 -2298545346 -53381707 -142892072 -278219778 -574726163 -2150205781 -151286350 -2250360974 -101086355 -3490494661 -1661242064 -1074073654 -34738122 -945816717 -608289773 -2232988060 -104487366 -1141132385 -3506572416 -1610914817 -12933420 -416320010 -980706718 -10825792 -3443551182 -2776525524 -335138 -3231722194 -44532831 -1421335228 -142342666 -811120154 -1147218925 -2367611246 -69654868 -4222348 -3624435928 -3551840523 -77967668 -2463755847 -706032790 -1077262534 -2376231880 -925059286 -125304554 -3624333504 -1940823454 -1887737903 -6262158 -578073551 -106029822 -182235594 -2252236174 -1678131760 -3909323963 -847760523 -552000424 -2629422019 -795718747 -3090656 -3271585593 -3845708012 -19353971 -2966053808 -1212416724 -1312070453 -235870850 -3091824202 -3269792698 -152819996 -98860412 -820192477 -2369799568 -1396620160 -244589602 -3498863850 -574856834 -3829239105 -159603286 -1067697294 -39236251 -2432997826 -721684755 -1644254266 -955946 -2695372509 -356835194 -211485320 -238662558 -1076233167 -3307891111 -3794546048 -37949562 -3637088288 -863193421 -271789329 -761391063 -205299928 -67378860 -2158013456 -3599194065 -1907079858 -174119784 -1624289467 -7483173 -2759382862 -224727064 -134258952 -3543155069 -2441640202 -2174979241 -851922069 -542448292 -3253137 -2080458461 -54616262 -252468170 -3223217159 -665218426 -4028018793 -4626772 -1748803383 -709060767 -3121149182 -56479134 -3893141625 -2686933815 -2995214218 -2162482869 -262490641 -1011561522 -549060114 -3932247987 -3223024295 -152321631 -3101843551 -1280099225 -3358647209 -252846296 -3524154097 -2187760847 -3909680653 -2179387890 -1015137433 -3494929304 -50606464 -3901100357 -9850320 -940382251 -2699631292 -3087385960 -9538500 -234958491 -272389742 -220260678 -2684647653 -43257408 -4027072178 -28810004 -2101495309 -18607774 -134280454 -3223347501 -1376157898 -3222543805 -22419610 -973776048 -83221848 -218483748 -2685071319 -134550656 -3506980865 -2173075612 -2483766325 -66860762 -138671625 -1075841013 -2367832091 -2247808 -38814954 -3490485897 -60737793 -604469508 -2153524819 -536917141 -1074075984 -12724890 -2972321868 -23188040 -1074423975 -1117820684 -1879381029 -1739586 -939530176 -5327050 -58757130 -2151669013 -67532608 -3087534325 -2474001 -277224382 -2191034903 -1057240535 -549434183 -3405807240 -1618369262 -86191107 -2955045761 -308647117 -1578408101 -3139990 -806116500 -3831595195 -155443373 -19022846 -98715033 -2634272139 -3275515777 -512124196 -3230432369 -575086366 -3225228801 -199711444 -942108876 -121867967 -2819529105 -2200767815 -1921129010 -36410428 -780163669 -274212015 -2376151708 -3359123316 -20068231 -2349001203 -2185655880 -973119224 -3235762297 -755212101 -2956716003 -103138961 -3376199891 -92680340 -3758301290 -3236398675 -1090770984 -4196670 -813793301 -16288768 -1277219531 -140550882 -25313600 -3257601090 -2477397505 -429066492 -583196168 -671646619 -2754150662 -2399163262 -69629076 -101346518 -3775145624 -3282507882 -1619334952 -6457996 -637846925 -676180878 -175175818 -1698451828 -2233162017 -3087408874 -49089607 -478663992 -280881932 -945942552 -3224705271 -151407497 -607767788 -80172123 -3624479885 -1110753748 -2013690146 -2184431875 -709117454 -2692553290 -2157242825 -874605844 -86108881 -2567065312 -1092017287 -344356159 -2425400907 -574662615 -1084594274 -1262643867 -929455814 -56999307 -2821124246 -858115549 -1888834109 -2150800911 -627861145 -6024170 -228373816 -1178327534 -1093027685 -3624421308 -3798255747 -449290167 -2597181707 -926243929 -2687439124 -254107214 -3829027460 -93803542 -3968018064 -1388720668 -1151812149 -1214147364 -844558349 -1080633195 -2350576007 -2368200508 -97528200 -2365796063 -2476535242 -1017242931 -3503925127 -852957056 -3492589682 -115795988 -925186774 -40237656 -4094491891 -1906813406 -1611043710 -1115295490 -787740617 -652006269 -3420228435 -1736435170 -1628768048 -3173066342 -1659370060 -502667371 -3701617539 -971219790 -3559002171 -3372410256 -2218574844 -14962797 -2680285584 -2318530008 -1580611180 -3962509653 -2995731663 -3262644231 -3386622672 -832903192 -826852989 -2339061594 -52616487 -319161836 -848007203 -713596765 -405804387 -2343674302 -2393126614 -2268412740 -3959609298 -3943003701 -1375818464 -3492713455 -3041590872 -1028634474 -69944722 -1329116577 -3238922414 -3508802651 -2688827650 -432118456 -181619625 -1020588554 -2158511183 -3996414429 -3430521601 -92558330 -4085981271 -3335052120 -1094411888 -943803286 -2019381420 -612050958 -739046845 -40203708 -160356556 -3241366485 -3011934011 -2552681725 -46401557 -544316860 -2897832596 -1064122014 -34062854 -3390969819 -4180831325 -2007854337 -3762749433 -174296912 -1678023203 -39792904 -3137637515 -3780663668 -688110716 -3769355130 -46416140 -3162873767 -230484689 -571417648 -3770011349 -1611628070 -2703187687 -147275591 -2556554365 -236196063 -3627157681 -2268570387 -3524220149 -2196407803 -683730648 -832718794 -958399385 -2289805767 -1393849733 -3560321216 -2190933457 -570506109 -1190464059 -855891340 -815207364 -727755671 -959944786 -2399256258 -2955296368 -2226474309 -4248919733 -54373041 -4255540140 -1079558374 -758297126 -3494062195 -172905473 -3660879546 -2169485331 -3171064613 -2734421278 -239124661 -1636792719 -1032199552 -3022143494 -1238328860 -2755367096 -1172068287 -2416030799 -1111231360 -1162238438 -136341168 -936511690 -3697688233 -2310946572 -1017208991 -3260655066 -2861019521 -4085782611 -3269494883 -820892676 -610312130 -873064187 -444719755 -1077221226 -1178295173 -2928297301 -123238584 -1803717266 -3778860833 -622164036 -2906858569 -3462751317 -230473195 -3229782038 -4056351409 -4062480954 -157481248 -15888294 -1022616105 -2251826379 -236458376 -3468433827 -3859679691 -4169609282 -3270154816 -3638739572 -3024095882 -811148317 -3261183116 -1325974504 -589588966 -546263216 -4039391440 -1001817745 -16154680 -165750980 -2788265304 -2620478124 -3439592229 -1654681662 -3608040307 -3777078995 -994394444 -1014396095 -138120475 -2685072838 -3228373358 -2552662027 -28069284 -314728824 -2426995424 -649430792 -2352053910 -2291666758 -940013010 -3257519298 -143153873 -2445086935 -895972163 -2420598353 -573867732 -1148475689 -120727570 -874272160 -1499568331 -730384503 -2381214 -272910609 -2992637073 -253053713 -84832812 -2226240734 -3876274424 -18983620 -1268799900 -1348803766 -205671635 -2826229385 -660957935 -1646191083 -103509332 -1678012033 -2713914564 -2105972745 -14594356 -278969605 -3966027377 -46113154 -1246514745 -3316402942 -990363635 -2962749314 -524577371 -3903648383 -202779778 -3762835161 -2261224091 -3692935449 -90068990 -813864789 -3496510266 -3456387596 -143015350 -315738178 -4026606747 -2176794694 -2351395438 -2264420045 -68273726 -3627034496 -1856958854 -1350988020 -58099784 -4067096716 -100097690 -1012654471 -2271403796 -1141174688 -2164427209 -562335369 -549995830 -416389002 -309413793 -11860448 -2231458885 -604433027 -251864294 -3498465912 -1401395398 -3022766621 -190641354 -139719433 -1619043956 -1125777754 -74067650 -4207624 -958432937 -1116985600 -79164300 -2419620443 -777581327 -1142807361 -63314936 -4130282535 -23324492 -554363587 -2992739718 -1208439855 -772634 -540021839 -2789338031 -163090632 -120839590 -1620336448 -2164918412 -1913539649 -141022634 -2660075661 -963507036 -2687451280 -1208246255 -2771730565 -69420323 -3233866653 -1241879628 -1723226915 -202266692 -2689359561 -1651839518 -3227502861 -78020380 -811821517 -2640397810 -18786699 -109454782 -3498917610 -542022675 -1621201984 -1220764211 -518079134 -106428047 -2150406528 -4213442838 -1712410802 -33957546 -2833255501 -1363466077 -2361205692 -238621598 -1081475811 -3290623399 -1645509834 -105086074 -1522806889 -959667661 -1344480514 -2894325459 -2637988048 -7641220 -3634424343 -2525971609 -1437315771 -174455456 -1926534907 -1080174481 -2914707278 -2355466320 -138587648 -2201502550 -3552082560 -2770463793 -818376469 -961820903 -1622385204 -3028513484 -318825118 -189698242 -3224822639 -898006137 -4135907579 -37993300 -1613862757 -1859348874 -2060448975 -35441046 -3966690161 -3037175409 -1654613515 -2255792831 -1335945969 -1023753955 -1688992272 -3938874011 -3642382007 -225770871 -2716500061 -207929882 -3426021282 -219580528 -3637400609 -3530004700 -1753898265 -166081018 -1019445811 -2555921818 -2201231873 -3422693765 -43214040 -587807866 -3506115085 -837243260 -2442251152 -240230417 -1077703104 -1327561358 -2265348349 diff --git a/new_R/tests/testthat/tests.R b/new_R/tests/testthat/tests.R deleted file mode 100644 index 59dc004..0000000 --- a/new_R/tests/testthat/tests.R +++ /dev/null @@ -1,63 +0,0 @@ -library(SyncRNG) -context("SyncRNG unit tests") - -test_that("test_randi", { - s <- SyncRNG(seed=123456) - expect_equal(s$randi(), 959852049) - expect_equal(s$randi(), 2314333085) - expect_equal(s$randi(), 2255782734) - expect_equal(s$randi(), 2921461239) - expect_equal(s$randi(), 1024197102) -}) - -test_that("test_rand", { - s <- SyncRNG(seed=123456) - expect_equal(s$rand(), 959852049 /(2**32)) - expect_equal(s$rand(), 2314333085/(2**32)) - expect_equal(s$rand(), 2255782734/(2**32)) - expect_equal(s$rand(), 2921461239/(2**32)) - expect_equal(s$rand(), 1024197102/(2**32)) -}) - -test_that("test_randbelow", { - s <- SyncRNG(seed=123456) - expect_equal(s$randbelow(5), 4) - expect_equal(s$randbelow(5), 0) - expect_equal(s$randbelow(5), 4) - expect_equal(s$randbelow(5), 4) - expect_equal(s$randbelow(5), 2) -}) - -test_that("test_shuffle", { - s <- SyncRNG(seed=123456) - x <- c(1, 2, 3, 4, 5) - y <- s$shuffle(x) - expect_equal(y, c(3, 4, 1, 2, 5)) -}) - -test_that("test_first_1000", { - s <- SyncRNG(seed=0) - fileName <- "./first_1000_seed_0.txt" - conn <- file(fileName, open="r") - linn <- readLines(conn) - for (i in 1:length(linn)) { - exp <- as.numeric(linn[i]) - expect_equal(exp, s$randi()) - } - close(conn) -}) - -printf <- function(...) invisible(cat(sprintf(...))); - -test_that("test_first_1000_unif", { - set.seed(0, 'user', 'user') - fileName <- "./first_1000_seed_0.txt" - conn <- file(fileName, open="r") - linn <- readLines(conn) - for (i in 1:length(linn)) { - exp <- as.numeric(linn[i]) - u <- as.numeric(runif(1)*(2**32 - 1)) - expect_equal(exp, u) - } - close(conn) -}) |
