tests/testthat/test-step.DV.R

test_that("Dumontet-Vignes step selection handles inputs well", {
  f <- function(x) return(NA)
  expect_error(step.DV(x = 2, f), "Could not compute the function value")
  expect_error(step.DV(sin, 1, range = c(0, 1)), "must be a positive vector of length 2")
})

test_that("Dumontet-Vignes step selection behaves reasonably", {
  f <- function(x) x^4
  s <- step.DV(x = 2, f)
  expect_identical(s$exitcode, 0L)
  expect_lt(sum(s$abs.error), 1e-6)
  expect_equal(s$value, 32, tolerance = 1e-8)
  u <- s$iterations$ratio[length(s$iterations$ratio)]
  u <- max(u, 1/u)
  # Stopping criterion
  expect_gte(u, 2)
  expect_lte(u, 15)

  s2 <- step.DV(x = 2, f, range = c(1e-10, 1e-7))
  expect_identical(s2$exitcode, 3L)

  s3 <- step.DV(x = 2, f, range = c(1e-3, 1e-1), maxit = 10)
  expect_identical(s3$exitcode, 6L)

  s4 <- step.DV(x = 2, f, h0 = 1000, maxit = 5)
  expect_identical(s4$exitcode, 6L)

  # Too large a size must be limited -- the range must be over-ridden
  s5 <- step.DV(x = 2, f, h0 = 1000, range = c(1e2, 1e4), maxit = 5)
  expect_equal(s5$par, 0.2, tolerance = 1e-12)
  expect_identical(s5$exitcode, 6L)

  expect_identical(step.DV(x = 2, f, maxit = 1)$exitcode, 7L)
})

test_that("Dumontet--Vignes algorithm stops if the function returns NA for all allowed step sizes", {
  f <- function(x) ifelse(abs(x - 2) < 1e-8, x^4, NA)
  expect_error(step.DV(f, 2, range = c(1e-7, 1e-2)), "attempts of step shrinkage")
})

test_that("Tweaking the DV algorithm for noisier functions", {
  f <- function(x) x^4
  s.perfect <- step.DV(x = 2, f, h0 = 1e-7, max.rel.error = 2e-16)
  s.noisy <- step.DV(x = 2, f, h0 = 1e-7, max.rel.error = 2e-8)
  expect_lt(s.perfect$par, s.noisy$par)
})

test_that("DV for functions with near-zero f''' stops immediately", {
  # Quadratic function, f''' = 0
  s1 <- step.DV(function(x) x^2, 1)
  expect_lte(s1$counts, 2)
  expect_identical(s1$exitcode, 1L)

  s2 <- step.DV(function(x) pi*x + exp(1), 1)
  expect_lte(s2$counts, 2)
  expect_identical(s2$exitcode, 1L)
})

test_that("Parallelisation in DV works", {
  expect_identical(step.DV(sin, 1, cores = 1), step.DV(sin, 1, cores = 2))
  clus <- parallel::makePSOCKcluster(2)
  expect_identical(step.DV(sin, 1, cores = 1), step.DV(sin, 1, cl = clus))
  parallel::stopCluster(clus)
})

Try the pnd package in your browser

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

pnd documentation built on Sept. 9, 2025, 5:44 p.m.