aboutsummaryrefslogtreecommitdiff
path: root/SyncRNG.R
blob: ca25eefd1e11c0a3b6c9a30ea3ae69990b43b41a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
library(methods)

dyn.load('RSyncRNG.so')

SyncRNG <- setRefClass('SyncRNG',
	fields=list(
		    seed='numeric',
		    state='numeric',
		    BPF='numeric'
		    ),
	methods=list(
		initialize=function(..., seed=0) {
			BPF <<- 32
			seed <<- seed
			tmp <- .Call('R_syncrng_seed',
			     as.numeric(seed))
			state <<- tmp[1:4]
			callSuper(...)
		},
		randi=function() {
			tmp <- .Call('R_syncrng_rand',
				     as.numeric(state))
			state <<- tmp[1:4]
			return(tmp[5])
		},
		rand=function() {
			r <- randi()
			return (r * 2.3283064365387e-10)
		},
		randbelow=function(n) {
			maxsize <- 2^BPF
			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) {
			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)
		}
		)
	)