tests/testthat/test-difeq-replicate.R

context("discrete: replicated")

test_that("replication: simplest case", {
  rhs <- function(i, y, p) {
    y + p
  }

  y0 <- as.numeric(1:5)
  p <- 1
  i <- 0:10
  res <- difeq(y0, i, rhs, p)

  res2 <- difeq_replicate(3, y0, i, rhs, p)

  expect_is(res2, "array")
  expect_equal(dim(res2), c(11, 6, 3))
  expect_equal(res2[, , 1], res)
  expect_equal(res2[, , 2], res)
  expect_equal(res2[, , 3], res)
  expect_equal(names(attributes(res2)), "dim")
})


test_that("preserve y names", {
  rhs <- function(i, y, p) {
    y + p
  }

  y0 <- as.numeric(1:5)
  p <- 1
  i <- 0:10
  names(y0) <- letters[seq_along(y0)]
  res <- difeq(y0, i, rhs, p)

  res2 <- difeq_replicate(3, y0, i, rhs, p, as_array = TRUE)

  expect_equal(dimnames(res2), c(dimnames(res), list(NULL)))
})


test_that("varying initial conditions", {
  rhs <- function(i, y, p) {
    y + p
  }

  y0 <- lapply(1:3, seq, length.out = 5)
  p <- 1
  i <- 0:10
  cmp <- difeq(y0[[1]], i, rhs, p, return_step = FALSE)
  res <- difeq_replicate(3, y0, i, rhs, p, return_step = FALSE)

  expect_equal(res[, , 1L], cmp)
  expect_equal(res[, , 2L], cmp + 1)
  expect_equal(res[, , 3L], cmp + 2)
})


test_that("names from varying initial conditions", {
  rhs <- function(i, y, p) {
    y + p
  }

  y0 <- lapply(1:3, seq, length.out = 5)
  names(y0) <- c("X", "Y", "Z")
  for (i in seq_along(y0)) {
    names(y0[[i]]) <- letters[seq_len(5)]
  }
  p <- 1
  i <- 0:10
  cmp <- difeq(y0[[1]], i, rhs, p, return_step = FALSE)
  res3 <- difeq_replicate(3, y0, i, rhs, p,
                          return_step = FALSE, as_array = TRUE)

  expect_equal(dimnames(res3), c(dimnames(cmp), list(NULL)))
})


test_that("replicate invalid input", {
  rhs <- function(i, y, p) {
    y + p
  }
  y0 <- as.numeric(1:5)
  p <- 1
  i <- 0:10

  expect_error(difeq_replicate(0, y0, i, rhs, p, unknown = "whatever"),
               "Invalid dot arguments")
  expect_error(difeq_replicate(1, y0, i, rhs, p, as_array = FALSE),
               "as_array = FALSE no longer supported")
  expect_error(difeq_replicate(0, y0, i, rhs, p),
               "n must be positive")
  expect_error(difeq_replicate(2, list(y0), i, rhs, p),
               "'y' must have 2 elements")
  expect_error(difeq_replicate(2, list(y0, y0[-1]), i, rhs, p),
               "All 'y' lengths must be the same")
  expect_error(difeq_replicate(2, list(setNames(y0, letters[1:5]),
                                       setNames(y0, LETTERS[1:5])),
                               i, rhs, p),
               "All 'y' names must be the same")
  expect_error(difeq_replicate(1, y0, -1, rhs, p),
               "steps must be positive")
  expect_error(difeq_replicate(1, y0, i, rhs, p, n_history = 1),
               "If given, n_history must be at least 2")
  expect_error(difeq_replicate(1, y0, i, rhs, p, dllname = "whatever"),
               "dllname must not be given")
  expect_error(difeq_replicate(2, matrix(y0), i, rhs, p),
               "Expected '2' columns in 'y'")
})


test_that("basic replication", {
  rhs <- function(i, y, p) {
    y + p
  }

  y0 <- lapply(1:3, seq, length.out = 5)

  p <- 1
  i <- 0:10
  cmp <- difeq(y0[[1]], i, rhs, p)
  res <- difeq_replicate(3, y0, i, rhs, p)

  expect_equal(res[, , 1L], difeq(y0[[1L]], i, rhs, p))
  expect_equal(res[, , 2L], difeq(y0[[2L]], i, rhs, p))
  expect_equal(res[, , 3L], difeq(y0[[3L]], i, rhs, p))

  expect_identical(difeq_replicate(3, do.call(cbind, y0), i, rhs, p), res)
})


test_that("add output, time", {
  rhs <- function(i, y, p) {
    ret <- y + p
    attr(ret, "output") <- sum(y)
    ret
  }

  y0 <- list(
    as.numeric(1:5),
    as.numeric(2:6),
    as.numeric(3:7))
  p <- 3
  i <- 0:10

  ## This is what we're trying to achieve:
  a <- difeq(y0[[1]], i, rhs, p, n_out = 1L)
  b <- difeq(y0[[2]], i, rhs, p, n_out = 1L)
  c <- difeq(y0[[3]], i, rhs, p, n_out = 1L)
  d <- difeq_replicate(3, y0, i, rhs, p, n_out = 1L)

  expect_equal(dim(d), c(dim(a), 3))
  expect_equal(d[, , 1], a)
  expect_equal(d[, , 2], b)
  expect_equal(d[, , 3], c)

  e <- difeq_replicate(3, y0, i, rhs, p, n_out = 1L,
                       return_output_with_y = FALSE)
  expect_equal(attr(e, "output"), d[, 7, , drop = FALSE])

  attr(e, "output") <- NULL
  expect_equal(e, d[, 1:6, , drop = FALSE])
})


test_that("limitations of replication interface", {
  rhs <- function(i, y, p) {
    y + p
  }
  y0 <- as.numeric(1:5)
  p <- 1
  i <- 0:10
  expect_error(
    difeq_replicate(1, y0, i, rhs, p, restartable = TRUE),
    "Can't return pointer when n_replicates > 1")
  expect_error(
    difeq_replicate(1, y0, i, rhs, p, return_history = TRUE),
    "Can't return history when n_replicates > 1")
})


test_that("Minimal output", {
  rhs <- function(i, y, p) {
    ret <- y + p
    attr(ret, "output") <- sum(y)
    ret
  }

  y0 <- cbind(1:5, 2:6, 3:7)
  rownames(y0) <- letters[1:5]
  outnames <- "total"

  p <- 1
  cmp <- difeq(y0[[1]], 10, rhs, p)
  res <- difeq_replicate(3, y0, 10, rhs, p, n_out = 1L,
                         outnames = outnames,
                         return_minimal = TRUE)
  output <- attr(res, "output")

  expect_equal(dim(res), c(5, 10, 3))
  expect_equal(dim(output), c(1, 10, 3))
  expect_equal(rownames(res), rownames(y0))
  expect_equal(rownames(output), outnames)
})

Try the dde package in your browser

Any scripts or data that you put into this service are public.

dde documentation built on Sept. 23, 2024, 5:09 p.m.