context("test-mcmc")
TestDir <- function() {
test.dir <- tempfile()
if(dir.create(test.dir)) {
return(test.dir)
}
else {
stop("Failed to create test directory")
}
}
test_that("MCMC samples saved", {
iter <- 3
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
x <- c(0, 0)
y <- 0
samps <- Mcmc({
x <- c(1, 2)
y <- 1
})
expect_equivalent(samps$x[,], matrix(rep(1:2, each=iter), nrow=iter))
expect_equivalent(samps$y[,], matrix(rep(1, each=iter), nrow=iter))
})
test_that("Out of memory MCMC is file backed", {
iter <- 1
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
samps <- Mcmc({
x <- 1
})
expect_true(bigmemory::is.filebacked(samps$x))
})
test_that("In memory MCMC is not file backed", {
iter <- 1
Mcmc <- InitMcmc(iter)
samps <- Mcmc({
x <- 1
})
expect_false(bigmemory::is.big.matrix(samps$x))
})
test_that("Thinning works", {
iter <- 3
thin <- 2
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir, thin)
x <- 0
samps <- Mcmc({
x <- x + 1
})
expect_equivalent(samps$x[,], matrix(c(2, 4, 6)), ncol=1)
})
test_that("Non-numeric assignments aren't saved", {
iter <- 3
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
x <- 0
y <- c("char1", "char2")
z <- "char3"
samps <- Mcmc({
x <- 1
y <- c("testchar1", "testchar2")
z <- "testchar3"
})
expect_null(samps$y)
expect_null(samps$z)
expect_equivalent(samps$x[,], rep(1, iter))
})
test_that("MCMC stops if thinning value isn't valid", {
iter <- 1
test.dir <- TestDir()
thinning.error.msg <- "'thin' must be an integer > 0"
expect_error(InitMcmc(iter, test.dir, thin=-1), thinning.error.msg)
expect_error(InitMcmc(iter, test.dir, thin=1.5), thinning.error.msg)
})
test_that("MCMC stops if number of iterations isn't valid", {
mcmc.iterations.error.msg <- "'n.save' must be an integer > 0"
expect_error(InitMcmc(-1), mcmc.iterations.error.msg)
expect_error(InitMcmc(0), mcmc.iterations.error.msg)
expect_error(InitMcmc(1.1), mcmc.iterations.error.msg)
})
test_that("Warning given if the exclusions isn't a character vector", {
exclude.warning.msg <- "'exclude' will be ignored, expected character vector"
expect_warning(InitMcmc(1, exclude=c(1, 2, 3)), exclude.warning.msg)
})
test_that("Excluded assignments aren't saved", {
iter <- 1
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir, exclude="x")
samps <- Mcmc({
x <- 1
y <- 1
})
expect_null(samps$x)
expect_equivalent(samps$y[,], 1)
})
test_that("Error thrown if saving on-disk but 'bigmemory' not installed", {
m <- mockery::mock(FALSE)
mockery::stub(InitMcmc, 'requireNamespace', m)
iter <- 1
test.dir <- TestDir()
# Error if saving on-disk and bigmemory not installed
bigmem.err.msg <- "Package 'bigmemory' required for saving on-disk"
expect_error(InitMcmc(iter, test.dir), bigmem.err.msg)
mockery::expect_call(m, 1, requireNamespace("bigmemory", quietly=TRUE))
# Saving in-memory still works
Mcmc <- InitMcmc(iter)
samps <- Mcmc({
x <- 1
})
expect_equivalent(samps$x, rep(1, iter))
})
test_that("Matrix assignments are saved successfully", {
iter <- 2
test.dir <- TestDir()
expected.save.result <- matrix(rep(1:4, times=iter), nrow=2, byrow=TRUE)
Mcmc1 <- InitMcmc(iter, test.dir)
samps1 <- Mcmc1({
x <- matrix(expected.save.result[1,], nrow=2)
})
expect_equivalent(samps1$x[,], expected.save.result)
Mcmc2 <- InitMcmc(iter)
samps2 <- Mcmc2({
x <- matrix(expected.save.result[1,], nrow=2)
})
expect_equivalent(samps2$x, expected.save.result)
})
test_that("Array assignments are saved successfully", {
iter <- 2
test.dir <- TestDir()
expected.save.result <- matrix(rep(1:6, each=2), nrow=2)
Mcmc1 <- InitMcmc(iter, test.dir)
samps1 <- Mcmc1({
x <- array(1:6, dim=c(1, 2, 3))
})
expect_equivalent(samps1$x[,], expected.save.result)
Mcmc2 <- InitMcmc(iter)
samps2 <- Mcmc2({
x <- array(1:6, dim=c(1, 2, 3))
})
expect_equivalent(samps2$x, expected.save.result)
})
test_that("Completed file-backed MCMC can be loaded back into R", {
iter <- 2
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
samps <- Mcmc({
x <- 1
y <- 2
})
samps.loaded <- LoadMcmc(test.dir)
expect_equal(samps, samps.loaded)
expect_equivalent(samps$x[,], samps.loaded$x[,])
expect_equivalent(samps$y[,], samps.loaded$y[,])
})
test_that("InitMcmc samples overwritten if overwrite=TRUE", {
iter <- 2
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir, overwrite=TRUE)
samps.1 <- Mcmc({
x <- 1
})
samps.2 <- Mcmc({
x <- 2
})
expect_equivalent(samps.2$x[,], rep(2, iter))
})
test_that("InitMcmc samples not overwritten if overwrite=FALSE", {
err.msg <- paste0("Backing file already exists in backing.path. ",
"Use overwrite=TRUE to replace.")
iter <- 2
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir, overwrite=FALSE)
samps.1 <- Mcmc({
x <- 1
})
expect_error(samps.2 <- Mcmc({ x <- 2 }), err.msg)
expect_equivalent(samps.1$x[,], rep(1, iter))
rm(samps.1)
loaded.samps.1 <- LoadMcmc(test.dir)
expect_equivalent(loaded.samps.1$x[,], rep(1, iter))
})
test_that("Default behavior for InitMcmc is overwrite=FALSE", {
err.msg <- paste0("Backing file already exists in backing.path. ",
"Use overwrite=TRUE to replace.")
iter <- 2
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
samps.1 <- Mcmc({
x <- 1
})
expect_error(samps.2 <- Mcmc({ x <- 2 }), err.msg)
})
test_that("Function returned by InitMcmc can take overwrite argument", {
iter <- 2
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
samps.1 <- Mcmc({
x <- 1
})
samps.2 <- Mcmc({
x <- 2
}, overwrite=TRUE)
expect_equivalent(samps.2$x[,], rep(2, iter))
})
test_that("Error message if no .desc files in backing.path for LoadMcmc", {
test.dir <- TestDir()
wrong.path.err.msg <-
paste0("No '.desc' files found in ", test.dir)
expect_error(LoadMcmc(test.dir), wrong.path.err.msg, fixed=TRUE)
})
test_that("In-progress file-backed MCMC can be viewed", {
iter <- 10
test.dir <- TestDir()
# Make some fake samples
x <- matrix(NA, nrow=iter, ncol=1)
y <- matrix(NA, nrow=iter, ncol=2)
x[1:8,] <- 1:8
y[1:6,] <- 1:6
y[6, 2] <- NA
bigmemory::as.big.matrix(x, backingpath=test.dir, backingfile="x",
descriptorfile="x.desc")
bigmemory::as.big.matrix(y, backingpath=test.dir, backingfile="y",
descriptorfile="y.desc")
samps <- Peek(test.dir)
expect_equivalent(samps$x[,], 1:5)
expect_equivalent(samps$y[,], matrix(rep(1:5, times=2), nrow=5))
})
test_that("Error message if no .desc files in backing.path for Peek", {
test.dir <- TestDir()
wrong.path.err.msg <-
paste0("No '.desc' files found in ", test.dir)
expect_error(Peek(test.dir), wrong.path.err.msg, fixed=TRUE)
})
test_that("ToMemory converts MCMC samples to in-memory", {
iter <- 3
test.dir <- TestDir()
Mcmc <- InitMcmc(iter, test.dir)
x <- c(0, 0)
y <- 0
samps <- Mcmc({
x <- c(1, 2)
y <- 1
})
in.memory.samps <- ToMemory(samps)
# Check that the samples are the same
expect_equivalent(samps$x[,], in.memory.samps$x)
expect_equivalent(samps$y[,], in.memory.samps$y)
# Check that the samples are in-memory
expect_true(is.matrix(in.memory.samps$x))
expect_false(bigmemory::is.big.matrix(in.memory.samps$x))
expect_true(is.matrix(in.memory.samps$y))
expect_false(bigmemory::is.big.matrix(in.memory.samps$y))
# Check that the dimensions are the same
expect_true(all(dim(samps$x) == dim(in.memory.samps$x)))
expect_true(all(dim(samps$y) == dim(in.memory.samps$y)))
})
test_that("File-backed MCMC is flushed on exit", {
iter <- 3
test.dir <- TestDir()
m <- mockery::mock(TRUE, TRUE)
Mcmc <- InitMcmc(iter, test.dir)
with_mock(flush=m,
samps <- Mcmc({ x <- c(1, 2)
y <- 1 }),
.env="bigmemory")
mockery::expect_called(m, 2)
mockery::expect_args(m, 1, samps$x)
mockery::expect_args(m, 2, samps$y)
})
test_that("Warning given if file-backed MCMC fails to flush on exit", {
iter <- 3
test.dir <- TestDir()
flush.failed.warning.msg <-
"Failed to flush big.matrix, some samples may not be saved on-disk"
m <- mockery::mock(FALSE)
Mcmc <- InitMcmc(iter, test.dir)
expect_warning(with_mock(flush=m,
samps <- Mcmc({ x <- c(1, 2)}),
.env="bigmemory"),
flush.failed.warning.msg)
mockery::expect_called(m, 1)
})
test_that("Peek doesn't fail if the MCMC is complete", {
n.iter <- 5
SampleSomething <- function() 1
backing.path <- TestDir()
Mcmc <- InitMcmc(n.iter, backing.path=backing.path)
Mcmc({
x <- SampleSomething()
})
samples.so.far <- Peek(backing.path)
expect_equivalent(samples.so.far$x[,], rep(1, n.iter))
})
test_that("Parameter dimensions can change if overwrite=TRUE", {
skip_on_os("windows") # file.remove doesn't always work on Windows
n.iter <- 5
backing.path <- TestDir()
f <- function() 1
Mcmc <- InitMcmc(n.iter, backing.path=backing.path, overwrite=TRUE)
samps <- Mcmc({
x <- f()
})
f <- function() c(2, 2)
samps <- Mcmc({
x <- f()
})
expect_equivalent(samps$x[,], matrix(rep(c(2, 2), each=n.iter),
nrow=n.iter, ncol=2))
})
test_that("Error message given if backing file can't be removed", {
skip_on_os("windows") # file.remove doesn't always work on Windows
n.iter <- 5
backing.path <- TestDir()
file.rm.err.msg <- paste0("Failed to remove ", file.path(backing.path, "x"),
". Try removing the file manually.")
f <- function() 1
Mcmc <- InitMcmc(n.iter, backing.path=backing.path, overwrite=TRUE)
samps <- Mcmc({
x <- f()
})
m <- mockery::mock(FALSE)
# mockery::stub(Mcmc, 'FileRemove', m, depth=10)
f <- function() c(2, 2)
expect_error(with_mock(file.remove=m,
samps <- Mcmc({ x <- f() })),
file.rm.err.msg,
fixed=TRUE
)
mockery::expect_called(m, 1)
})
test_that("Error message given if .desc file isn't found and overwrite=TRUE", {
n.iter <- 5
backing.path <- TestDir()
desc.rm.err.msg <- paste0("Tried to overwrite ", "x",
" but couldn't find ", file.path(backing.path, "x.desc"),
". Try removing the old results manually.")
f <- function() 1
Mcmc <- InitMcmc(n.iter, backing.path=backing.path, overwrite=TRUE)
samps <- Mcmc({
x <- f()
})
file.remove(file.path(backing.path, "x.desc"))
expect_error(samps <- Mcmc({ x <- f() }), desc.rm.err.msg, fixed=TRUE)
})
test_that("MCMC can be resumed", {
n.iter <- 5
SampleX <- function(x) x + 1
SampleY <- function(y) y + 10
backing.path <- TestDir()
x <- 0
y <- 0
interrupt.mcmc <- TRUE
Mcmc <- InitMcmc(n.iter, backing.path=backing.path)
# Stop the MCMC in the middle of the third iteration
testthat::expect_error(
samps <- Mcmc({
x <- SampleX(x)
if(x==3 && interrupt.mcmc) break
y <- SampleY(y)
}))
interrupt.mcmc <- FALSE
samps <- Resume(backing.path)
expect_equivalent(samps$x[,], 1:5)
expect_equivalent(samps$y[,], seq(10, 50, by=10))
})
test_that("Resume doesn't fail if MCMC is already complete", {
n.iter <- 5
SampleX <- function(x) x + 1
SampleY <- function(y) y + 10
backing.path <- TestDir()
x <- 0
y <- 0
Mcmc <- InitMcmc(n.iter, backing.path=backing.path)
samps <- Mcmc({
x <- SampleX(x)
y <- SampleY(y)
})
samps <- Resume(backing.path)
expect_equivalent(samps$x[,], 1:5)
expect_equivalent(samps$y[,], seq(10, 50, by=10))
})
test_that("Resume works if thinning is set", {
n.iter <- 5
thin <- 2
SampleX <- function(x) x + 1
SampleY <- function(y) y + 10
backing.path <- TestDir()
x <- 0
y <- 0
interrupt.mcmc <- TRUE
Mcmc <- InitMcmc(n.iter, backing.path=backing.path, thin=thin)
# Stop the MCMC in the middle of the run
testthat::expect_error(
samps <- Mcmc({
if(x==3 && interrupt.mcmc) break
x <- SampleX(x)
y <- SampleY(y)
}))
interrupt.mcmc <- FALSE
samps <- Resume(backing.path)
expect_equivalent(samps$x[,], seq(2, 10, by=2))
expect_equivalent(samps$y[,], seq(20, 100, by=20))
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.