R Under development (unstable) (2024-02-28 r85999 ucrt) -- "Unsuffered Consequences" Copyright (C) 2024 The R Foundation for Statistical Computing Platform: x86_64-w64-mingw32/x64 R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > lcg_get_seed <- port4me:::lcg_get_seed > lcg_set_seed <- port4me:::lcg_set_seed > lcg_port <- port4me:::lcg_port > lcg <- port4me:::lcg > > a <- environment(lcg)[["a"]] > c <- environment(lcg)[["c"]] > m <- environment(lcg)[["modulus"]] > message(sprintf("- LCG parameters (a,c,m): (%d,%d,%d)", a, c, m)) - LCG parameters (a,c,m): (75,74,65537) > stopifnot(a == 75L, c == 74L, m == 2^16+1) > > > message("lcg_port() draws uniformly from {min, ..., max}") lcg_port() draws uniformly from {min, ..., max} > > assert_lcg_port <- function(min = 1024L, max = 65535L, subset = NULL, seed = 0L) { + if (is.null(subset)) { + n <- max - min + 1L + ports <- min:max + } else { + min <- min(subset) + max <- max(subset) + n <- length(subset) + ports <- subset + } + + counts <- integer(length = n) + names(counts) <- ports + + lcg_set_seed(seed = seed) + + for (kk in seq_len(n)) { + port <- lcg_port(min = min, max = max, subset = subset) + stopifnot(port >= min, port <= max) + if (is.null(subset)) { + idx <- port - min + 1L + } else { + idx <- which(port == ports) + } + stopifnot(!is.na(idx), idx >= 1L, idx <= n) + counts[idx] <- counts[idx] + 1L + } + stopifnot(sum(counts) == n) + + message("- Distribution of counts:") + dist <- table(counts) + names(dist) <- sprintf("n=%s", names(dist)) + print(dist) + stopifnot(all(counts == 1L)) + } ## assert_lcg_port() > > > message("lcg_port() draws uniformly from {1024, ..., 65535}") lcg_port() draws uniformly from {1024, ..., 65535} > assert_lcg_port() - Distribution of counts: n=1 64512 > > message("lcg_port() draws uniformly from {1024, ..., 65535} regardless of seed") lcg_port() draws uniformly from {1024, ..., 65535} regardless of seed > assert_lcg_port(seed = 1L) - Distribution of counts: n=1 64512 > assert_lcg_port(seed = 42L) - Distribution of counts: n=1 64512 > assert_lcg_port(seed = 65535L) - Distribution of counts: n=1 64512 > > message("lcg_port(min = 1) draws uniformly from {1, ..., 65535}") lcg_port(min = 1) draws uniformly from {1, ..., 65535} > assert_lcg_port(min = 1) - Distribution of counts: n=1 65535 > > message("lcg_port(min = 50, max = 100) draws uniformly from {50, ..., 100}") lcg_port(min = 50, max = 100) draws uniformly from {50, ..., 100} > assert_lcg_port(min = 50, max = 100) - Distribution of counts: n=1 51 > > message("lcg_port(subset = 50:100) draws uniformly from {50, ..., 100}") lcg_port(subset = 50:100) draws uniformly from {50, ..., 100} > assert_lcg_port(subset = 50:100) - Distribution of counts: n=1 51 > > message("lcg_port(subset = seq(1, 65535, by = 5)) draws uniformly from {1, 5, ..., 65535}") lcg_port(subset = seq(1, 65535, by = 5)) draws uniformly from {1, 5, ..., 65535} > assert_lcg_port(subset = seq(1, 65535, by = 5)) - Distribution of counts: n=1 13107 > > > > message("lcg() draws from all values in {0, ..., m-1} except one of them") lcg() draws from all values in {0, ..., m-1} except one of them > seeds <- 0:(m-1) > seeds_next <- (a * seeds + c) %% m > seed_skip <- seeds[seeds_next == seeds] > message(sprintf(" - Skipped seed: %s", seed_skip)) - Skipped seed: 65536 > stopifnot(length(seed_skip) == 1L) > > counts <- integer(length = m) > names(counts) <- seq(from = 0L, to = m - 1L) > counts[seed_skip + 1L] <- 1L > > seed <- 0L > message(sprintf("Initializing seed: %d", seed)) Initializing seed: 0 > lcg_set_seed(seed = seed) [1] 0 > > for (kk in seq_len(m - 1L)) { + idx <- lcg() + 1L + stopifnot(idx >= 1L, idx <= m) + counts[idx] <- counts[idx] + 1L + } > > stopifnot(sum(counts) == m) > stopifnot(all(counts > 0L)) ## technically => all(counts == 1) > > > message("lcg() draws from uniformly from {0, ..., m-1} except one of them") lcg() draws from uniformly from {0, ..., m-1} except one of them > > message("- Distribution of counts:") - Distribution of counts: > dist <- table(counts) > names(dist) <- sprintf("n=%s", names(dist)) > print(dist) n=1 65537 > stopifnot(all(counts == 1L)) > > proc.time() user system elapsed 9.46 2.71 12.12