aboutsummaryrefslogtreecommitdiff
path: root/syncrng.c
diff options
context:
space:
mode:
authorGertjan van den Burg <burg@ese.eur.nl>2015-07-31 16:21:25 +0200
committerGertjan van den Burg <burg@ese.eur.nl>2015-07-31 16:21:25 +0200
commit2971238c8957df1bce0629c12d8c209b39328590 (patch)
tree5c84f9bede77ea23d6bc3467cbb82e619feb85ac /syncrng.c
parentmore reliable way to import SyncRNG from R (diff)
downloadSyncRNG-2971238c8957df1bce0629c12d8c209b39328590.tar.gz
SyncRNG-2971238c8957df1bce0629c12d8c209b39328590.zip
reformat to proper python and R packages
Diffstat (limited to 'syncrng.c')
-rw-r--r--syncrng.c233
1 files changed, 0 insertions, 233 deletions
diff --git a/syncrng.c b/syncrng.c
deleted file mode 100644
index 668c39e..0000000
--- a/syncrng.c
+++ /dev/null
@@ -1,233 +0,0 @@
-#ifdef TARGETPYTHON
-#include "Python.h"
-#endif
-
-#ifndef TARGETPYTHON
-#define STRICT_R_HEADERS
-#include <stdio.h>
-#include <stdlib.h>
-#include <R.h>
-#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 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
- */
-unsigned long lfsr113(unsigned long **state)
-{
- unsigned long z1, z2, z3, z4, 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(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(unsigned long seed, unsigned long **state)
-{
- unsigned long 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(unsigned long)*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)
-{
- unsigned long seed, *state = NULL;
-
- if (!PyArg_ParseTuple(args, "k", &seed))
- return NULL;
-
- lfsr113_seed(seed, &state);
-
- PyObject *pystate = Py_BuildValue("[k, k, k, k]",
- state[0], state[1], state[2], state[3]);
- free(state);
- return pystate;
-}
-
-static PyObject *syncrng_rand(PyObject *self, PyObject *args)
-{
- unsigned long i, value, numints, *localstate;
-
- PyObject *listObj;
- PyObject *intObj;
-
- if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &listObj))
- return NULL;
-
- // we're just assuming you would never pass more than 4 values
- localstate = malloc(sizeof(unsigned long)*5);
- numints = PyList_Size(listObj);
- for (i=0; i<numints; i++) {
- intObj = PyList_GetItem(listObj, i);
- value = (unsigned long) PyLong_AsLong(intObj);
- localstate[i] = value;
- }
-
- unsigned long rand = lfsr113(&localstate);
- localstate[4] = rand;
-
- PyObject *pystate = Py_BuildValue("[k, k, k, k, k]",
- localstate[0], localstate[1], localstate[2],
- localstate[3], 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}
-};
-
-PyMODINIT_FUNC initsyncrng(void)
-{
- PyObject *m = Py_InitModule3("syncrng", SyncRNGMethods,
- "Python interface to SyncRNG");
- if (m == NULL)
- return;
-}
-#endif
-
-#ifndef TARGETPYTHON
-/*
- *
- * Start of R code
- *
- */
-SEXP R_syncrng_seed(SEXP seed)
-{
- int i;
- double *pseed = REAL(seed),
- *pstate = NULL;
- unsigned long useed = (unsigned long) *pseed;
- unsigned long *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;
-}
-
-SEXP R_syncrng_rand(SEXP state)
-{
- unsigned long *localstate = malloc(sizeof(unsigned long)*4);
- double *pstate = REAL(state);
- int i;
- for (i=0; i<4; i++) {
- localstate[i] = (unsigned long) pstate[i];
- }
-
- unsigned long 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;
-}
-/*
- *
- * End of R code
- *
- */
-#endif