aboutsummaryrefslogtreecommitdiff
path: root/new_R/R
diff options
context:
space:
mode:
Diffstat (limited to 'new_R/R')
-rw-r--r--new_R/R/SyncRNG.R76
-rw-r--r--new_R/R/syncrng-package.R50
2 files changed, 126 insertions, 0 deletions
diff --git a/new_R/R/SyncRNG.R b/new_R/R/SyncRNG.R
new file mode 100644
index 0000000..e7176b4
--- /dev/null
+++ b/new_R/R/SyncRNG.R
@@ -0,0 +1,76 @@
+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
new file mode 100644
index 0000000..949401d
--- /dev/null
+++ b/new_R/R/syncrng-package.R
@@ -0,0 +1,50 @@
+#' @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